AC_CHECK_FUNCS(getrlimit)
AC_CHECK_FUNCS(fork execv execve)
+AC_ARG_WITH([overridable-allocators], [ --with-overridable-allocators allow g_*alloc/g_free to call custom allocators set via g_mem_set_vtable])
+
+if test x$with_overridable_allocators == xyes; then
+ AC_DEFINE(ENABLE_OVERRIDABLE_ALLOCATORS,1,[Overridable allocator support enabled])
+ AC_MSG_NOTICE([Overridable allocator support enabled])
+else
+ AC_MSG_NOTICE([Overridable allocator support disabled])
+fi
+
#
# Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding
# the detection of strndup on OS X so Mono built on 10.7+ still runs on 10.6. This can be
AC_CHECK_FUNCS(strndup getpwuid_r)
fi
-AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = xno )
+AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = xno || test x$with_overridable_allocators == xyes)
AM_ICONV()
AC_SEARCH_LIBS(sqrtf, m)
gdate-unix.c gdir-unix.c gfile-unix.c gmisc-unix.c \
gmodule-unix.c gtimer-unix.c
-# some unices and windows do not have an implementation of vasprintf
-# used by eglib, use provided implementation instead
-if NEED_VASPRINTF
-vasprintf_files = vasprintf.c
-else
-vaprinttf_files = foo.c
-endif
-
if HOST_WIN32
os_files = $(win_files)
else
garray.c \
gbytearray.c \
gerror.c \
- vasprintf.h \
ghashtable.c \
giconv.c \
gmem.c \
gutf8.c \
gunicode.c \
unicode-data.h \
- $(os_files) \
- $(vasprintf_files)
+ $(os_files)
libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include <config.h>
#include <glib.h>
-
-#include "vasprintf.h"
-
GError *
g_error_new (gpointer domain, gint code, const char *format, ...)
{
err->code = code;
va_start (args, format);
- if (vasprintf (&err->message, format, args) == -1)
+ if (g_vasprintf (&err->message, format, args) == -1)
err->message = g_strdup_printf ("internal: invalid format string %s", format);
va_end (args);
err->domain = domain;
err->code = code;
- if (vasprintf (&err->message, format, ap) == -1)
+ if (g_vasprintf (&err->message, format, ap) == -1)
err->message = g_strdup_printf ("internal: invalid format string %s", format);
return err;
{
g_return_if_fail (error != NULL);
- free (error->message);
+ g_free (error->message);
g_free (error);
}
#ifndef __GLIB_H
#define __GLIB_H
-
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
+
#ifdef _MSC_VER
#pragma include_alias(<eglib-config.h>, <eglib-config.hw>)
#endif
gpointer g_realloc (gpointer obj, gsize size);
gpointer g_malloc (gsize x);
gpointer g_malloc0 (gsize x);
+gpointer g_calloc (gsize n, gsize x);
gpointer g_try_malloc (gsize x);
gpointer g_try_realloc (gpointer obj, gsize size);
#define g_alloca(size) alloca (size)
gpointer g_memdup (gconstpointer mem, guint byte_size);
-static inline gchar *g_strdup (const gchar *str) { if (str) {return strdup (str);} return NULL; }
+static inline gchar *g_strdup (const gchar *str) { if (str) { return (gchar*) g_memdup (str, (guint)strlen (str) + 1); } return NULL; }
gchar **g_strdupv (gchar **str_array);
typedef struct {
gpointer (*realloc) (gpointer mem, gsize n_bytes);
void (*free) (gpointer mem);
gpointer (*calloc) (gsize n_blocks, gsize n_block_bytes);
- gpointer (*try_malloc) (gsize n_bytes);
- gpointer (*try_realloc) (gpointer mem, gsize n_bytes);
} GMemVTable;
-#define g_mem_set_vtable(x)
+void g_mem_set_vtable (GMemVTable* vtable);
struct _GMemChunk {
guint alloc_size;
gint g_fprintf (FILE *file, gchar const *format, ...);
gint g_sprintf (gchar *string, gchar const *format, ...);
gint g_snprintf (gchar *string, gulong n, gchar const *format, ...);
+gint g_vasprintf (gchar **ret, const gchar *fmt, va_list ap);
#define g_vprintf vprintf
#define g_vfprintf vfprintf
#define g_vsprintf vsprintf
#define g_vsnprintf vsnprintf
-#define g_vasprintf vasprintf
gsize g_strlcpy (gchar *dest, const gchar *src, gsize dest_size);
gchar *g_stpcpy (gchar *dest, const char *src);
gchar *g_get_prgname (void);
void g_set_prgname (const gchar *prgname);
+gboolean g_ensure_directory_exists (const gchar *filename);
+
/*
* Shell
*/
if (context->parser.end_element != NULL && context->state == START_ELEMENT){
context->parser.end_element (context, ename, context->user_data, error);
if (error != NULL && *error != NULL){
- free (ename);
+ g_free (ename);
goto fail;
}
}
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <config.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
+#if defined (ENABLE_OVERRIDABLE_ALLOCATORS)
+
+static GMemVTable sGMemVTable = { malloc, realloc, free, calloc };
+
+void
+g_mem_set_vtable (GMemVTable* vtable)
+{
+ sGMemVTable.calloc = vtable->calloc ? vtable->calloc : calloc;
+ sGMemVTable.realloc = vtable->realloc ? vtable->realloc : realloc;
+ sGMemVTable.malloc = vtable->malloc ? vtable->malloc : malloc;
+ sGMemVTable.free = vtable->free ? vtable->free : free;
+}
+
+#define G_FREE_INTERNAL sGMemVTable.free
+#define G_REALLOC_INTERNAL sGMemVTable.realloc
+#define G_CALLOC_INTERNAL sGMemVTable.calloc
+#define G_MALLOC_INTERNAL sGMemVTable.malloc
+#else
+
+void
+g_mem_set_vtable (GMemVTable* vtable)
+{
+}
+
+#define G_FREE_INTERNAL free
+#define G_REALLOC_INTERNAL realloc
+#define G_CALLOC_INTERNAL calloc
+#define G_MALLOC_INTERNAL malloc
+#endif
void
g_free (void *ptr)
{
if (ptr != NULL)
- free (ptr);
+ G_FREE_INTERNAL (ptr);
}
gpointer
g_free (obj);
return 0;
}
- ptr = realloc (obj, size);
+ ptr = G_REALLOC_INTERNAL (obj, size);
if (ptr)
return ptr;
g_error ("Could not allocate %i bytes", size);
gpointer ptr;
if (!x)
return 0;
- ptr = malloc (x);
+ ptr = G_MALLOC_INTERNAL (x);
if (ptr)
return ptr;
g_error ("Could not allocate %i bytes", x);
}
+gpointer g_calloc (gsize n, gsize x)
+{
+ gpointer ptr;
+ if (!x || !n)
+ return 0;
+ ptr = G_CALLOC_INTERNAL (n, x);
+ if (ptr)
+ return ptr;
+ g_error ("Could not allocate %i (%i * %i) bytes", x*n, n, x);
+}
gpointer g_malloc0 (gsize x)
{
- gpointer ptr;
- if (!x)
- return 0;
- ptr = calloc(1,x);
- if (ptr)
- return ptr;
- g_error ("Could not allocate %i bytes", x);
+ return g_calloc (1,x);
}
gpointer g_try_malloc (gsize x)
{
if (x)
- return malloc (x);
+ return G_MALLOC_INTERNAL (x);
return 0;
}
gpointer g_try_realloc (gpointer obj, gsize size)
{
if (!size) {
- g_free (obj);
+ G_FREE_INTERNAL (obj);
return 0;
}
- return realloc (obj, size);
+ return G_REALLOC_INTERNAL (obj, size);
}
gint ccBuf = GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, 9);
buf[ccBuf - 1] = '-';
ccBuf += GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, buf + ccBuf, 9);
- return strdup(buf);
+ return g_strdup (buf);
}
gboolean
}
}
+ g_free (drive);
+ g_free (path);
+
return home_dir;
}
#include <stdlib.h>
#include <glib.h>
-#include "vasprintf.h"
-
/* The current fatal levels, error is always fatal */
static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR;
static GLogFunc default_log_func;
va_list args;
va_start (args, format);
- if (vasprintf (&msg, format, args) < 0)
+ if (g_vasprintf (&msg, format, args) < 0)
return;
va_end (args);
stdout_handler = default_stdout_handler;
stdout_handler (msg);
- free (msg);
+ g_free (msg);
}
void
va_list args;
va_start (args, format);
- if (vasprintf (&msg, format, args) < 0)
+ if (g_vasprintf (&msg, format, args) < 0)
return;
va_end (args);
stderr_handler = default_stderr_handler;
stderr_handler (msg);
- free (msg);
+ g_free (msg);
}
GLogLevelFlags
if (!default_log_func)
default_log_func = g_log_default_handler;
- if (vasprintf (&msg, format, args) < 0)
+ if (g_vasprintf (&msg, format, args) < 0)
return;
default_log_func (log_domain, log_level, msg, default_log_func_user_data);
- free (msg);
+ g_free (msg);
}
void
#include <stdio.h>
#include <glib.h>
#include <errno.h>
+#include <sys/stat.h>
#ifdef G_OS_WIN32
#include <direct.h>
{
return name;
}
+
+gboolean
+g_ensure_directory_exists (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+ gchar *dir_utf8 = g_path_get_dirname (filename);
+ gunichar2 *p;
+ gunichar2 *dir_utf16 = NULL;
+ int retval;
+
+ if (!dir_utf8 || !dir_utf8 [0])
+ return FALSE;
+
+ dir_utf16 = g_utf8_to_utf16 (dir_utf8, strlen (dir_utf8), NULL, NULL, NULL);
+ g_free (dir_utf8);
+
+ if (!dir_utf16)
+ return FALSE;
+
+ p = dir_utf16;
+
+ /* make life easy and only use one directory seperator */
+ while (*p != '\0')
+ {
+ if (*p == '/')
+ *p = '\\';
+ p++;
+ }
+
+ p = dir_utf16;
+
+ /* get past C:\ )*/
+ while (*p++ != '\\')
+ {
+ }
+
+ while (1) {
+ gboolean bRet = FALSE;
+ p = wcschr (p, '\\');
+ if (p)
+ *p = '\0';
+ retval = _wmkdir (dir_utf16);
+ if (retval != 0 && errno != EEXIST) {
+ g_free (dir_utf16);
+ return FALSE;
+ }
+ if (!p)
+ break;
+ *p++ = '\\';
+ }
+
+ g_free (dir_utf16);
+ return TRUE;
+#else
+ char *p;
+ gchar *dir = g_path_get_dirname (filename);
+ int retval;
+ struct stat sbuf;
+
+ if (!dir || !dir [0]) {
+ g_free (dir);
+ return FALSE;
+ }
+
+ if (stat (dir, &sbuf) == 0 && S_ISDIR (sbuf.st_mode)) {
+ g_free (dir);
+ return TRUE;
+ }
+
+ p = dir;
+ while (*p == '/')
+ p++;
+
+ while (1) {
+ p = strchr (p, '/');
+ if (p)
+ *p = '\0';
+ retval = mkdir (dir, 0777);
+ if (retval != 0 && errno != EEXIST) {
+ g_free (dir);
+ return FALSE;
+ }
+ if (!p)
+ break;
+ *p++ = '/';
+ }
+
+ g_free (dir);
+ return TRUE;
+#endif
+}
+
#include <ctype.h>
#include <glib.h>
-#include "vasprintf.h"
+/*
+ * g_strndup and g_vasprintf need to allocate memory with g_malloc if
+ * ENABLE_OVERRIDABLE_ALLOCATORS is defined so that it can be safely freed with g_free
+ * rather than free.
+ */
/* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */
gchar *
g_strndup (const gchar *str, gsize n)
{
-#ifdef HAVE_STRNDUP
+#if defined (HAVE_STRNDUP) && !defined (ENABLE_OVERRIDABLE_ALLOCATORS)
return strndup (str, n);
#else
if (str) {
#endif
}
+gint g_vasprintf (gchar **ret, const gchar *fmt, va_list ap)
+{
+#if defined (HAVE_VASPRINTF) && !defined (ENABLE_OVERRIDABLE_ALLOCATORS)
+ return vasprintf (ret, fmt, ap);
+#else
+ char *buf;
+ int len;
+ size_t buflen;
+ va_list ap2;
+
+#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
+ ap2 = ap;
+ len = _vscprintf(fmt, ap2); // NOTE MS specific extension ( :-( )
+#else
+ va_copy(ap2, ap);
+ len = vsnprintf(NULL, 0, fmt, ap2);
+#endif
+
+ if (len >= 0 && (buf = g_malloc ((buflen = (size_t) (len + 1)))) != NULL) {
+ len = vsnprintf(buf, buflen, fmt, ap);
+ *ret = buf;
+ } else {
+ *ret = NULL;
+ len = -1;
+ }
+
+ va_end(ap2);
+ return len;
+#endif
+}
+
void
g_strfreev (gchar **str_array)
{
int n;
char *ret;
- n = vasprintf (&ret, format, args);
+ n = g_vasprintf (&ret, format, args);
if (n == -1)
return NULL;
int n;
va_start (args, format);
- n = vasprintf (&ret, format, args);
+ n = g_vasprintf (&ret, format, args);
va_end (args);
if (n == -1)
return NULL;
+++ /dev/null
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int vasprintf(char **ret, const char *fmt, va_list ap)
-{
- char *buf;
- int len;
- size_t buflen;
- va_list ap2;
-
-#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
- ap2 = ap;
- len = _vscprintf(fmt, ap2); // NOTE MS specific extension ( :-( )
-#else
- va_copy(ap2, ap);
- len = vsnprintf(NULL, 0, fmt, ap2);
-#endif
-
- if (len >= 0 && (buf = malloc ((buflen = (size_t) (len + 1)))) != NULL) {
- len = vsnprintf(buf, buflen, fmt, ap);
- *ret = buf;
- } else {
- *ret = NULL;
- len = -1;
- }
-
- va_end(ap2);
- return len;
-}
-
+++ /dev/null
-#ifndef __VASPRINTF_H
-#define __VASPRINTF_H
-
-#include <stdarg.h>
-#include <config.h>
-
-#ifndef HAVE_VASPRINTF
-int vasprintf(char **ret, const char *fmt, va_list ap);
-#endif
-
-#endif /* __VASPRINTF_H */
#include "test.h"
extern gint global_passed, global_tests;
-
-#ifndef HAVE_VASPRINTF
- /* systen does not provide a vasprintf function, use the one
- provided within eglib itself */
-extern int vasprintf(char **ret, const char *format, va_list ap);
-#endif
-
static gchar *last_result = NULL;
gboolean
return NULL;
#else
va_start(args, format);
- n = vasprintf(&ret, format, args);
+ n = g_vasprintf(&ret, format, args);
va_end(args);
if(n == -1) {
.I llvm-path=<PREFIX>
Same for the llvm tools 'opt' and 'llc'.
.TP
-.I gen-seq-points-file=FILE.msym
+.I msym-dir=<PATH>
Instructs the AOT compiler to generate offline sequence points .msym files.
-The path is optional, if none is passed then a .msym file will be generated
-next to the input assembly.
+The generated .msym files will be stored into a subfolder of <PATH> named as the
+compilation AOTID.
.TP
.I mtriple=<TRIPLE>
Use the GNU style target triple <TRIPLE> to determine some code generation options, i.e.
IL stack is empty. These are places where the debugger can set a
breakpoint.
.TP
-\fBgen-compact-seq-points\fR
-This option generates sequence points data that maps native offsets to
-IL offsets. Sequence point data is used to display IL offset in
-stacktraces. Stacktraces with IL offsets can be symbolicated using
-mono-symbolicate tool.
+\fBno-compact-seq-points\fR
+Unless the option is used, the runtime generates sequence points data that
+maps native offsets to IL offsets. Sequence point data is used to
+display IL offset in stacktraces. Stacktraces with IL offsets can be
+symbolicated using mono-symbolicate tool.
.TP
\fBhandle-sigint\fR
Captures the interrupt signal (Control-C) and displays a stack trace
-d:NET_4_0 \
-d:NET_4_5 \
-d:MONO \
+ -d:NETSTANDARD \
-nowarn:1699 \
-nostdlib \
$(DEFAULT_REFERENCES) \
-d:NET_4_0 \
-d:NET_4_5 \
-d:MONO \
+ -d:NETSTANDARD \
-d:MOBILE,MOBILE_STATIC,MOBILE_LEGACY \
-d:FULL_AOT_RUNTIME \
-d:DISABLE_REMOTING \
-d:MOBILE_DYNAMIC \
-d:MONODROID \
-d:ANDROID \
+ -d:NETSTANDARD \
-nowarn:1699 \
-nostdlib \
$(DEFAULT_REFERENCES) \
-d:DISABLE_REMOTING \
-d:DISABLE_COM \
-d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK \
+ -d:NETSTANDARD \
-nowarn:1699 \
-nostdlib \
$(DEFAULT_REFERENCES) \
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+RegistryAclExtensions.cs
--- /dev/null
+//
+// RegistryAclExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Security;
+using System.Security.AccessControl;
+
+namespace Microsoft.Win32
+{
+ public static class RegistryAclExtensions
+ {
+ [MonoTODO]
+ public static RegistrySecurity GetAccessControl (this RegistryKey key)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static RegistrySecurity GetAccessControl (this RegistryKey key, AccessControlSections includeSections)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (this RegistryKey key, RegistrySecurity registrySecurity)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.RegistryAccessRule))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.RegistryAuditRule))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.RegistrySecurity))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryAclExtensions))]
// THE SOFTWARE.
//
-#if !MOBILE
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.Registry))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryHive))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryValueKind))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryValueOptions))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryView))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeRegistryHandle))]
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.BrowsableAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CategoryAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ComponentCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DescriptionAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignOnlyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignerCategoryAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignerSerializationVisibility))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignerSerializationVisibilityAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DisplayNameAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EventHandlerList))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IComponent))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IContainer))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ISite))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ImmutableObjectAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.InitializationEventAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.LocalizableAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.MergablePropertyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.NotifyParentPropertyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ParenthesizePropertyNameAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ReadOnlyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshProperties))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshPropertiesAttribute))]
//
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ArrayConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.AttributeCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.AttributeProviderAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.BaseNumberConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.BooleanConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ByteConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CancelEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CharConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionChangeAction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionChangeEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionChangeEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CustomTypeDescriptor))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DateTimeConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DateTimeOffsetConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DecimalConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DefaultEventAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DefaultPropertyAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DoubleConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EnumConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EventDescriptor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EventDescriptorCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ExtenderProvidedPropertyAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.GuidConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.HandledEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.HandledEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ICustomTypeDescriptor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IExtenderProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IListSource))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ITypeDescriptorContext))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ITypedList))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.Int16Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.Int32Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.Int64Converter))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ITypeDescriptorContext))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.InvalidAsynchronousStateException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.MemberDescriptor))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.MultilineStringConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.NullableConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.PropertyDescriptor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.PropertyDescriptorCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ProvidePropertyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.SByteConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.SingleConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.StringConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TimeSpanConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeConverterAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeDescriptionProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeDescriptionProviderAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeDescriptor))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeListConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.UInt16Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.UInt32Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.UInt64Converter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.UriTypeConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleCancelEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleCancelEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleColor))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleSpecialKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleKeyInfo))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleModifiers))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleSpecialKey))]
--- /dev/null
+//
+// DbColumn.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Collections.Generic;
+
+namespace System.Data.Common
+{
+ public abstract class DbColumn
+ {
+ public bool? AllowDBNull { get; protected set; }
+ public string BaseCatalogName { get; protected set; }
+ public string BaseColumnName { get; protected set; }
+ public string BaseSchemaName { get; protected set; }
+ public string BaseServerName { get; protected set; }
+ public string BaseTableName { get; protected set; }
+ public string ColumnName { get; protected set; }
+ public int? ColumnOrdinal { get; protected set; }
+ public int? ColumnSize { get; protected set; }
+ public bool? IsAliased { get; protected set; }
+ public bool? IsAutoIncrement { get; protected set; }
+ public bool? IsExpression { get; protected set; }
+ public bool? IsHidden { get; protected set; }
+ public bool? IsIdentity { get; protected set; }
+ public bool? IsKey { get; protected set; }
+ public bool? IsLong { get; protected set; }
+ public bool? IsReadOnly { get; protected set; }
+ public bool? IsUnique { get; protected set; }
+ public int? NumericPrecision { get; protected set; }
+ public int? NumericScale { get; protected set; }
+ public string UdtAssemblyQualifiedName { get; protected set; }
+ public Type DataType { get; protected set; }
+ public string DataTypeName { get; protected set; }
+ public virtual object this[string property] {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+
+namespace System.Data.Common
+{
+
+ internal class DataRowDbColumn : DbColumn
+ {
+ private DataColumnCollection schemaColumns;
+ private DataRow schemaRow;
+
+ public DataRowDbColumn(DataRow readerSchemaRow, DataColumnCollection readerSchemaColumns)
+ {
+ this.schemaRow = readerSchemaRow;
+ this.schemaColumns = readerSchemaColumns;
+ populateFields();
+ }
+
+ private void populateFields()
+ {
+ AllowDBNull = GetDbColumnValue<bool?>(SchemaTableColumn.AllowDBNull);
+ BaseCatalogName = GetDbColumnValue<string>(SchemaTableOptionalColumn.BaseCatalogName);
+ BaseColumnName = GetDbColumnValue<string>(SchemaTableColumn.BaseColumnName);
+ BaseSchemaName = GetDbColumnValue<string>(SchemaTableColumn.BaseSchemaName);
+ BaseServerName = GetDbColumnValue<string>(SchemaTableOptionalColumn.BaseServerName);
+ BaseTableName = GetDbColumnValue<string>(SchemaTableColumn.BaseTableName);
+ ColumnName = GetDbColumnValue<string>(SchemaTableColumn.ColumnName);
+ ColumnOrdinal = GetDbColumnValue<int?>(SchemaTableColumn.ColumnOrdinal);
+ ColumnSize = GetDbColumnValue<int?>(SchemaTableColumn.ColumnSize);
+ IsAliased = GetDbColumnValue<bool?>(SchemaTableColumn.IsAliased);
+ IsAutoIncrement = GetDbColumnValue<bool?>(SchemaTableOptionalColumn.IsAutoIncrement);
+ IsExpression = GetDbColumnValue<bool>(SchemaTableColumn.IsExpression);
+ IsHidden = GetDbColumnValue<bool?>(SchemaTableOptionalColumn.IsHidden);
+ IsIdentity = GetDbColumnValue<bool?>("IsIdentity");
+ IsKey = GetDbColumnValue<bool?>(SchemaTableColumn.IsKey);
+ IsLong = GetDbColumnValue<bool?>(SchemaTableColumn.IsLong);
+ IsReadOnly = GetDbColumnValue<bool?>(SchemaTableOptionalColumn.IsReadOnly);
+ IsUnique = GetDbColumnValue<bool?>(SchemaTableColumn.IsUnique);
+ NumericPrecision = GetDbColumnValue<int?>(SchemaTableColumn.NumericPrecision);
+ NumericScale = GetDbColumnValue<int?>(SchemaTableColumn.NumericScale);
+ UdtAssemblyQualifiedName = GetDbColumnValue<string>("UdtAssemblyQualifiedName");
+ DataType = GetDbColumnValue<Type>(SchemaTableColumn.DataType);
+ DataTypeName = GetDbColumnValue<string>("DataTypeName");
+ }
+
+ private T GetDbColumnValue<T>(string columnName)
+ {
+ if (!schemaColumns.Contains(columnName))
+ {
+ return default(T);
+ }
+ object schemaObject = schemaRow[columnName];
+ if (schemaObject is T)
+ {
+ return (T)schemaObject;
+ }
+ return default(T);
+ }
+ }
+
+ public static class DbDataReaderExtensions
+ {
+ public static System.Collections.ObjectModel.ReadOnlyCollection<DbColumn> GetColumnSchema(this DbDataReader reader)
+ {
+ IList<DbColumn> columnSchema = new List<DbColumn>();
+ DataTable schemaTable = reader.GetSchemaTable();
+ DataColumnCollection schemaTableColumns = schemaTable.Columns;
+ foreach (DataRow row in schemaTable.Rows)
+ {
+ DbColumn dbColumn = new DataRowDbColumn(row, schemaTableColumns);
+ columnSchema.Add(dbColumn);
+ }
+ System.Collections.ObjectModel.ReadOnlyCollection<DbColumn> readOnlyColumnSchema = new System.Collections.ObjectModel.ReadOnlyCollection<DbColumn>(columnSchema);
+ return readOnlyColumnSchema;
+ }
+
+ public static bool CanGetColumnSchema(this DbDataReader reader)
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// IDbColumnSchemaGenerator.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Data.Common
+{
+ public interface IDbColumnSchemaGenerator
+ {
+ System.Collections.ObjectModel.ReadOnlyCollection<DbColumn> GetColumnSchema();
+ }
+}
\ No newline at end of file
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System System.Data
+LIB_REFS = System System.Data System.Xml
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
TypeForwarders.cs
AssemblyInfo.cs
-
+IDbColumnSchemaGenerator.cs
+DbColumn.cs
+DbDataReaderExtensions.Facade.cs
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DBNull))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.CommandBehavior))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.CommandType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbCommand))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbConnection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbConnectionStringBuilder))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataReader))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataRecord))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbEnumerator))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbParameter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbParameterCollection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbProviderFactory))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbTransaction))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ConnectionState))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTable))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DbType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataParameter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataParameterCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataReader))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataRecord))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbCommand))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbConnection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbDataParameter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbTransaction))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IsolationLevel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ParameterDirection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StateChangeEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StateChangeEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.UpdateRowSource))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DBNull))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.SqlServer.Server.SqlMetaData))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.ApplicationIntent))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SortOrder))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopy))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopyColumnMapping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopyColumnMappingCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopyOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlClientFactory))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlCommand))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlConnection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlInfoMessageEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlParameter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlParameterCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlRowsCopiedEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlRowsCopiedEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlTransaction))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlDbType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.INullable))]
// THE SOFTWARE.
//
-// TODO: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeProcessHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeProcessHandle))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.DataReceivedEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.DataReceivedEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Process))]
--- /dev/null
+//
+// StackFrameExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace System.Diagnostics
+{
+ public static class StackFrameExtensions
+ {
+ [MonoTODO]
+ public static bool HasNativeImage (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool HasMethod (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool HasILOffset (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool HasSource (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+StackFrameExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackFrame))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackTrace))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackFrameExtensions))]
--- /dev/null
+//
+// EventCounter.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Diagnostics.Tracing
+{
+ public class EventCounter
+ {
+ public EventCounter (string name, EventSource eventSource)
+ {
+ }
+
+ public void WriteMetric (float value)
+ {
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+EventCounter.cs
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventActivityOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventChannel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventCommand))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventCommandEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventDataAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldFormat))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldTags))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventIgnoreAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventKeywords))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventLevel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventListener))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventManifestOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventOpcode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSource))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceSettings))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceSettings))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTags))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTask))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventWrittenEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.NonEventAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventActivityOptions))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventChannel))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventDataAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldFormat))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldTags))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventIgnoreAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventManifestOptions))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceOptions))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTags))]
--- /dev/null
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Drawing.Primitives.dll")]
+[assembly: AssemblyDescription ("System.Drawing.Primitives.dll")]
+[assembly: AssemblyDefaultAlias ("System.Drawing.Primitives.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Drawing.Primitives
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Drawing.Primitives.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+ifneq (2.1, $(FRAMEWORK_VERSION))
+ifndef XAMMAC_4_5
+LIB_REFS += System.Drawing
+endif
+endif
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.Point))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.PointF))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.Rectangle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.RectangleF))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.Size))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.SizeF))]
--- /dev/null
+AssemblyInfo.cs
+
+../../System.Drawing/System.Drawing/Point.cs
+../../System.Drawing/System.Drawing/PointF.cs
+../../System.Drawing/System.Drawing/Rectangle.cs
+../../System.Drawing/System.Drawing/RectangleF.cs
+../../System.Drawing/System.Drawing/Size.cs
+../../System.Drawing/System.Drawing/SizeF.cs
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include mobile_System.Drawing.Primitives.dll.sources
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ public static class GlobalizationExtensions
+ {
+ public static StringComparer GetStringComparer(this CompareInfo compareInfo, CompareOptions options)
+ {
+ if (compareInfo == null)
+ {
+ throw new ArgumentNullException(nameof(compareInfo));
+ }
+
+ if (options == CompareOptions.Ordinal)
+ {
+ return StringComparer.Ordinal;
+ }
+
+ if (options == CompareOptions.OrdinalIgnoreCase)
+ {
+ return StringComparer.OrdinalIgnoreCase;
+ }
+
+ if ((options & CultureAwareComparer.ValidCompareMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
+
+ return new CultureAwareComparer(compareInfo, options);
+ }
+ }
+
+ internal sealed class CultureAwareComparer : StringComparer
+ {
+ internal const CompareOptions ValidCompareMaskOffFlags =
+ ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
+ CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
+
+ private readonly CompareInfo _compareInfo;
+ private readonly CompareOptions _options;
+
+ internal CultureAwareComparer(CompareInfo compareInfo, CompareOptions options)
+ {
+ Debug.Assert((options & ValidCompareMaskOffFlags) == 0);
+ _compareInfo = compareInfo;
+ _options = options;
+ }
+
+ public override int Compare(string x, string y)
+ {
+ if (Object.ReferenceEquals(x, y)) return 0;
+ if (x == null) return -1;
+ if (y == null) return 1;
+ return _compareInfo.Compare(x, y, _options);
+ }
+
+ public override bool Equals(string x, string y)
+ {
+ if (Object.ReferenceEquals(x, y)) return true;
+ if (x == null || y == null) return false;
+
+ return (_compareInfo.Compare(x, y, _options) == 0);
+ }
+
+ public override int GetHashCode(string obj)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+ Contract.EndContractBlock();
+
+ // StringSort used in compare operation and not with the hashing
+ return _compareInfo.GetHashCode(obj, _options & (~CompareOptions.StringSort));
+ }
+
+ // Equals method for the comparer itself.
+ public override bool Equals(object obj)
+ {
+ CultureAwareComparer comparer = obj as CultureAwareComparer;
+ return
+ comparer != null &&
+ _options == comparer._options &&
+ _compareInfo.Equals(comparer._compareInfo);
+ }
+
+ public override int GetHashCode()
+ {
+ return _compareInfo.GetHashCode() ^ ((int)_options & 0x7FFFFFFF);
+ }
+ }
+}
--- /dev/null
+partial class SR
+{
+ public const string Argument_InvalidFlag = "Value of flags is invalid.";
+}
\ No newline at end of file
--- /dev/null
+//
+// StringNormalizationExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System.Text;
+
+namespace System
+{
+ public static class StringNormalizationExtensions
+ {
+ [MonoTODO]
+ public static bool IsNormalized(this string value)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool IsNormalized(this string value, NormalizationForm normalizationForm)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static String Normalize(this string value)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static String Normalize(this string value, NormalizationForm normalizationForm)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+SR.cs
+GlobalizationExtensions.cs
+StringNormalizationExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Globalization.IdnMapping))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Text.NormalizationForm))]
-// Missing: [assembly:System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Globalization.GlobalizationExtensions))]
-// Missing: [assembly:System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.StringNormalizationExtensions))]
--- /dev/null
+// This is stub only. The implementation should come from https://github.com/dotnet/corefx/tree/master/src/System.IO.Compression/src/System/IO/Compression
+
+namespace System.IO.Compression
+{
+ public class ZipArchive : System.IDisposable
+ {
+ public ZipArchive(System.IO.Stream stream) { }
+ public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode) { }
+ public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) { }
+ public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding entryNameEncoding) { }
+ public System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry> Entries { get { return default(System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry>); } }
+ public System.IO.Compression.ZipArchiveMode Mode { get { return default(System.IO.Compression.ZipArchiveMode); } }
+ public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName) { return default(System.IO.Compression.ZipArchiveEntry); }
+ public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName, System.IO.Compression.CompressionLevel compressionLevel) { return default(System.IO.Compression.ZipArchiveEntry); }
+ public void Dispose() { }
+ protected virtual void Dispose(bool disposing) { }
+ public System.IO.Compression.ZipArchiveEntry GetEntry(string entryName) { return default(System.IO.Compression.ZipArchiveEntry); }
+ }
+
+ public partial class ZipArchiveEntry
+ {
+ internal ZipArchiveEntry() { }
+ public System.IO.Compression.ZipArchive Archive { get { return default(System.IO.Compression.ZipArchive); } }
+ public long CompressedLength { get { return default(long); } }
+ public string FullName { get { return default(string); } }
+ public System.DateTimeOffset LastWriteTime { get { return default(System.DateTimeOffset); } set { } }
+ public long Length { get { return default(long); } }
+ public string Name { get { return default(string); } }
+ public void Delete() { }
+ public System.IO.Stream Open() { return default(System.IO.Stream); }
+ public override string ToString() { return default(string); }
+ }
+
+ public enum ZipArchiveMode
+ {
+ Create = 1,
+ Read = 0,
+ Update = 2,
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+Missing.cs
--- /dev/null
+//
+// FileSystemAclExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.IO
+{
+ public static partial class FileSystemAclExtensions
+ {
+ [MonoTODO]
+ public static System.Security.AccessControl.DirectorySecurity GetAccessControl(this System.IO.DirectoryInfo directoryInfo)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.DirectorySecurity GetAccessControl(this System.IO.DirectoryInfo directoryInfo, System.Security.AccessControl.AccessControlSections includeSections)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileInfo fileInfo)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileInfo fileInfo, System.Security.AccessControl.AccessControlSections includeSections)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileStream fileStream)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl(this System.IO.DirectoryInfo directoryInfo, System.Security.AccessControl.DirectorySecurity directorySecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl(this System.IO.FileInfo fileInfo, System.Security.AccessControl.FileSecurity fileSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl(this System.IO.FileStream fileStream, System.Security.AccessControl.FileSecurity fileSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+FileSystemAclExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.FileSystemAuditRule))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.FileSystemRights))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.FileSystemSecurity))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.FileSystemAclExtensions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.RenamedEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.RenamedEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.WatcherChangeTypes))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.WaitForChangedResult))]
--- /dev/null
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.IO.Packaging.dll")]
+[assembly: AssemblyDescription ("System.IO.Packaging.dll")]
+[assembly: AssemblyDefaultAlias ("System.IO.Packaging.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.IO.Packaging
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.IO.Packaging.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System WindowsBase
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.FileFormatException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.CompressionOption))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.EncryptionOption))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackUriHelper))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.Package))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackagePart))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackagePartCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageProperties))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationship))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationshipCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationshipSelector))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationshipSelectorType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.TargetMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.ZipPackage))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.ZipPackagePart))]
--- /dev/null
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Net.Ping.dll")]
+[assembly: AssemblyDescription ("System.Net.Ping.dll")]
+[assembly: AssemblyDefaultAlias ("System.Net.Ping.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Net.Ping
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Net.Ping.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.IPStatus))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.Ping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.PingException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.PingOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.PingReply))]
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.AuthenticatedStream))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.EncryptionPolicy))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.LocalCertificateSelectionCallback))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.NegotiateStream))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.ProtectionLevel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.RemoteCertificateValidationCallback))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.SslStream))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.AuthenticationException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.ExtendedProtection.PolicyEnforcement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.ExtendedProtection.ProtectionScenario))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.ExtendedProtection.ServiceNameCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.InvalidCredentialException))]
--- /dev/null
+//
+// SocketReceiveFromResult.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Sockets
+{
+ public struct SocketReceiveFromResult
+ {
+ public int ReceivedBytes;
+ public EndPoint RemoteEndPoint;
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SocketReceiveMessageFromResult.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Sockets
+{
+ public struct SocketReceiveMessageFromResult
+ {
+ public int ReceivedBytes;
+ public SocketFlags SocketFlags;
+ public EndPoint RemoteEndPoint;
+ public IPPacketInformation PacketInformation;
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Net.Sockets
+{
+ public static class SocketTaskExtensions
+ {
+ public static Task<Socket> AcceptAsync(this Socket socket)
+ {
+ return Task<Socket>.Factory.FromAsync(
+ (callback, state) => ((Socket)state).BeginAccept(callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult),
+ state: socket);
+ }
+
+ public static Task<Socket> AcceptAsync(this Socket socket, Socket acceptSocket)
+ {
+ const int ReceiveSize = 0;
+ return Task<Socket>.Factory.FromAsync(
+ (socketForAccept, receiveSize, callback, state) => ((Socket)state).BeginAccept(socketForAccept, receiveSize, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult),
+ acceptSocket,
+ ReceiveSize,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, EndPoint remoteEndPoint)
+ {
+ return Task.Factory.FromAsync(
+ (targetEndPoint, callback, state) => ((Socket)state).BeginConnect(targetEndPoint, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ remoteEndPoint,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, IPAddress address, int port)
+ {
+ return Task.Factory.FromAsync(
+ (targetAddress, targetPort, callback, state) => ((Socket)state).BeginConnect(targetAddress, targetPort, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ address,
+ port,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, IPAddress[] addresses, int port)
+ {
+ return Task.Factory.FromAsync(
+ (targetAddresses, targetPort, callback, state) => ((Socket)state).BeginConnect(targetAddresses, targetPort, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ addresses,
+ port,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, string host, int port)
+ {
+ return Task.Factory.FromAsync(
+ (targetHost, targetPort, callback, state) => ((Socket)state).BeginConnect(targetHost, targetPort, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ host,
+ port,
+ state: socket);
+ }
+
+ public static Task<int> ReceiveAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffer, flags, callback, state) => ((Socket)state).BeginReceive(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ callback,
+ state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndReceive(asyncResult),
+ buffer,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<int> ReceiveAsync(
+ this Socket socket,
+ IList<ArraySegment<byte>> buffers,
+ SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffers, flags, callback, state) => ((Socket)state).BeginReceive(targetBuffers, flags, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndReceive(asyncResult),
+ buffers,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<SocketReceiveFromResult> ReceiveFromAsync(
+ this Socket socket,
+ ArraySegment<byte> buffer,
+ SocketFlags socketFlags,
+ EndPoint remoteEndPoint)
+ {
+ object[] packedArguments = new object[] { socket, remoteEndPoint };
+
+ return Task<SocketReceiveFromResult>.Factory.FromAsync(
+ (targetBuffer, flags, callback, state) =>
+ {
+ var arguments = (object[])state;
+ var s = (Socket)arguments[0];
+ var e = (EndPoint)arguments[1];
+
+ IAsyncResult result = s.BeginReceiveFrom(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ ref e,
+ callback,
+ state);
+
+ arguments[1] = e;
+ return result;
+ },
+ asyncResult =>
+ {
+ var arguments = (object[])asyncResult.AsyncState;
+ var s = (Socket)arguments[0];
+ var e = (EndPoint)arguments[1];
+
+ int bytesReceived = s.EndReceiveFrom(asyncResult, ref e);
+
+ return new SocketReceiveFromResult()
+ {
+ ReceivedBytes = bytesReceived,
+ RemoteEndPoint = e
+ };
+ },
+ buffer,
+ socketFlags,
+ state: packedArguments);
+ }
+
+ public static Task<SocketReceiveMessageFromResult> ReceiveMessageFromAsync(
+ this Socket socket,
+ ArraySegment<byte> buffer,
+ SocketFlags socketFlags,
+ EndPoint remoteEndPoint)
+ {
+ object[] packedArguments = new object[] { socket, socketFlags, remoteEndPoint };
+
+ return Task<SocketReceiveMessageFromResult>.Factory.FromAsync(
+ (targetBuffer, callback, state) =>
+ {
+ var arguments = (object[])state;
+ var s = (Socket)arguments[0];
+ var f = (SocketFlags)arguments[1];
+ var e = (EndPoint)arguments[2];
+
+ IAsyncResult result = s.BeginReceiveMessageFrom(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ f,
+ ref e,
+ callback,
+ state);
+
+ arguments[2] = e;
+ return result;
+ },
+ asyncResult =>
+ {
+ var arguments = (object[])asyncResult.AsyncState;
+ var s = (Socket)arguments[0];
+ var f = (SocketFlags)arguments[1];
+ var e = (EndPoint)arguments[2];
+ IPPacketInformation ipPacket;
+
+ int bytesReceived = s.EndReceiveMessageFrom(
+ asyncResult,
+ ref f,
+ ref e,
+ out ipPacket);
+
+ return new SocketReceiveMessageFromResult()
+ {
+ PacketInformation = ipPacket,
+ ReceivedBytes = bytesReceived,
+ RemoteEndPoint = e,
+ SocketFlags = f
+ };
+ },
+ buffer,
+ state: packedArguments);
+ }
+
+ public static Task<int> SendAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffer, flags, callback, state) => ((Socket)state).BeginSend(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ callback,
+ state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndSend(asyncResult),
+ buffer,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<int> SendAsync(
+ this Socket socket,
+ IList<ArraySegment<byte>> buffers,
+ SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffers, flags, callback, state) => ((Socket)state).BeginSend(targetBuffers, flags, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndSend(asyncResult),
+ buffers,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<int> SendToAsync(
+ this Socket socket,
+ ArraySegment<byte> buffer,
+ SocketFlags socketFlags,
+ EndPoint remoteEndPoint)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffer, flags, endPoint, callback, state) => ((Socket)state).BeginSendTo(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ endPoint,
+ callback,
+ state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndSendTo(asyncResult),
+ buffer,
+ socketFlags,
+ remoteEndPoint,
+ state: socket);
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+SocketReceiveFromResult.cs
+SocketReceiveMessageFromResult.cs
+SocketTaskExtensions.cs
// THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.FlowControl))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OpCode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OpCodes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OperandType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.PackingSize))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.StackBehaviour))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.CallingConventions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.EventAttributes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.FieldAttributes))]
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Reflection
+{
+ internal static class Requires
+ {
+ internal static void NotNull(object obj, string name)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException(name);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+partial class SR
+{
+ public const string NoMetadataTokenAvailable = "There is no metadata token available for the given member.";
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+SR.cs
+Requires.cs
+TypeExtensions.CoreCLR.cs
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// NOTE: These are extension methods in the contract, but plain static methods
+// in this implementation. This is done to avoid confusion around what would
+// look like infinite recursion in the implementation. Callers compiled against
+// the contract will still be able to invoke them as extension methods and get
+// source compatibility with classic reflection code.
+//
+// However, this does not apply if there is no 1:1 correspondence with an instance
+// in mscorlib. New extension methods should be marked with 'this'.
+
+namespace System.Reflection
+{
+ public static class TypeExtensions
+ {
+ public static ConstructorInfo GetConstructor(Type type, Type[] types)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetConstructor(types);
+ }
+
+ public static ConstructorInfo[] GetConstructors(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetConstructors();
+ }
+
+ public static ConstructorInfo[] GetConstructors(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetConstructors(bindingAttr);
+ }
+
+ public static MemberInfo[] GetDefaultMembers(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetDefaultMembers();
+ }
+
+ public static EventInfo GetEvent(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvent(name);
+ }
+
+ public static EventInfo GetEvent(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvent(name, bindingAttr);
+ }
+
+ public static EventInfo[] GetEvents(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvents();
+ }
+
+ public static EventInfo[] GetEvents(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvents(bindingAttr);
+ }
+
+ public static FieldInfo GetField(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetField(name);
+ }
+
+ public static FieldInfo GetField(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetField(name, bindingAttr);
+ }
+
+ public static FieldInfo[] GetFields(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetFields();
+ }
+
+ public static FieldInfo[] GetFields(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetFields(bindingAttr);
+ }
+
+ public static Type[] GetGenericArguments(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetGenericArguments();
+ }
+
+ public static Type[] GetInterfaces(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetInterfaces();
+ }
+
+ public static MemberInfo[] GetMember(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMember(name);
+ }
+
+ public static MemberInfo[] GetMember(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMember(name, bindingAttr);
+ }
+
+ public static MemberInfo[] GetMembers(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMembers();
+ }
+
+ public static MemberInfo[] GetMembers(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMembers(bindingAttr);
+ }
+
+ public static MethodInfo GetMethod(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethod(name);
+ }
+
+ public static MethodInfo GetMethod(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethod(name, bindingAttr);
+ }
+
+ public static MethodInfo GetMethod(Type type, string name, Type[] types)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethod(name, types);
+ }
+
+ public static MethodInfo[] GetMethods(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethods();
+ }
+
+ public static MethodInfo[] GetMethods(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethods(bindingAttr);
+ }
+
+ public static Type GetNestedType(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetNestedType(name, bindingAttr);
+ }
+
+ public static Type[] GetNestedTypes(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetNestedTypes(bindingAttr);
+ }
+
+ public static PropertyInfo[] GetProperties(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperties();
+ }
+
+ public static PropertyInfo[] GetProperties(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperties(bindingAttr);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name, bindingAttr);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name, Type returnType)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name, returnType);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name, Type returnType, Type[] types)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name, returnType, types);
+ }
+
+ public static bool IsAssignableFrom(Type type, Type c)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.IsAssignableFrom(c);
+ }
+
+ public static bool IsInstanceOfType(Type type, object o)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.IsInstanceOfType(o);
+ }
+ }
+
+ public static class AssemblyExtensions
+ {
+ public static Type[] GetExportedTypes(Assembly assembly)
+ {
+ Requires.NotNull(assembly, nameof(assembly));
+ return assembly.GetExportedTypes();
+ }
+
+ public static Module[] GetModules(Assembly assembly)
+ {
+ Requires.NotNull(assembly, nameof(assembly));
+ return assembly.GetModules();
+ }
+
+ public static Type[] GetTypes(Assembly assembly)
+ {
+ Requires.NotNull(assembly, nameof(assembly));
+ return assembly.GetTypes();
+ }
+ }
+
+ public static class EventInfoExtensions
+ {
+ public static MethodInfo GetAddMethod(EventInfo eventInfo)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetAddMethod();
+ }
+
+ public static MethodInfo GetAddMethod(EventInfo eventInfo, bool nonPublic)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetAddMethod(nonPublic);
+ }
+
+ public static MethodInfo GetRaiseMethod(EventInfo eventInfo)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRaiseMethod();
+ }
+
+ public static MethodInfo GetRaiseMethod(EventInfo eventInfo, bool nonPublic)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRaiseMethod(nonPublic);
+ }
+
+ public static MethodInfo GetRemoveMethod(EventInfo eventInfo)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRemoveMethod();
+ }
+
+ public static MethodInfo GetRemoveMethod(EventInfo eventInfo, bool nonPublic)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRemoveMethod(nonPublic);
+ }
+ }
+
+ public static class MemberInfoExtensions
+ {
+
+ /// <summary>
+ /// Determines if there is a metadata token available for the given member.
+ /// <see cref="GetMetadataToken(MemberInfo)"/> throws <see cref="InvalidOperationException"/> otherwise.
+ /// </summary>
+ /// <remarks>This maybe</remarks>
+ public static bool HasMetadataToken(this MemberInfo member)
+ {
+ Requires.NotNull(member, nameof(member));
+
+ try
+ {
+ return GetMetadataTokenOrZeroOrThrow(member) != 0;
+ }
+ catch (InvalidOperationException)
+ {
+ // Thrown for unbaked ref-emit members/types.
+ // Other cases such as typeof(byte[]).MetadataToken will be handled by comparison to zero above.
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets a metadata token for the given member if available. The returned token is never nil.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// There is no metadata token available. <see cref="HasMetadataToken(MemberInfo)"/> returns false in this case.
+ /// </exception>
+ public static int GetMetadataToken(this MemberInfo member)
+ {
+ Requires.NotNull(member, nameof(member));
+
+ int token = GetMetadataTokenOrZeroOrThrow(member);
+
+ if (token == 0)
+ {
+ throw new InvalidOperationException(SR.NoMetadataTokenAvailable);
+ }
+
+ return token;
+ }
+
+ private static int GetMetadataTokenOrZeroOrThrow(MemberInfo member)
+ {
+ int token = member.MetadataToken;
+
+ // Tokens have MSB = table index, 3 LSBs = row index
+ // row index of 0 is a nil token
+ const int rowMask = 0x00FFFFFF;
+ if ((token & rowMask) == 0)
+ {
+ // Nil token is returned for edge cases like typeof(byte[]).MetadataToken.
+ return 0;
+ }
+
+ return token;
+ }
+ }
+
+ public static class MethodInfoExtensions
+ {
+ public static MethodInfo GetBaseDefinition(MethodInfo method)
+ {
+ Requires.NotNull(method, nameof(method));
+ return method.GetBaseDefinition();
+ }
+ }
+
+ public static class ModuleExtensions
+ {
+ public static bool HasModuleVersionId(this Module module)
+ {
+ Requires.NotNull(module, nameof(module));
+ return true; // not expected to fail on platforms with Module.ModuleVersionId built-in.
+ }
+
+ public static Guid GetModuleVersionId(this Module module)
+ {
+ Requires.NotNull(module, nameof(module));
+ return module.ModuleVersionId;
+ }
+ }
+
+ public static class PropertyInfoExtensions
+ {
+ public static MethodInfo[] GetAccessors(PropertyInfo property)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetAccessors();
+ }
+
+ public static MethodInfo[] GetAccessors(PropertyInfo property, bool nonPublic)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetAccessors(nonPublic);
+ }
+
+ public static MethodInfo GetGetMethod(PropertyInfo property)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetGetMethod();
+ }
+
+ public static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetGetMethod(nonPublic);
+ }
+
+ public static MethodInfo GetSetMethod(PropertyInfo property)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetSetMethod();
+ }
+
+ public static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetSetMethod(nonPublic);
+ }
+ }
+}
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.BindingFlags))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.AssemblyExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.EventInfoExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.MethodInfoExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.PropertyInfoExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.TypeExtensions))]
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Runtime.Serialization.Formatters.dll")]
+[assembly: AssemblyDescription ("System.Runtime.Serialization.Formatters.dll")]
+[assembly: AssemblyDefaultAlias ("System.Runtime.Serialization.Formatters.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Runtime.Serialization.Formatters
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Runtime.Serialization.Formatters.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.NonSerializedAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.IDeserializationCallback))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.IFormatterConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.ISerializable))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationEntry))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationInfoEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.SerializableAttribute))]
+
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+namespace System.Runtime.Serialization
+{
+ public interface ISerializationSurrogateProvider
+ {
+ object GetDeserializedObject (object obj, Type targetType);
+ object GetObjectToSerialize (object obj, Type targetType);
+ Type GetSurrogateType (Type type);
+ }
+}
+
TypeForwarders.cs
AssemblyInfo.cs
-
+ISerializationSurrogateProvider.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.OnSerializingAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.StreamingContext))]
-
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.InvalidDataContractException))]
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#if !NO_CODEDOM
+using System.CodeDom;
+#endif
+using System.Collections.ObjectModel;
+using System.Reflection;
+
+namespace System.Runtime.Serialization
+{
+ public static class DataContractSerializerExtensions
+ {
+ public static ISerializationSurrogateProvider GetSerializationSurrogateProvider(this DataContractSerializer serializer)
+ {
+ SurrogateProviderAdapter adapter = serializer.DataContractSurrogate as SurrogateProviderAdapter;
+ return (adapter == null) ? null : adapter.Provider;
+ }
+
+ public static void SetSerializationSurrogateProvider(this DataContractSerializer serializer, ISerializationSurrogateProvider provider)
+ {
+ // allocate every time, expectation is that this won't happen enough to warrant maintaining a CondtionalWeakTable.
+ IDataContractSurrogate adapter = new SurrogateProviderAdapter(provider);
+
+ // DCS doesn't expose a setter, access the field directly as a workaround
+ typeof(DataContractSerializer)
+ .GetField("dataContractSurrogate", BindingFlags.Instance | BindingFlags.NonPublic)
+ .SetValue(serializer, adapter);
+ }
+
+ private class SurrogateProviderAdapter : IDataContractSurrogate
+ {
+ private ISerializationSurrogateProvider _provider;
+ public SurrogateProviderAdapter(ISerializationSurrogateProvider provider)
+ {
+ _provider = provider;
+ }
+
+ public ISerializationSurrogateProvider Provider { get { return _provider; } }
+ public object GetCustomDataToExport(Type clrType, Type dataContractType)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+ public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+ public Type GetDataContractType(Type type)
+ {
+ return _provider.GetSurrogateType(type);
+ }
+
+ public object GetDeserializedObject(object obj, Type targetType)
+ {
+ return _provider.GetDeserializedObject(obj, targetType);
+ }
+
+ public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+ public object GetObjectToSerialize(object obj, Type targetType)
+ {
+ return _provider.GetObjectToSerialize(obj, targetType);
+ }
+
+ public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+#if !NO_CODEDOM
+ public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
+ {
+ throw NotImplemented.ByDesign;
+ }
+#endif
+ }
+ }
+}
\ No newline at end of file
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System.Runtime.Serialization System.Xml
+LIB_REFS = System System.Runtime.Serialization System.Xml Facades/System.Runtime.Serialization.Primitives
LIB_MCS_FLAGS = $(SIGN_FLAGS)
+ifeq (2.1, $(FRAMEWORK_VERSION))
+LIB_MCS_FLAGS += /d:NO_CODEDOM
+endif
+
PLATFORM_DEBUG_FLAGS =
NO_TEST = yes
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System
+{
+ //
+ // This class enables one to throw a NotImplementedException using the following idiom:
+ //
+ // throw NotImplemented.ByDesign;
+ //
+ // Used by methods whose intended implementation is to throw a NotImplementedException (typically
+ // virtual methods in public abstract classes that intended to be subclassed by third parties.)
+ //
+ // This makes it distinguishable both from human eyes and CCI from NYI's that truly represent undone work.
+ //
+ internal static class NotImplemented
+ {
+ internal static Exception ByDesign
+ {
+ get
+ {
+ return new NotImplementedException();
+ }
+ }
+
+ internal static Exception ByDesignWithMessage(String message)
+ {
+ return new NotImplementedException(message);
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+
+DataContractSerializerExtensions.cs
+NotImplemented.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XmlDictionaryWriter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.OnXmlDictionaryReaderClose))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XmlDictionaryReaderQuotaTypes))]
--- /dev/null
+//
+// ECCurve.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct ECCurve
+ {
+ public byte[] A;
+ public byte[] B;
+ public byte[] Cofactor;
+ public ECCurveType CurveType;
+ public ECPoint G;
+ public HashAlgorithmName? Hash;
+ public byte[] Order;
+ public byte[] Polynomial;
+ public byte[] Prime;
+ public byte[] Seed;
+ public bool IsCharacteristic2 { get { throw new NotImplementedException (); } }
+ public bool IsExplicit { get { throw new NotImplementedException (); } }
+ public bool IsNamed { get { throw new NotImplementedException (); } }
+ public bool IsPrime { get { throw new NotImplementedException (); } }
+ public Oid Oid { get { throw new NotImplementedException (); } }
+ public static ECCurve CreateFromFriendlyName (string oidFriendlyName) { throw new NotImplementedException (); }
+ public static ECCurve CreateFromOid (Oid curveOid) { throw new NotImplementedException (); }
+ public static ECCurve CreateFromValue (string oidValue) { throw new NotImplementedException (); }
+ public void Validate () { throw new NotImplementedException (); }
+
+ public enum ECCurveType
+ {
+ Implicit = 0,
+ PrimeShortWeierstrass = 1,
+ PrimeTwistedEdwards = 2,
+ PrimeMontgomery = 3,
+ Characteristic2 = 4,
+ Named = 5,
+ }
+
+ public static class NamedCurves
+ {
+ public static ECCurve brainpoolP160r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP160t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP192r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP192t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP224r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP224t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP256r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP256t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP320r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP320t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP384r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP384t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP512r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP512t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve nistP256 { get { throw new NotImplementedException (); } }
+ public static ECCurve nistP384 { get { throw new NotImplementedException (); } }
+ public static ECCurve nistP521 { get { throw new NotImplementedException (); } }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// ECPArameters.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public partial struct ECParameters
+ {
+ public ECCurve Curve;
+ public byte[] D;
+ public ECPoint Q;
+ public void Validate () { throw new NotImplementedException (); }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// ECPoint.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct ECPoint
+ {
+ public byte[] X;
+ public byte[] Y;
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// IncrementalHash.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class IncrementalHash : IDisposable
+ {
+ private IncrementalHash () { }
+ public HashAlgorithmName AlgorithmName { get { throw new NotImplementedException (); } }
+ public void AppendData (byte[] data) { }
+ public void AppendData (byte[] data, int offset, int count) { }
+ public static IncrementalHash CreateHash (HashAlgorithmName hashAlgorithm) { throw new NotImplementedException (); }
+ public static IncrementalHash CreateHMAC (HashAlgorithmName hashAlgorithm, byte[] key) { throw new NotImplementedException (); }
+ public void Dispose () { }
+ public byte[] GetHashAndReset () { throw new NotImplementedException (); }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+ECCurve.cs
+ECPoint.cs
+ECParameters.cs
+IncrementalHash.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.Cng.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.Cng.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.Cng.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.Cng
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.Cng.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System System.Core
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AesCng))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngAlgorithm))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngAlgorithmGroup))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngExportPolicies))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKey))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyBlobFormat))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyCreationOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyCreationParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyHandleOpenOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyOpenOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyUsages))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngProperty))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngPropertyCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngPropertyOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngUIPolicy))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngUIProtectionLevels))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECDsaCng))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSACng))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.TripleDESCng))]
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.Csp.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.Csp.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.Csp.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.Csp
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.Csp.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CspKeyContainerInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CspParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CspProviderFlags))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ICspAsymmetricAlgorithm))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.KeyNumber))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSACryptoServiceProvider))]
+
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.OpenSsl.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.OpenSsl.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.OpenSsl.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+//
+// ECDsaOpenSsl.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class ECDsaOpenSsl : ECDsa
+ {
+ public override byte[] SignHash (byte[] hash)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool VerifyHash (byte[] hash, byte[] signature)
+ {
+ throw new NotImplementedException ();
+ }
+
+ // TODO: Implement full contract API
+ }
+}
\ No newline at end of file
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.OpenSsl
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.OpenSsl.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System.Core
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+//
+// RSAOpenSsl.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class RSAOpenSsl : RSA
+ {
+ public override RSAParameters ExportParameters (bool includePrivateParameters)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void ImportParameters (RSAParameters parameters)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override byte[] SignHash (byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool VerifyHash (byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
+ {
+ throw new NotImplementedException ();
+ }
+
+ // TODO: Implement full contract API
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeEvpPKeyHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class SafeEvpPKeyHandle : System.Runtime.InteropServices.SafeHandle
+ {
+ public SafeEvpPKeyHandle (IntPtr handle, bool ownsHandle)
+ : base (handle, ownsHandle)
+ {
+ }
+
+ public override bool IsInvalid { get { throw new NotImplementedException (); } }
+
+ public SafeEvpPKeyHandle DuplicateHandle ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected override bool ReleaseHandle ()
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+AssemblyInfo.cs
+ECDsaOpenSsl.cs
+RSAOpenSsl.cs
+SafeEvpPKeyHandle.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.Pkcs.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.Pkcs.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.Pkcs.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.Pkcs
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.Pkcs.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System System.Security
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptographicAttributeObject))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptographicAttributeObjectCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptographicAttributeObjectEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.AlgorithmIdentifier))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.CmsRecipient))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.CmsRecipientCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.CmsRecipientEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.ContentInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.EnvelopedCms))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.KeyAgreeRecipientInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.KeyTransRecipientInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9AttributeObject))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9ContentType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9DocumentDescription))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9DocumentName))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9MessageDigest))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9SigningTime))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.PublicKeyInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfoCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfoEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfoType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifier))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifierOrKey))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifierOrKeyType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifierType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Xml.X509IssuerSerial))]
+
+
// THE SOFTWARE.
//
-//TODO:[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeAccessTokenHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeAccessTokenHandle))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Principal.IdentityNotMappedException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Principal.IdentityReference))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Principal.IdentityReferenceCollection))]
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+namespace System.Security
+{
+ public static class SecureStringMarshal
+ {
+ public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static IntPtr SecureStringToCoTaskMemUnicode (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static IntPtr SecureStringToGlobalAllocAnsi (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
TypeForwarders.cs
AssemblyInfo.cs
-
+SecureStringMarshal.cs
//
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.SecureString))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.SecureStringMarshal))]
// THE SOFTWARE.
//
-#if !MOBILE && !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.CallbackBehaviorAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexChannelFactory<>))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexClientBase<>))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.InstanceContext))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpMessageCredentialType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpSecurity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpSecurityMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpsBinding))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpsSecurity))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpsSecurityMode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.HttpRequestMessageProperty))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.HttpResponseMessageProperty))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.HttpsTransportBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.HttpClientCredentialType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.HttpTransportSecurity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetHttpBinding))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetHttpsBinding))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetHttpMessageEncoding))]
// THE SOFTWARE.
//
-#if !MOBILE && !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.ConnectionOrientedTransportBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SslStreamSecurityBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.TcpConnectionPoolSettings))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetTcpBinding))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetTcpSecurity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.TcpTransportSecurity))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.TcpClientCredentialType))]
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System.ServiceModel System.Xml
+LIB_REFS = System System.ServiceModel System.Xml Facades/System.Security.Cryptography.X509Certificates
+
+ifneq (2.1, $(FRAMEWORK_VERSION))
+LIB_REFS += System.IdentityModel
+endif
+
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+X509ServiceCertificateAuthentication_mobile.cs
+X509CertificateValidator_mobile.cs
+X509CertificateValidationMode_mobile.cs
+X509CertificateRecipientClientCredential_mobile.cs
+X509CertificateInitiatorClientCredential_mobile.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageContractMemberAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageCredentialType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageHeader<>))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageHeaderAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageHeaderException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageParameterAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.OperationContext))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.UnknownMessageReceivedEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.XmlSerializerFormatAttribute))]
+#if !MOBILE && !XAMMAC_4_5
+
+// TODO: These are implemented as stubs in the facade directly on mobile (contrary to Desktop where they're forwarded to System.ServiceModel.dll/System.IdentityModel.dll).
+// I'm not 100% sure this is the right approach, but Marek thinks it's fine so I'm sticking with it for now.
+// The problem on mobile is that types like X509CertificateValidator live in System.IdentityModel.dll which is not built for mobile.
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IdentityModel.Selectors.X509CertificateValidator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509CertificateValidationMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509ServiceCertificateAuthentication))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509CertificateInitiatorClientCredential))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509CertificateRecipientClientCredential))]
+
+#endif
--- /dev/null
+//
+// X509CertificateInitiatorClientCredential_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.ServiceModel.Security
+{
+ public sealed class X509CertificateInitiatorClientCredential
+ {
+ [MonoTODO]
+ public X509Certificate2 Certificate
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ internal X509CertificateInitiatorClientCredential()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetCertificate(string subjectName, StoreLocation storeLocation, StoreName storeName)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509CertificateRecipientClientCredential_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.ServiceModel.Security
+{
+ public sealed class X509CertificateRecipientClientCredential
+ {
+ [MonoTODO]
+ public X509ServiceCertificateAuthentication Authentication
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509Certificate2 DefaultCertificate
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public Dictionary<Uri, X509Certificate2> ScopedCertificates
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509ServiceCertificateAuthentication SslCertificateAuthentication
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ internal X509CertificateRecipientClientCredential ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetDefaultCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetDefaultCertificate(string subjectName, StoreLocation storeLocation, StoreName storeName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetScopedCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue, Uri targetService)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetScopedCertificate(string subjectName, StoreLocation storeLocation, StoreName storeName, Uri targetService)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509CertificateValidationMode_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+namespace System.ServiceModel.Security
+{
+ public enum X509CertificateValidationMode
+ {
+ None,
+ PeerTrust,
+ ChainTrust,
+ PeerOrChainTrust,
+ Custom
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509CertificateValidator_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.IdentityModel.Selectors
+{
+ public abstract class X509CertificateValidator
+ {
+ public abstract void Validate (X509Certificate2 certificate);
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509ServiceCertificateAuthentication_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+using System.IdentityModel.Selectors;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.ServiceModel.Security
+{
+ public sealed class X509ServiceCertificateAuthentication
+ {
+ [MonoTODO]
+ public X509CertificateValidationMode CertificateValidationMode
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509CertificateValidator CustomCertificateValidator
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509RevocationMode RevocationMode
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public StoreLocation TrustedStoreLocation
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+ }
+}
+
+#endif
\ No newline at end of file
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SecurityBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SecurityHeaderLayout))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.TransportSecurityBindingElement))]
-#if !MOBILE
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DnsEndpointIdentity))]
-#if !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageSecurityVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.SpnEndpointIdentity))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.UpnEndpointIdentity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.BasicSecurityProfileVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.SecureConversationVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.SecurityPolicyVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.SecurityVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.TrustVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.SecureConversationSecurityTokenParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.SecurityTokenParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.SupportingTokenParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.UserNameSecurityTokenParameters))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.TrustVersion))]
-#endif
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.SpnEndpointIdentity))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.UpnEndpointIdentity))]
-#endif
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System System.ServiceProcess
+LIB_REFS = System
+
+ifneq (2.1, $(FRAMEWORK_VERSION))
+ifndef XAMMAC_4_5
+LIB_REFS += System.ServiceProcess
+endif
+endif
+
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
--- /dev/null
+//
+// ServiceControllerStatus_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ public enum ServiceControllerStatus
+ {
+ ContinuePending = 5,
+ Paused = 7,
+ PausePending = 6,
+ Running = 4,
+ StartPending = 2,
+ Stopped = 1,
+ StopPending = 3
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// ServiceController_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace System.ServiceProcess
+{
+ public class ServiceController : IDisposable
+ {
+ [MonoTODO]
+ public bool CanPauseAndContinue
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public bool CanShutdown
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public bool CanStop
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceController[] DependentServices
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public string DisplayName
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public string MachineName
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public SafeHandle ServiceHandle
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public string ServiceName
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceController[] ServicesDependedOn
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceType ServiceType
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceStartMode StartType
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceControllerStatus Status
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceController (string name)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public ServiceController (string name, string machineName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Continue ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Dispose ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual void Dispose (bool disposing)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetDevices ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetDevices (string machineName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetServices ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetServices (string machineName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Pause ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Refresh ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Start ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Start (string[] args)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Stop ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void WaitForStatus (ServiceControllerStatus desiredStatus)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void WaitForStatus (ServiceControllerStatus desiredStatus, TimeSpan timeout)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// ServiceStartMode_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ public enum ServiceStartMode
+ {
+ Automatic = 2,
+ Boot = 0,
+ Disabled = 4,
+ Manual = 3,
+ System = 1
+ }
+}
+
+#endif
--- /dev/null
+//
+// ServiceType_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ [Flags]
+ public enum ServiceType
+ {
+ Adapter = 4,
+ FileSystemDriver = 2,
+ InteractiveProcess = 256,
+ KernelDriver = 1,
+ RecognizerDriver = 8,
+ Win32OwnProcess = 16,
+ Win32ShareProcess = 32
+ }
+}
+
+#endif
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+ServiceController_mobile.cs
+ServiceControllerStatus_mobile.cs
+ServiceStartMode_mobile.cs
+ServiceType_mobile.cs
+TimeoutException_mobile.cs
--- /dev/null
+//
+// TimeoutException_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ public class TimeoutException : Exception
+ {
+ [MonoTODO]
+ public TimeoutException ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public TimeoutException (string message)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public TimeoutException (string message, Exception innerException)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
// THE SOFTWARE.
//
+#if !MOBILE && !XAMMAC_4_5
+
+// TODO: These are implemented as stubs in the facade directly on mobile
+
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceController))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceControllerStatus))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceStartMode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.TimeoutException))]
-
+#endif
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Text.Encoding.CodePages.dll")]
+[assembly: AssemblyDescription ("System.Text.Encoding.CodePages.dll")]
+[assembly: AssemblyDefaultAlias ("System.Text.Encoding.CodePages.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+namespace System.Text
+{
+ public sealed partial class CodePagesEncodingProvider
+ {
+ private CodePagesEncodingProvider ()
+ {
+ }
+
+ public static System.Text.EncodingProvider Instance {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Text.Encoding.CodePages
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Text.Encoding.CodePages.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+AssemblyInfo.cs
+CodePagesEncodingProvider.cs
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+ThreadingAclExtensions.cs
--- /dev/null
+//
+// ThreadingAclExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Security.AccessControl;
+using System.Diagnostics.Contracts;
+
+namespace System.Threading
+{
+ public static class ThreadingAclExtensions
+ {
+ [MonoTODO]
+ public static EventWaitHandleSecurity GetAccessControl (EventWaitHandle handle)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (EventWaitHandle handle, EventWaitHandleSecurity eventSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static MutexSecurity GetAccessControl (Mutex mutex)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (Mutex mutex, MutexSecurity mutexSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static SemaphoreSecurity GetAccessControl (Semaphore semaphore)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (Semaphore semaphore, SemaphoreSecurity semaphoreSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.SemaphoreRights))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.SemaphoreSecurity))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ThreadingAclExtensions))]
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System.Threading
+{
+ //
+ // Implementation of ThreadPoolBoundHandle that sits on top of the CLR's ThreadPool and Overlapped infrastructure
+ //
+
+ /// <summary>
+ /// Represents an I/O handle that is bound to the system thread pool and enables low-level
+ /// components to receive notifications for asynchronous I/O operations.
+ /// </summary>
+ public sealed partial class ThreadPoolBoundHandle : IDisposable
+ {
+ private readonly SafeHandle _handle;
+ private bool _isDisposed;
+
+ private ThreadPoolBoundHandle(SafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Gets the bound operating system handle.
+ /// </summary>
+ /// <value>
+ /// A <see cref="SafeHandle"/> object that holds the bound operating system handle.
+ /// </value>
+ public SafeHandle Handle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="ThreadPoolBoundHandle"/> for the specific handle,
+ /// which is bound to the system thread pool.
+ /// </summary>
+ /// <param name="handle">
+ /// A <see cref="SafeHandle"/> object that holds the operating system handle. The
+ /// handle must have been opened for overlapped I/O on the unmanaged side.
+ /// </param>
+ /// <returns>
+ /// <see cref="ThreadPoolBoundHandle"/> for <paramref name="handle"/>, which
+ /// is bound to the system thread pool.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="handle"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="handle"/> has been disposed.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> does not refer to a valid I/O handle.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> refers to a handle that has not been opened
+ /// for overlapped I/O.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> refers to a handle that has already been bound.
+ /// </exception>
+ /// <remarks>
+ /// This method should be called once per handle.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="ThreadPoolBoundHandle"/> does not take ownership of <paramref name="handle"/>,
+ /// it remains the responsibility of the caller to call <see cref="SafeHandle.Dispose"/>.
+ /// </remarks>
+ public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
+ {
+ if (handle == null)
+ throw new ArgumentNullException(nameof(handle));
+
+ if (handle.IsClosed || handle.IsInvalid)
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ try
+ {
+ // ThreadPool.BindHandle will always return true, otherwise, it throws. See the underlying FCall
+ // implementation in ThreadPoolNative::CorBindIoCompletionCallback to see the implementation.
+ bool succeeded = ThreadPool.BindHandle(handle);
+ Debug.Assert(succeeded);
+ }
+ catch (Exception ex)
+ { // BindHandle throws ApplicationException on full CLR and Exception on CoreCLR.
+ // We do not let either of these leak and convert them to ArgumentException to
+ // indicate that the specified handles are invalid.
+
+ if (ex.HResult == System.HResults.E_HANDLE) // Bad handle
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ if (ex.HResult == System.HResults.E_INVALIDARG) // Handle already bound or sync handle
+ throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, nameof(handle));
+
+ throw;
+ }
+
+ return new ThreadPoolBoundHandle(handle);
+ }
+
+ /// <summary>
+ /// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, specifying
+ /// a delegate that is invoked when the asynchronous I/O operation is complete, a user-provided
+ /// object providing context, and managed objects that serve as buffers.
+ /// </summary>
+ /// <param name="callback">
+ /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
+ /// invoked when the asynchronous I/O operation completes.
+ /// </param>
+ /// <param name="state">
+ /// A user-provided object that distinguishes this <see cref="NativeOverlapped"/> from other
+ /// <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
+ /// </param>
+ /// <param name="pinData">
+ /// An object or array of objects representing the input or output buffer for the operation. Each
+ /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
+ /// </param>
+ /// <returns>
+ /// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The unmanaged pointer returned by this method can be passed to the operating system in
+ /// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
+ /// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
+ /// </para>
+ /// <para>
+ /// The buffer or buffers specified in <paramref name="pinData"/> must be the same as those passed
+ /// to the unmanaged operating system function that performs the asynchronous I/O.
+ /// </para>
+ /// <note>
+ /// The buffers specified in <paramref name="pinData"/> are pinned for the duration of
+ /// the I/O operation.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="callback"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ EnsureNotDisposed();
+
+ ThreadPoolBoundHandleOverlapped overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, preAllocated: null);
+ overlapped._boundHandle = this;
+ return overlapped._nativeOverlapped;
+ }
+
+ /// <summary>
+ /// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, using the callback,
+ /// state, and buffers associated with the specified <see cref="PreAllocatedOverlapped"/> object.
+ /// </summary>
+ /// <param name="preAllocated">
+ /// A <see cref="PreAllocatedOverlapped"/> object from which to create the NativeOverlapped pointer.
+ /// </param>
+ /// <returns>
+ /// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The unmanaged pointer returned by this method can be passed to the operating system in
+ /// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
+ /// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="preAllocated"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="preAllocated"/> is currently in use for another I/O operation.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed, or
+ /// this method was called after <paramref name="preAllocated"/> was disposed.
+ /// </exception>
+ /// <seealso cref="PreAllocatedOverlapped"/>
+ public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated)
+ {
+ if (preAllocated == null)
+ throw new ArgumentNullException(nameof(preAllocated));
+
+ EnsureNotDisposed();
+
+ preAllocated.AddRef();
+ try
+ {
+ ThreadPoolBoundHandleOverlapped overlapped = preAllocated._overlapped;
+
+ if (overlapped._boundHandle != null)
+ throw new ArgumentException(SR.Argument_PreAllocatedAlreadyAllocated, nameof(preAllocated));
+
+ overlapped._boundHandle = this;
+
+ return overlapped._nativeOverlapped;
+ }
+ catch
+ {
+ preAllocated.Release();
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Frees the unmanaged memory associated with a <see cref="NativeOverlapped"/> structure
+ /// allocated by the <see cref="AllocateNativeOverlapped"/> method.
+ /// </summary>
+ /// <param name="overlapped">
+ /// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure to be freed.
+ /// </param>
+ /// <remarks>
+ /// <note type="caution">
+ /// You must call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method exactly once
+ /// on every <see cref="NativeOverlapped"/> unmanaged pointer allocated using the
+ /// <see cref="AllocateNativeOverlapped"/> method.
+ /// If you do not call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method, you will
+ /// leak memory. If you call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method more
+ /// than once on the same <see cref="NativeOverlapped"/> unmanaged pointer, memory will be corrupted.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="overlapped"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped)
+ {
+ if (overlapped == null)
+ throw new ArgumentNullException(nameof(overlapped));
+
+ // Note: we explicitly allow FreeNativeOverlapped calls after the ThreadPoolBoundHandle has been Disposed.
+
+ ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, this);
+
+ if (wrapper._boundHandle != this)
+ throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped));
+
+ if (wrapper._preAllocated != null)
+ wrapper._preAllocated.Release();
+ else
+ Overlapped.Free(overlapped);
+ }
+
+ /// <summary>
+ /// Returns the user-provided object specified when the <see cref="NativeOverlapped"/> instance was
+ /// allocated using the <see cref="AllocateNativeOverlapped(IOCompletionCallback, object, byte[])"/>.
+ /// </summary>
+ /// <param name="overlapped">
+ /// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure from which to return the
+ /// asscociated user-provided object.
+ /// </param>
+ /// <returns>
+ /// A user-provided object that distinguishes this <see cref="NativeOverlapped"/>
+ /// from other <see cref="NativeOverlapped"/> instances, otherwise, <see langword="null"/> if one was
+ /// not specified when the instance was allocated using <see cref="AllocateNativeOverlapped"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="overlapped"/> is <see langword="null"/>.
+ /// </exception>
+ public unsafe static object GetNativeOverlappedState(NativeOverlapped* overlapped)
+ {
+ if (overlapped == null)
+ throw new ArgumentNullException(nameof(overlapped));
+
+ ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, null);
+ Debug.Assert(wrapper._boundHandle != null);
+ return wrapper._userState;
+ }
+
+ private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
+ {
+ ThreadPoolBoundHandleOverlapped wrapper;
+ try
+ {
+ wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
+ }
+ catch (NullReferenceException ex)
+ {
+ throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped), ex);
+ }
+
+ return wrapper;
+ }
+
+ public void Dispose()
+ {
+ // .NET Native's version of ThreadPoolBoundHandle that wraps the Win32 ThreadPool holds onto
+ // native resources so it needs to be disposable. To match the contract, we are also disposable.
+ // We also implement a disposable state to mimic behavior between this implementation and
+ // .NET Native's version (code written against us, will also work against .NET Native's version).
+ _isDisposed = true;
+ }
+
+
+ private void EnsureNotDisposed()
+ {
+ if (_isDisposed)
+ throw new ObjectDisposedException(GetType().ToString());
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Overlapped subclass adding data needed by ThreadPoolBoundHandle.
+ /// </summary>
+ internal sealed class ThreadPoolBoundHandleOverlapped : Overlapped
+ {
+ private readonly IOCompletionCallback _userCallback;
+ internal readonly object _userState;
+ internal PreAllocatedOverlapped _preAllocated;
+ internal unsafe NativeOverlapped* _nativeOverlapped;
+ internal ThreadPoolBoundHandle _boundHandle;
+ internal bool _completed;
+
+ public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
+ {
+ _userCallback = callback;
+ _userState = state;
+ _preAllocated = preAllocated;
+
+ _nativeOverlapped = Pack(CompletionCallback, pinData);
+ _nativeOverlapped->OffsetLow = 0; // CLR reuses NativeOverlapped instances and does not reset these
+ _nativeOverlapped->OffsetHigh = 0;
+ }
+
+ private unsafe static void CompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
+ {
+ ThreadPoolBoundHandleOverlapped overlapped = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(nativeOverlapped);
+
+ //
+ // The Win32 thread pool implementation of ThreadPoolBoundHandle does not permit reuse of NativeOverlapped
+ // pointers without freeing them and allocating new a new one. We need to ensure that code using the CLR
+ // ThreadPool implementation follows those rules.
+ //
+ if (overlapped._completed)
+ throw new InvalidOperationException(SR.InvalidOperation_NativeOverlappedReused);
+
+ overlapped._completed = true;
+
+ if (overlapped._boundHandle == null)
+ throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree);
+
+ overlapped._userCallback(errorCode, numBytes, nativeOverlapped);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Represents pre-allocated state for native overlapped I/O operations.
+ /// </summary>
+ /// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
+ public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
+ {
+ internal readonly ThreadPoolBoundHandleOverlapped _overlapped;
+ private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PreAllocatedOverlapped"/> class, specifying
+ /// a delegate that is invoked when each asynchronous I/O operation is complete, a user-provided
+ /// object providing context, and managed objects that serve as buffers.
+ /// </summary>
+ /// <param name="callback">
+ /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
+ /// invoked when each asynchronous I/O operation completes.
+ /// </param>
+ /// <param name="state">
+ /// A user-provided object that distinguishes <see cref="NativeOverlapped"/> instance produced from this
+ /// object from other <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
+ /// </param>
+ /// <param name="pinData">
+ /// An object or array of objects representing the input or output buffer for the operations. Each
+ /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
+ /// </param>
+ /// <remarks>
+ /// The new <see cref="PreAllocatedOverlapped"/> instance can be passed to
+ /// <see cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>, to produce
+ /// a <see cref="NativeOverlapped"/> instance that can be passed to the operating system in overlapped
+ /// I/O operations. A single <see cref="PreAllocatedOverlapped"/> instance can only be used for
+ /// a single native I/O operation at a time. However, the state stored in the <see cref="PreAllocatedOverlapped"/>
+ /// instance can be reused for subsequent native operations.
+ /// <note>
+ /// The buffers specified in <paramref name="pinData"/> are pinned until <see cref="Dispose"/> is called.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="callback"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ _overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, this);
+ }
+
+ internal bool AddRef()
+ {
+ return _lifetime.AddRef(this);
+ }
+
+ internal void Release()
+ {
+ _lifetime.Release(this);
+ }
+
+ /// <summary>
+ /// Frees the resources associated with this <see cref="PreAllocatedOverlapped"/> instance.
+ /// </summary>
+ public unsafe void Dispose()
+ {
+ _lifetime.Dispose(this);
+ GC.SuppressFinalize(this);
+ }
+
+ ~PreAllocatedOverlapped()
+ {
+ //
+ // During shutdown, don't automatically clean up, because this instance may still be
+ // reachable/usable by other code.
+ //
+ if (!Environment.HasShutdownStarted)
+ Dispose();
+ }
+
+ unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
+ {
+ if (_overlapped != null)
+ {
+ if (disposed)
+ {
+ Overlapped.Free(_overlapped._nativeOverlapped);
+ }
+ else
+ {
+ _overlapped._boundHandle = null;
+ _overlapped._completed = false;
+ *_overlapped._nativeOverlapped = default(NativeOverlapped);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Provides callbacks to objects whose lifetime is managed by <see cref="DeferredDisposableLifetime{T}"/>.
+ /// </summary>
+ internal interface IDeferredDisposable
+ {
+ /// <summary>
+ /// Called when the object's refcount reaches zero.
+ /// </summary>
+ /// <param name="disposed">
+ /// Indicates whether the object has been disposed.
+ /// </param>
+ /// <remarks>
+ /// If the refount reaches zero before the object is disposed, this method will be called with
+ /// <paramref name="disposed"/> set to false. If the object is then disposed, this method will be
+ /// called again, with <paramref name="disposed"/> set to true. If the refcount reaches zero
+ /// after the object has already been disposed, this will be called a single time, with
+ /// <paramref name="disposed"/> set to true.
+ /// </remarks>
+ void OnFinalRelease(bool disposed);
+ }
+
+ /// <summary>
+ /// Manages the lifetime of an object which implements IDisposable, but which must defer the actual
+ /// cleanup of state until all existing uses of the object are complete.
+ /// </summary>
+ /// <typeparam name="T">The type of object whose lifetime will be managed.</typeparam>
+ /// <remarks>
+ /// This type maintains a reference count, and tracks whether the object has been disposed. When
+ /// Callbacks are made to <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when the refcount
+ /// reaches zero. Objects that need to defer cleanup until they have been disposed *and* they have
+ /// no more references can do so in <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when
+ /// 'disposed' is true.
+ /// </remarks>
+ internal struct DeferredDisposableLifetime<T> where T : class, IDeferredDisposable
+ {
+ //
+ // _count is positive until Dispose is called, after which it's (-1 - refcount).
+ //
+ private int _count;
+
+ public bool AddRef(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+
+ // Have we been disposed?
+ if (oldCount < 0)
+ throw new ObjectDisposedException(typeof(T).ToString());
+
+ int newCount = checked(oldCount + 1);
+
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ return true;
+ }
+ }
+
+ public void Release(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+ if (oldCount > 0)
+ {
+ // We haven't been disposed. Decrement _count.
+ int newCount = oldCount - 1;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == 0)
+ obj.OnFinalRelease(disposed: false);
+ return;
+ }
+ }
+ else
+ {
+ Debug.Assert(oldCount != 0 && oldCount != -1);
+
+ // We've been disposed. Increment _count.
+ int newCount = oldCount + 1;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == -1)
+ obj.OnFinalRelease(disposed: true);
+ return;
+ }
+ }
+ }
+ }
+
+ public void Dispose(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+ if (oldCount < 0)
+ return; // already disposed
+
+ int newCount = -1 - oldCount;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == -1)
+ obj.OnFinalRelease(disposed: true);
+ return;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// HResults.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System
+{
+ internal static class HResults
+ {
+ internal const int E_HANDLE = unchecked((int)0x80070006);
+ internal const int E_INVALIDARG = unchecked((int)0x80070057);
+ }
+}
\ No newline at end of file
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS)
+LIB_MCS_FLAGS = $(SIGN_FLAGS) -unsafe
PLATFORM_DEBUG_FLAGS =
--- /dev/null
+// strings taken from corefx
+
+class SR
+{
+ public const string Argument_AlreadyBoundOrSyncHandle = "'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.";
+ public const string Argument_InvalidHandle = "'handle' has been disposed or is an invalid handle.";
+ public const string Argument_NativeOverlappedAlreadyFree = "'overlapped' has already been freed.";
+ public const string Argument_NativeOverlappedWrongBoundHandle = "'overlapped' was not allocated by this ThreadPoolBoundHandle instance.";
+ public const string Argument_PreAllocatedAlreadyAllocated = "'preAllocated' is already in use.";
+ public const string InvalidOperation_NativeOverlappedReused = "NativeOverlapped cannot be reused for multiple operations.";
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+ClrThreadPoolBoundHandle.cs
+ClrThreadPoolBoundHandleOverlapped.cs
+ClrThreadPoolPreAllocatedOverlapped.cs
+DeferredDisposableLifetime.cs
+SR.cs
+HResults.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.IOCompletionCallback))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.NativeOverlapped))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.PreAllocatedOverlapped))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ThreadPoolBoundHandle))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.Serialization.IXmlSerializable))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XmlDateTimeSerializationMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.Serialization.XmlSchemaProviderAttribute))]
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System System.Xml.Linq
+LIB_REFS = System System.Xml System.Xml.Linq
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
TypeForwarders.cs
AssemblyInfo.cs
-
+XDocumentExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XPath.Extensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XPath.XDocumentExtensions))]
--- /dev/null
+
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml.Linq;
+
+namespace System.Xml.XPath
+{
+ public static class XDocumentExtensions
+ {
+ private class XDocumentNavigable : IXPathNavigable
+ {
+ private XNode _node;
+ public XDocumentNavigable(XNode n)
+ {
+ _node = n;
+ }
+ public XPathNavigator CreateNavigator()
+ {
+ return _node.CreateNavigator();
+ }
+ }
+ public static IXPathNavigable ToXPathNavigable(this XNode node)
+ {
+ return new XDocumentNavigable(node);
+ }
+ }
+}
\ No newline at end of file
# Caution while renaming SUBDIRS variables as those are used outside mono repository.
# ie: macccore/builds/Makefile
-monotouch_PARALLEL_SUBDIRS = System.Collections.Concurrent System.Collections System.ComponentModel.Annotations System.ComponentModel.EventBasedAsync System.ComponentModel \
+common_SUBDIRS = System.Collections.Concurrent System.Collections System.ComponentModel.Annotations System.ComponentModel.EventBasedAsync System.ComponentModel \
System.Diagnostics.Contracts System.Diagnostics.Debug System.Diagnostics.Tracing System.Diagnostics.Tools System.Dynamic.Runtime System.Globalization System.IO System.Linq.Expressions \
System.Linq.Parallel System.Linq.Queryable System.Linq System.Net.NetworkInformation System.Net.Primitives System.Net.Requests System.ObjectModel \
System.Reflection.Extensions System.Reflection.Primitives System.Reflection System.Resources.ResourceManager System.Runtime.Extensions \
System.Runtime.InteropServices System.Runtime.InteropServices.WindowsRuntime System.Runtime.Numerics System.Runtime.Serialization.Json \
-System.Runtime.Serialization.Primitives System.Runtime.Serialization.Xml System.Runtime System.Security.Principal System.ServiceModel.Http \
-System.ServiceModel.Primitives System.ServiceModel.Security System.Text.Encoding.Extensions System.Text.Encoding System.Text.RegularExpressions System.Threading.Tasks.Parallel \
+System.Runtime System.Security.Principal System.ServiceModel.Http \
+System.ServiceModel.Security System.Text.Encoding.Extensions System.Text.Encoding System.Text.RegularExpressions System.Threading.Tasks.Parallel \
System.Threading.Tasks System.Threading.Timer System.Threading System.Xml.ReaderWriter System.Xml.XDocument System.Xml.XmlSerializer \
System.Runtime.Handles System.ServiceModel.Duplex System.ServiceModel.NetTcp \
Microsoft.Win32.Primitives Microsoft.Win32.Registry System.AppContext System.Collections.NonGeneric System.Collections.Specialized System.ComponentModel.Primitives \
System.Security.AccessControl System.Security.Claims System.Security.Cryptography.DeriveBytes System.Security.Cryptography.Encoding System.Security.Cryptography.Encryption \
System.Security.Cryptography.Encryption.Aes System.Security.Cryptography.Encryption.ECDiffieHellman System.Security.Cryptography.Encryption.ECDsa System.Security.Cryptography.Hashing \
System.Security.Cryptography.Hashing.Algorithms System.Security.Cryptography.RSA System.Security.Cryptography.RandomNumberGenerator \
-System.Security.Cryptography.X509Certificates System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
+System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
System.Xml.XPath System.Xml.XmlDocument System.Xml.Xsl.Primitives Microsoft.Win32.Registry.AccessControl System.Diagnostics.StackTrace System.Globalization.Extensions \
System.IO.FileSystem.AccessControl System.Private.CoreLib.InteropServices System.Private.CoreLib.Threading System.Reflection.TypeExtensions \
System.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)
Mono.Security \
System \
System.Core \
+ System.Security \
System.XML \
I18N \
System.ServiceModel.Internals \
Mono.Data.Tds \
System.Transactions \
System.Numerics \
+ System.Numerics.Vectors \
System.Data \
Mono.Cairo \
Mono.Data.Sqlite \
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) \
System \
Mono.Posix \
System.Core \
+ System.Security \
System.XML \
I18N \
System.ServiceModel.Internals \
Mono.CompilerServices.SymbolWriter \
System.Data.Linq \
System.Net.Http \
+ System.Net.Http.WebRequest \
Mono.Security.Providers.DotNet \
Mono.Security.Providers.OldTls \
Mono.Security.Providers.NewSystemSource \
Mono.Security.Providers.NewTls \
System.Runtime.InteropServices.RuntimeInformation \
+ System.Reflection.Context \
+ System.Net.Http.WinHttpHandler \
$(pcl_facade_dirs)
net_4_x_dirs := \
System.Workflow.Activities \
System.Workflow.ComponentModel \
System.Workflow.Runtime \
+ System.Reflection.Context \
$(pcl_facade_dirs)
xbuild_2_0_dirs := \
include ../../build/rules.make
LIBRARY = Mono.Tasklets.dll
-NO_TEST = yes
+
+LIB_MCS_FLAGS =
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
include ../../build/library.make
--- /dev/null
+Mono.Tasklets/ContinuationsTest.cs
--- /dev/null
+using NUnit.Framework;
+
+using System;
+using Mono.Tasklets;
+
+namespace MonoTests.System
+{
+ [TestFixture]
+ public class ContinuationsTest {
+
+ 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:
--- /dev/null
+//
+// SafeNCryptHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public abstract class SafeNCryptHandle : System.Runtime.InteropServices.SafeHandle
+ {
+ protected SafeNCryptHandle ()
+ : base (IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid { get { throw new NotImplementedException (); } }
+
+ protected override bool ReleaseHandle ()
+ {
+ return false;
+ }
+
+ protected abstract bool ReleaseNativeHandle();
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeNCryptKeyHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeNCryptKeyHandle : SafeNCryptHandle
+ {
+ public SafeNCryptKeyHandle ()
+ {
+ }
+
+ protected override bool ReleaseNativeHandle ()
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeNCryptProviderHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeNCryptProviderHandle : SafeNCryptHandle
+ {
+ public SafeNCryptProviderHandle ()
+ {
+ }
+
+ protected override bool ReleaseNativeHandle ()
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeNCryptSecretHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeNCryptSecretHandle : SafeNCryptHandle
+ {
+ public SafeNCryptSecretHandle ()
+ {
+ }
+
+ protected override bool ReleaseNativeHandle ()
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
{
}
- public AnonymousPipeClientStream (PipeDirection direction,SafePipeHandle safePipeHandle)
+ public AnonymousPipeClientStream (PipeDirection direction, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
/*
impl = new UnixAnonymousPipeClient (this, safePipeHandle);
*/
+#if MOBILE
+ throw new NotImplementedException ();
+#else
InitializeHandle (safePipeHandle, false, false);
+#endif
IsConnected = true;
}
}
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize)
+#if MOBILE
+ : base (direction, bufferSize)
+ {
+ throw new NotImplementedException ();
+ }
+#else
: this (direction, inheritability, bufferSize, null)
{
}
+#endif
+#if !MOBILE
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity)
: base (direction, bufferSize)
{
InitializeHandle (impl.Handle, false, false);
IsConnected = true;
}
+#endif
[MonoTODO]
public AnonymousPipeServerStream (PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle)
if (direction == PipeDirection.InOut)
throw new NotSupportedException ("Anonymous pipe direction can only be either in or out.");
+#if MOBILE
+ throw new NotImplementedException ();
+#else
if (IsWindows)
impl = new Win32AnonymousPipeServer (this, serverSafePipeHandle, clientSafePipeHandle);
else
IsConnected = true;
ClientSafePipeHandle = clientSafePipeHandle;
+#endif
+ }
+
+ ~AnonymousPipeServerStream ()
+ {
+ // To be compatible with .net
}
IAnonymousPipeServer impl;
}
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
+#if MOBILE
+ : base (direction, DefaultBufferSize)
+ {
+ throw new NotImplementedException ();
+ }
+#else
: this (serverName, pipeName, ToAccessRights (direction), options, impersonationLevel, inheritability)
{
}
+#endif
public NamedPipeClientStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
if (IsWindows)
impl = new Win32NamedPipeClient (this, safePipeHandle);
else
impl = new UnixNamedPipeClient (this, safePipeHandle);
IsConnected = isConnected;
InitializeHandle (safePipeHandle, true, isAsync);
+#endif
}
+#if !MOBILE
public NamedPipeClientStream (string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
: base (ToDirection (desiredAccessRights), DefaultBufferSize)
{
else
impl = new UnixNamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability);
}
+#endif
INamedPipeClient impl;
public void Connect ()
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
impl.Connect ();
InitializeHandle (impl.Handle, false, impl.IsAsync);
IsConnected = true;
+#endif
}
public void Connect (int timeout)
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
impl.Connect (timeout);
InitializeHandle (impl.Handle, false, impl.IsAsync);
IsConnected = true;
+#endif
}
public int NumberOfServerInstances {
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize)
+#if MOBILE
+ : base (direction, inBufferSize)
+ {
+ throw new NotImplementedException ();
+ }
+#else
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, null)
{
}
+#endif
+#if !MOBILE
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, HandleInheritability.None)
{
InitializeHandle (impl.Handle, false, (options & PipeOptions.Asynchronous) != PipeOptions.None);
}
+#endif
public NamedPipeServerStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
if (IsWindows)
impl = new Win32NamedPipeServer (this, safePipeHandle);
else
impl = new UnixNamedPipeServer (this, safePipeHandle);
IsConnected = isConnected;
InitializeHandle (safePipeHandle, true, isAsync);
+#endif
+ }
+
+ ~NamedPipeServerStream ()
+ {
+ // To be compatible with .net
}
INamedPipeServer impl;
impl.Disconnect ();
}
+#if !MOBILE
[MonoTODO]
[SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
public void RunAsClient (PipeStreamImpersonationWorker impersonationWorker)
{
throw new NotImplementedException ();
}
+#endif
public void WaitForConnection ()
{
throw new NotImplementedException ();
}
+#if !MOBILE
// async operations
Action wait_connect_delegate;
{
wait_connect_delegate.EndInvoke (asyncResult);
}
+#endif
}
}
// FIXME: not precise.
internal const int DefaultBufferSize = 0x400;
+#if !MOBILE
internal static bool IsWindows {
get { return Win32Marshal.IsWindows; }
}
+#endif
internal Exception ThrowACLException ()
{
return new NotImplementedException ("ACL is not supported in Mono");
}
+#if !MOBILE
internal static PipeAccessRights ToAccessRights (PipeDirection direction)
{
switch (direction) {
throw new ArgumentOutOfRangeException ();
}
}
+#endif
protected PipeStream (PipeDirection direction, int bufferSize)
: this (direction, PipeTransmissionMode.Byte, bufferSize)
set { stream = value; }
}
+#if !MOBILE
protected bool IsHandleExposed { get; private set; }
+#endif
[MonoTODO]
public bool IsMessageComplete { get; private set; }
}
// initialize/dispose/state check
+#if MOBILE
+ internal static void CheckPipePropertyOperations ()
+ {
+ }
+ static void CheckReadOperations ()
+ {
+ }
+
+ static void CheckWriteOperations ()
+ {
+ }
+#else
[MonoTODO]
protected internal virtual void CheckPipePropertyOperations ()
{
this.IsHandleExposed = isExposed;
this.IsAsync = isAsync;
}
+#endif
protected override void Dispose (bool disposing)
{
throw new NotSupportedException ();
}
+#if !MOBILE
public PipeSecurity GetAccessControl ()
{
return new PipeSecurity (SafePipeHandle,
public void WaitForPipeDrain ()
{
}
+#endif
[MonoTODO]
public override int Read ([In] byte [] buffer, int offset, int count)
// async
+#if !MOBILE
Func<byte [],int,int,int> read_delegate;
[HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
{
write_delegate.EndInvoke (asyncResult);
}
+#endif
}
}
--- /dev/null
+//
+// AesCng.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class AesCng : Aes
+ {
+ public AesCng ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AesCng (string keyName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AesCng (string keyName, CngProvider provider)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AesCng (string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Byte[] Key {
+ get {
+ throw new NotImplementedException ();
+ } set {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public override int KeySize {
+ get {
+ throw new NotImplementedException ();
+ }
+
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+ public override ICryptoTransform CreateDecryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateDecryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ return default(System.Security.Cryptography.ICryptoTransform);
+ }
+
+ protected override void Dispose (bool disposing) {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateIV ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateKey ()
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// TripleDESCng.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class TripleDESCng : TripleDES
+ {
+ public TripleDESCng ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TripleDESCng (string keyName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TripleDESCng (string keyName, CngProvider provider)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TripleDESCng (string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Byte[] Key {
+ get {
+ throw new NotImplementedException ();
+ } set {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public override int KeySize {
+ get {
+ throw new NotImplementedException ();
+ }
+
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+ public override ICryptoTransform CreateDecryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateDecryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ return default(System.Security.Cryptography.ICryptoTransform);
+ }
+
+ protected override void Dispose (bool disposing) {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateIV ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateKey ()
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
System.IO.MemoryMappedFiles/MemoryMappedView.cs
Microsoft.Win32.SafeHandles/SafeMemoryMappedFileHandle.cs
Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs
+System.Security.Cryptography/AesCng.cs
+System.Security.Cryptography/TripleDESCng.cs
System.Security.Cryptography.X509Certificates/ECDsaCertificateExtensions.cs
System.Security.Cryptography.X509Certificates/RSACertificateExtensions.cs
+Microsoft.Win32.SafeHandles/SafeNCryptHandle.cs
+Microsoft.Win32.SafeHandles/SafeNCryptKeyHandle.cs
+Microsoft.Win32.SafeHandles/SafeNCryptProviderHandle.cs
+Microsoft.Win32.SafeHandles/SafeNCryptSecretHandle.cs
+Microsoft.Win32.SafeHandles/SafePipeHandle.cs
+
+System.IO.Pipes/AnonymousPipeClientStream.cs
+System.IO.Pipes/AnonymousPipeServerStream.cs
+System.IO.Pipes/NamedPipeClientStream.cs
+System.IO.Pipes/NamedPipeServerStream.cs
+System.IO.Pipes/PipeDirection.cs
+System.IO.Pipes/PipeInterfaces.cs
+System.IO.Pipes/PipeOptions.cs
+System.IO.Pipes/PipeStream.cs
+System.IO.Pipes/PipeTransmissionMode.cs
ReferenceSources/SR.cs
ReferenceSources/SR.missing.cs
../referencesource/System.Core/System/Runtime/CompilerServices/ExecutionScope.cs
../referencesource/System.Core/System/Security/Cryptography/Aes.cs
+../referencesource/System.Core/System/Security/Cryptography/BCryptNative.cs
+../referencesource/System.Core/System/Security/Cryptography/CngAlgorithm.cs
+../referencesource/System.Core/System/Security/Cryptography/CngAlgorithmGroup.cs
+../referencesource/System.Core/System/Security/Cryptography/CngKey.cs
../referencesource/System.Core/System/Security/Cryptography/CngKeyBlobFormat.cs
+../referencesource/System.Core/System/Security/Cryptography/CngKeyCreationParameters.cs
+../referencesource/System.Core/System/Security/Cryptography/CngProperty.cs
+../referencesource/System.Core/System/Security/Cryptography/CngProvider.cs
+../referencesource/System.Core/System/Security/Cryptography/CngUIPolicy.cs
../referencesource/System.Core/System/Security/Cryptography/ECDiffieHellmanPublicKey.cs
../referencesource/System.Core/System/Security/Cryptography/ECDsa.cs
+../referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs
+../referencesource/System.Core/System/Security/Cryptography/NCryptNative.cs
+../referencesource/System.Core/System/Security/Cryptography/RsaCng.cs
../referencesource/System.Core/System/threading/ReaderWriterLockSlim/ReaderWriterLockSlim.cs
System.Security.Cryptography/AesCryptoServiceProvider.cs
System.Security.Cryptography/AesTransform.cs
-System.Security.Cryptography/CngAlgorithm.cs
-System.Security.Cryptography/CngAlgorithmGroup.cs
System.Security.Cryptography/MD5Cng.cs
System.Security.Cryptography/SHA1Cng.cs
System.Security.Cryptography/SHA256Cng.cs
#include common_System.Core.dll.sources
#include dynamic_System.Core.dll.sources
-Microsoft.Win32.SafeHandles/SafePipeHandle.cs
-
-System.IO.Pipes/AnonymousPipeClientStream.cs
-System.IO.Pipes/AnonymousPipeServerStream.cs
-System.IO.Pipes/NamedPipeClientStream.cs
-System.IO.Pipes/NamedPipeServerStream.cs
System.IO.Pipes/PipeAccessRights.cs
System.IO.Pipes/PipeAccessRule.cs
System.IO.Pipes/PipeAuditRule.cs
-System.IO.Pipes/PipeDirection.cs
-System.IO.Pipes/PipeInterfaces.cs
-System.IO.Pipes/PipeOptions.cs
System.IO.Pipes/PipeSecurity.cs
-System.IO.Pipes/PipeStream.cs
System.IO.Pipes/PipeStreamImpersonationWorker.cs
-System.IO.Pipes/PipeTransmissionMode.cs
System.IO.Pipes/PipeUnix.cs
System.IO.Pipes/PipeWin32.cs
System.Security.Cryptography/AesCryptoServiceProvider.cs
System.Security.Cryptography/AesTransform.cs
-System.Security.Cryptography/CngAlgorithm.cs
-System.Security.Cryptography/CngAlgorithmGroup.cs
System.Security.Cryptography/MD5Cng.cs
System.Security.Cryptography/SHA1Cng.cs
System.Security.Cryptography/SHA256Cng.cs
{
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 ();
}
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 ();
}
throw new NotImplementedException ();
}
- public bool IsDBNull (int i)
+ public bool IsDBNull (int ordinal)
{
throw new NotImplementedException ();
}
}
}
- 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 ();
}
LIBRARY = System.Drawing.dll
LIB_REFS = System
-LIB_MCS_FLAGS = /unsafe \
+LIB_MCS_FLAGS = /unsafe -d:FEATURE_TYPECONVERTER \
-resource:Assembly/Mono.ico,Mono.ico -resource:Assembly/Information.ico,Information.ico \
-resource:Assembly/Error.ico,Error.ico -resource:Assembly/Warning.ico,Warning.ico \
-resource:Assembly/Question.ico,Question.ico -resource:Assembly/Shield.ico,Shield.ico
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (PointConverter))]
#endif
public struct Point
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (RectangleConverter))]
#endif
public struct Rectangle
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (SizeConverter))]
#endif
public struct Size
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (SizeFConverter))]
#endif
public struct SizeF
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Net.Http.WinHttpHandler.dll")]
+[assembly: AssemblyDescription ("System.Net.Http.WinHttpHandler.dll")]
+[assembly: AssemblyDefaultAlias ("System.Net.Http.WinHttpHandler.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Net.Http.WinHttpHandler
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Net.Http.WinHttpHandler.dll
+LIB_REFS = System System.Net.Http
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+
+System.Net.Http/CookieUsePolicy.cs
+System.Net.Http/WindowsProxyUsePolicy.cs
+System.Net.Http/WinHttpHandler.cs
--- /dev/null
+//
+// CookieUsePolicy.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Http
+{
+ public enum CookieUsePolicy
+ {
+ IgnoreCookies = 0,
+ UseInternalCookieStoreOnly = 1,
+ UseSpecifiedCookieContainer = 2,
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// WinHttpHandler.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Net.Security;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.Net.Http
+{
+ public class WinHttpHandler : HttpMessageHandler
+ {
+ public WinHttpHandler() { throw new PlatformNotSupportedException (); }
+
+ public DecompressionMethods AutomaticDecompression { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public bool AutomaticRedirection { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public bool CheckCertificateRevocationList { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public ClientCertificateOption ClientCertificateOption { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public X509Certificate2Collection ClientCertificates { get { throw new PlatformNotSupportedException (); } }
+
+ public CookieContainer CookieContainer { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public CookieUsePolicy CookieUsePolicy { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public ICredentials DefaultProxyCredentials { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxAutomaticRedirections { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxConnectionsPerServer { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxResponseDrainSize { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxResponseHeadersLength { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public bool PreAuthenticate { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public IDictionary<string, object> Properties { get { throw new PlatformNotSupportedException (); } }
+
+ public IWebProxy Proxy { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public TimeSpan ReceiveDataTimeout { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public TimeSpan ReceiveHeadersTimeout { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public TimeSpan SendTimeout { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> ServerCertificateValidationCallback { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public ICredentials ServerCredentials { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public SslProtocols SslProtocols { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public WindowsProxyUsePolicy WindowsProxyUsePolicy { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ protected override void Dispose (bool disposing) { throw new PlatformNotSupportedException (); }
+
+ protected override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, Threading.CancellationToken cancellationToken) { throw new PlatformNotSupportedException (); }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// WindowsProxyUsePolicy.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Http
+{
+ public enum WindowsProxyUsePolicy
+ {
+ DoNotUseProxy = 0,
+ UseCustomProxy = 3,
+ UseWinHttpProxy = 1,
+ UseWinInetProxy = 2,
+ }
+}
\ No newline at end of file
LIBRARY = System.Numerics.Vectors.dll
LIB_REFS = System System.Numerics
-LIB_MCS_FLAGS =
+LIB_MCS_FLAGS = -unsafe
EXTRA_DISTFILES =
--- /dev/null
+// generated from Strings.resx in corefx
+
+partial class SR
+{
+ public const string Arg_ArgumentOutOfRangeException="Index was out of bounds:";
+ public const string Arg_ElementsInSourceIsGreaterThanDestination="Number of elements in source vector is greater than the destination array";
+ public const string Arg_MultiDimArrayNotSupported="Only one-dimensional arrays are supported";
+ public const string Arg_NullArgumentNullRef="The method was called with a null array argument.";
+ public const string Arg_RegisterLengthOfRangeException="length must be less than";
+ public const string Arg_TypeNotSupported="Specified type is not supported";
+ public const string Reflection_MethodNotSupported="Vector<T>.Count cannot be called via reflection when intrinsics are enabled.";
+
+ public static string Format (string message, object data)
+ {
+ return string.Format (message, data);
+ }
+}
../../build/common/SR.cs
Assembly/AssemblyInfo.cs
Assembly/TypeForwarders.cs
+SR.cs
+System.Numerics/ConstantHelper.cs
+System.Numerics/HashCodeHelper.cs
+System.Numerics/JitIntrinsicAttribute.cs
+System.Numerics/Register.cs
+System.Numerics/Vector_Operations.cs
+System.Numerics/Vector.cs
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.CompilerServices;
+
+namespace System.Numerics
+{
+ internal class ConstantHelper
+ {
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Byte GetByteWithAllBitsSet()
+ {
+ Byte value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Byte*)&value) = (Byte)0xff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static SByte GetSByteWithAllBitsSet()
+ {
+ SByte value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((SByte*)&value) = (SByte)0xff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static UInt16 GetUInt16WithAllBitsSet()
+ {
+ UInt16 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((UInt16*)&value) = (UInt16)0xffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Int16 GetInt16WithAllBitsSet()
+ {
+ Int16 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int16*)&value) = (Int16)0xffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static UInt32 GetUInt32WithAllBitsSet()
+ {
+ UInt32 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((UInt32*)&value) = (UInt32)0xffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Int32 GetInt32WithAllBitsSet()
+ {
+ Int32 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int32*)&value) = (Int32)0xffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static UInt64 GetUInt64WithAllBitsSet()
+ {
+ UInt64 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((UInt64*)&value) = (UInt64)0xffffffffffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Int64 GetInt64WithAllBitsSet()
+ {
+ Int64 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int64*)&value) = (Int64)0xffffffffffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Single GetSingleWithAllBitsSet()
+ {
+ Single value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int32*)&value) = (Int32)0xffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Double GetDoubleWithAllBitsSet()
+ {
+ Double value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int64*)&value) = (Int64)0xffffffffffffffff;
+ }
+ }
+ return value;
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Numerics
+{
+ internal static class HashCodeHelper
+ {
+ /// <summary>
+ /// Combines two hash codes, useful for combining hash codes of individual vector elements
+ /// </summary>
+ internal static int CombineHashCodes(int h1, int h2)
+ {
+ return (((h1 << 5) + h1) ^ h2);
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Numerics
+{
+ /// <summary>
+ /// An attribute that can be attached to JIT Intrinsic methods/properties
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)]
+ internal class JitIntrinsicAttribute : Attribute
+ {
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+namespace System.Numerics
+{
+ /// <summary>
+ /// A structure describing the layout of an SSE2-sized register.
+ /// Contains overlapping fields representing the set of valid numeric types.
+ /// Allows the generic Vector'T struct to contain an explicit field layout.
+ /// </summary>
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct Register
+ {
+ #region Internal Storage Fields
+ // Internal System.Byte Fields
+ [FieldOffset(0)]
+ internal Byte byte_0;
+ [FieldOffset(1)]
+ internal Byte byte_1;
+ [FieldOffset(2)]
+ internal Byte byte_2;
+ [FieldOffset(3)]
+ internal Byte byte_3;
+ [FieldOffset(4)]
+ internal Byte byte_4;
+ [FieldOffset(5)]
+ internal Byte byte_5;
+ [FieldOffset(6)]
+ internal Byte byte_6;
+ [FieldOffset(7)]
+ internal Byte byte_7;
+ [FieldOffset(8)]
+ internal Byte byte_8;
+ [FieldOffset(9)]
+ internal Byte byte_9;
+ [FieldOffset(10)]
+ internal Byte byte_10;
+ [FieldOffset(11)]
+ internal Byte byte_11;
+ [FieldOffset(12)]
+ internal Byte byte_12;
+ [FieldOffset(13)]
+ internal Byte byte_13;
+ [FieldOffset(14)]
+ internal Byte byte_14;
+ [FieldOffset(15)]
+ internal Byte byte_15;
+
+ // Internal System.SByte Fields
+ [FieldOffset(0)]
+ internal SByte sbyte_0;
+ [FieldOffset(1)]
+ internal SByte sbyte_1;
+ [FieldOffset(2)]
+ internal SByte sbyte_2;
+ [FieldOffset(3)]
+ internal SByte sbyte_3;
+ [FieldOffset(4)]
+ internal SByte sbyte_4;
+ [FieldOffset(5)]
+ internal SByte sbyte_5;
+ [FieldOffset(6)]
+ internal SByte sbyte_6;
+ [FieldOffset(7)]
+ internal SByte sbyte_7;
+ [FieldOffset(8)]
+ internal SByte sbyte_8;
+ [FieldOffset(9)]
+ internal SByte sbyte_9;
+ [FieldOffset(10)]
+ internal SByte sbyte_10;
+ [FieldOffset(11)]
+ internal SByte sbyte_11;
+ [FieldOffset(12)]
+ internal SByte sbyte_12;
+ [FieldOffset(13)]
+ internal SByte sbyte_13;
+ [FieldOffset(14)]
+ internal SByte sbyte_14;
+ [FieldOffset(15)]
+ internal SByte sbyte_15;
+
+ // Internal System.UInt16 Fields
+ [FieldOffset(0)]
+ internal UInt16 uint16_0;
+ [FieldOffset(2)]
+ internal UInt16 uint16_1;
+ [FieldOffset(4)]
+ internal UInt16 uint16_2;
+ [FieldOffset(6)]
+ internal UInt16 uint16_3;
+ [FieldOffset(8)]
+ internal UInt16 uint16_4;
+ [FieldOffset(10)]
+ internal UInt16 uint16_5;
+ [FieldOffset(12)]
+ internal UInt16 uint16_6;
+ [FieldOffset(14)]
+ internal UInt16 uint16_7;
+
+ // Internal System.Int16 Fields
+ [FieldOffset(0)]
+ internal Int16 int16_0;
+ [FieldOffset(2)]
+ internal Int16 int16_1;
+ [FieldOffset(4)]
+ internal Int16 int16_2;
+ [FieldOffset(6)]
+ internal Int16 int16_3;
+ [FieldOffset(8)]
+ internal Int16 int16_4;
+ [FieldOffset(10)]
+ internal Int16 int16_5;
+ [FieldOffset(12)]
+ internal Int16 int16_6;
+ [FieldOffset(14)]
+ internal Int16 int16_7;
+
+ // Internal System.UInt32 Fields
+ [FieldOffset(0)]
+ internal UInt32 uint32_0;
+ [FieldOffset(4)]
+ internal UInt32 uint32_1;
+ [FieldOffset(8)]
+ internal UInt32 uint32_2;
+ [FieldOffset(12)]
+ internal UInt32 uint32_3;
+
+ // Internal System.Int32 Fields
+ [FieldOffset(0)]
+ internal Int32 int32_0;
+ [FieldOffset(4)]
+ internal Int32 int32_1;
+ [FieldOffset(8)]
+ internal Int32 int32_2;
+ [FieldOffset(12)]
+ internal Int32 int32_3;
+
+ // Internal System.UInt64 Fields
+ [FieldOffset(0)]
+ internal UInt64 uint64_0;
+ [FieldOffset(8)]
+ internal UInt64 uint64_1;
+
+ // Internal System.Int64 Fields
+ [FieldOffset(0)]
+ internal Int64 int64_0;
+ [FieldOffset(8)]
+ internal Int64 int64_1;
+
+ // Internal System.Single Fields
+ [FieldOffset(0)]
+ internal Single single_0;
+ [FieldOffset(4)]
+ internal Single single_1;
+ [FieldOffset(8)]
+ internal Single single_2;
+ [FieldOffset(12)]
+ internal Single single_3;
+
+ // Internal System.Double Fields
+ [FieldOffset(0)]
+ internal Double double_0;
+ [FieldOffset(8)]
+ internal Double double_1;
+
+ #endregion Internal Storage Fields
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace System.Numerics
+{
+ /* Note: The following patterns are used throughout the code here and are described here
+ *
+ * PATTERN:
+ * if (typeof(T) == typeof(Int32)) { ... }
+ * else if (typeof(T) == typeof(Single)) { ... }
+ * EXPLANATION:
+ * At runtime, each instantiation of Vector<T> will be type-specific, and each of these typeof blocks will be eliminated,
+ * as typeof(T) is a (JIT) compile-time constant for each instantiation. This design was chosen to eliminate any overhead from
+ * delegates and other patterns.
+ *
+ * PATTERN:
+ * if (Vector.IsHardwareAccelerated) { ... }
+ * else { ... }
+ * EXPLANATION
+ * This pattern solves two problems:
+ * 1. Allows us to unroll loops when we know the size (when no hardware acceleration is present)
+ * 2. Allows reflection to work:
+ * - If a method is called via reflection, it will not be "intrinsified", which would cause issues if we did
+ * not provide an implementation for that case (i.e. if it only included a case which assumed 16-byte registers)
+ * (NOTE: It is assumed that Vector.IsHardwareAccelerated will be a compile-time constant, eliminating these checks
+ * from the JIT'd code.)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /// <summary>
+ /// A structure that represents a single Vector. The count of this Vector is fixed but CPU register dependent.
+ /// This struct only supports numerical types. This type is intended to be used as a building block for vectorizing
+ /// large algorithms. This type is immutable, individual elements cannot be modified.
+ /// </summary>
+ public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
+ {
+ #region Fields
+ private Register register;
+ #endregion Fields
+
+ #region Static Members
+ /// <summary>
+ /// Returns the number of elements stored in the vector. This value is hardware dependent.
+ /// </summary>
+ [JitIntrinsic]
+ public static int Count
+ {
+ get
+ {
+ return s_count;
+ }
+ }
+ private static readonly int s_count = InitializeCount();
+
+ /// <summary>
+ /// Returns a vector containing all zeroes.
+ /// </summary>
+ [JitIntrinsic]
+ public static Vector<T> Zero { get { return zero; } }
+ private static readonly Vector<T> zero = new Vector<T>(GetZeroValue());
+
+ /// <summary>
+ /// Returns a vector containing all ones.
+ /// </summary>
+ [JitIntrinsic]
+ public static Vector<T> One { get { return one; } }
+ private static readonly Vector<T> one = new Vector<T>(GetOneValue());
+
+ internal static Vector<T> AllOnes { get { return allOnes; } }
+ private static readonly Vector<T> allOnes = new Vector<T>(GetAllBitsSetValue());
+ #endregion Static Members
+
+ #region Static Initialization
+ private struct VectorSizeHelper
+ {
+ internal Vector<T> _placeholder;
+ internal byte _byte;
+ }
+
+ // Calculates the size of this struct in bytes, by computing the offset of a field in a structure
+ private static unsafe int InitializeCount()
+ {
+ VectorSizeHelper vsh;
+ byte* vectorBase = &vsh._placeholder.register.byte_0;
+ byte* byteBase = &vsh._byte;
+ int vectorSizeInBytes = (int)(byteBase - vectorBase);
+
+ int typeSizeInBytes = -1;
+ if (typeof(T) == typeof(Byte))
+ {
+ typeSizeInBytes = sizeof(Byte);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ typeSizeInBytes = sizeof(SByte);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ typeSizeInBytes = sizeof(UInt16);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ typeSizeInBytes = sizeof(Int16);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ typeSizeInBytes = sizeof(UInt32);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ typeSizeInBytes = sizeof(Int32);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ typeSizeInBytes = sizeof(UInt64);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ typeSizeInBytes = sizeof(Int64);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ typeSizeInBytes = sizeof(Single);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ typeSizeInBytes = sizeof(Double);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+
+ return vectorSizeInBytes / typeSizeInBytes;
+ }
+ #endregion Static Initialization
+
+ #region Constructors
+ /// <summary>
+ /// Constructs a vector whose components are all <code>value</code>
+ /// </summary>
+ [JitIntrinsic]
+ public unsafe Vector(T value)
+ : this()
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Byte)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (SByte)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt16)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int16)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt32)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int32)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt64)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int64)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Single)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Double)(object)value;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = (Byte)(object)value;
+ register.byte_1 = (Byte)(object)value;
+ register.byte_2 = (Byte)(object)value;
+ register.byte_3 = (Byte)(object)value;
+ register.byte_4 = (Byte)(object)value;
+ register.byte_5 = (Byte)(object)value;
+ register.byte_6 = (Byte)(object)value;
+ register.byte_7 = (Byte)(object)value;
+ register.byte_8 = (Byte)(object)value;
+ register.byte_9 = (Byte)(object)value;
+ register.byte_10 = (Byte)(object)value;
+ register.byte_11 = (Byte)(object)value;
+ register.byte_12 = (Byte)(object)value;
+ register.byte_13 = (Byte)(object)value;
+ register.byte_14 = (Byte)(object)value;
+ register.byte_15 = (Byte)(object)value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = (SByte)(object)value;
+ register.sbyte_1 = (SByte)(object)value;
+ register.sbyte_2 = (SByte)(object)value;
+ register.sbyte_3 = (SByte)(object)value;
+ register.sbyte_4 = (SByte)(object)value;
+ register.sbyte_5 = (SByte)(object)value;
+ register.sbyte_6 = (SByte)(object)value;
+ register.sbyte_7 = (SByte)(object)value;
+ register.sbyte_8 = (SByte)(object)value;
+ register.sbyte_9 = (SByte)(object)value;
+ register.sbyte_10 = (SByte)(object)value;
+ register.sbyte_11 = (SByte)(object)value;
+ register.sbyte_12 = (SByte)(object)value;
+ register.sbyte_13 = (SByte)(object)value;
+ register.sbyte_14 = (SByte)(object)value;
+ register.sbyte_15 = (SByte)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = (UInt16)(object)value;
+ register.uint16_1 = (UInt16)(object)value;
+ register.uint16_2 = (UInt16)(object)value;
+ register.uint16_3 = (UInt16)(object)value;
+ register.uint16_4 = (UInt16)(object)value;
+ register.uint16_5 = (UInt16)(object)value;
+ register.uint16_6 = (UInt16)(object)value;
+ register.uint16_7 = (UInt16)(object)value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = (Int16)(object)value;
+ register.int16_1 = (Int16)(object)value;
+ register.int16_2 = (Int16)(object)value;
+ register.int16_3 = (Int16)(object)value;
+ register.int16_4 = (Int16)(object)value;
+ register.int16_5 = (Int16)(object)value;
+ register.int16_6 = (Int16)(object)value;
+ register.int16_7 = (Int16)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = (UInt32)(object)value;
+ register.uint32_1 = (UInt32)(object)value;
+ register.uint32_2 = (UInt32)(object)value;
+ register.uint32_3 = (UInt32)(object)value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = (Int32)(object)value;
+ register.int32_1 = (Int32)(object)value;
+ register.int32_2 = (Int32)(object)value;
+ register.int32_3 = (Int32)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = (UInt64)(object)value;
+ register.uint64_1 = (UInt64)(object)value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = (Int64)(object)value;
+ register.int64_1 = (Int64)(object)value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = (Single)(object)value;
+ register.single_1 = (Single)(object)value;
+ register.single_2 = (Single)(object)value;
+ register.single_3 = (Single)(object)value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = (Double)(object)value;
+ register.double_1 = (Double)(object)value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Constructs a vector from the given array. The size of the given array must be at least Vector'T.Count.
+ /// </summary>
+ [JitIntrinsic]
+ public unsafe Vector(T[] values) : this(values, 0) { }
+
+ /// <summary>
+ /// Constructs a vector from the given array, starting from the given index.
+ /// The array must contain at least Vector'T.Count from the given index.
+ /// </summary>
+ public unsafe Vector(T[] values, int index)
+ : this()
+ {
+ if (values == null)
+ {
+ // Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
+ throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
+ }
+ if (index < 0 || (values.Length - index) < Count)
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Byte)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (SByte)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt16)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int16)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt32)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int32)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt64)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int64)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Single)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Double)(object)values[g + index];
+ }
+ }
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ *(basePtr + 0) = (Byte)(object)values[0 + index];
+ *(basePtr + 1) = (Byte)(object)values[1 + index];
+ *(basePtr + 2) = (Byte)(object)values[2 + index];
+ *(basePtr + 3) = (Byte)(object)values[3 + index];
+ *(basePtr + 4) = (Byte)(object)values[4 + index];
+ *(basePtr + 5) = (Byte)(object)values[5 + index];
+ *(basePtr + 6) = (Byte)(object)values[6 + index];
+ *(basePtr + 7) = (Byte)(object)values[7 + index];
+ *(basePtr + 8) = (Byte)(object)values[8 + index];
+ *(basePtr + 9) = (Byte)(object)values[9 + index];
+ *(basePtr + 10) = (Byte)(object)values[10 + index];
+ *(basePtr + 11) = (Byte)(object)values[11 + index];
+ *(basePtr + 12) = (Byte)(object)values[12 + index];
+ *(basePtr + 13) = (Byte)(object)values[13 + index];
+ *(basePtr + 14) = (Byte)(object)values[14 + index];
+ *(basePtr + 15) = (Byte)(object)values[15 + index];
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ *(basePtr + 0) = (SByte)(object)values[0 + index];
+ *(basePtr + 1) = (SByte)(object)values[1 + index];
+ *(basePtr + 2) = (SByte)(object)values[2 + index];
+ *(basePtr + 3) = (SByte)(object)values[3 + index];
+ *(basePtr + 4) = (SByte)(object)values[4 + index];
+ *(basePtr + 5) = (SByte)(object)values[5 + index];
+ *(basePtr + 6) = (SByte)(object)values[6 + index];
+ *(basePtr + 7) = (SByte)(object)values[7 + index];
+ *(basePtr + 8) = (SByte)(object)values[8 + index];
+ *(basePtr + 9) = (SByte)(object)values[9 + index];
+ *(basePtr + 10) = (SByte)(object)values[10 + index];
+ *(basePtr + 11) = (SByte)(object)values[11 + index];
+ *(basePtr + 12) = (SByte)(object)values[12 + index];
+ *(basePtr + 13) = (SByte)(object)values[13 + index];
+ *(basePtr + 14) = (SByte)(object)values[14 + index];
+ *(basePtr + 15) = (SByte)(object)values[15 + index];
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ *(basePtr + 0) = (UInt16)(object)values[0 + index];
+ *(basePtr + 1) = (UInt16)(object)values[1 + index];
+ *(basePtr + 2) = (UInt16)(object)values[2 + index];
+ *(basePtr + 3) = (UInt16)(object)values[3 + index];
+ *(basePtr + 4) = (UInt16)(object)values[4 + index];
+ *(basePtr + 5) = (UInt16)(object)values[5 + index];
+ *(basePtr + 6) = (UInt16)(object)values[6 + index];
+ *(basePtr + 7) = (UInt16)(object)values[7 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ *(basePtr + 0) = (Int16)(object)values[0 + index];
+ *(basePtr + 1) = (Int16)(object)values[1 + index];
+ *(basePtr + 2) = (Int16)(object)values[2 + index];
+ *(basePtr + 3) = (Int16)(object)values[3 + index];
+ *(basePtr + 4) = (Int16)(object)values[4 + index];
+ *(basePtr + 5) = (Int16)(object)values[5 + index];
+ *(basePtr + 6) = (Int16)(object)values[6 + index];
+ *(basePtr + 7) = (Int16)(object)values[7 + index];
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ *(basePtr + 0) = (UInt32)(object)values[0 + index];
+ *(basePtr + 1) = (UInt32)(object)values[1 + index];
+ *(basePtr + 2) = (UInt32)(object)values[2 + index];
+ *(basePtr + 3) = (UInt32)(object)values[3 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ *(basePtr + 0) = (Int32)(object)values[0 + index];
+ *(basePtr + 1) = (Int32)(object)values[1 + index];
+ *(basePtr + 2) = (Int32)(object)values[2 + index];
+ *(basePtr + 3) = (Int32)(object)values[3 + index];
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ *(basePtr + 0) = (UInt64)(object)values[0 + index];
+ *(basePtr + 1) = (UInt64)(object)values[1 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ *(basePtr + 0) = (Int64)(object)values[0 + index];
+ *(basePtr + 1) = (Int64)(object)values[1 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ *(basePtr + 0) = (Single)(object)values[0 + index];
+ *(basePtr + 1) = (Single)(object)values[1 + index];
+ *(basePtr + 2) = (Single)(object)values[2 + index];
+ *(basePtr + 3) = (Single)(object)values[3 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ *(basePtr + 0) = (Double)(object)values[0 + index];
+ *(basePtr + 1) = (Double)(object)values[1 + index];
+ }
+ }
+ }
+ }
+
+#pragma warning disable 3001 // void* is not a CLS-Compliant argument type
+ private unsafe Vector(void* dataPointer) : this(dataPointer, 0) { }
+#pragma warning restore 3001 // void* is not a CLS-Compliant argument type
+
+#pragma warning disable 3001 // void* is not a CLS-Compliant argument type
+ // Implemented with offset if this API ever becomes public; an offset of 0 is used internally.
+ private unsafe Vector(void* dataPointer, int offset)
+ : this()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* castedPtr = (Byte*)dataPointer;
+ castedPtr += offset;
+ fixed (Byte* registerBase = &this.register.byte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* castedPtr = (SByte*)dataPointer;
+ castedPtr += offset;
+ fixed (SByte* registerBase = &this.register.sbyte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* castedPtr = (UInt16*)dataPointer;
+ castedPtr += offset;
+ fixed (UInt16* registerBase = &this.register.uint16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* castedPtr = (Int16*)dataPointer;
+ castedPtr += offset;
+ fixed (Int16* registerBase = &this.register.int16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* castedPtr = (UInt32*)dataPointer;
+ castedPtr += offset;
+ fixed (UInt32* registerBase = &this.register.uint32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* castedPtr = (Int32*)dataPointer;
+ castedPtr += offset;
+ fixed (Int32* registerBase = &this.register.int32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* castedPtr = (UInt64*)dataPointer;
+ castedPtr += offset;
+ fixed (UInt64* registerBase = &this.register.uint64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* castedPtr = (Int64*)dataPointer;
+ castedPtr += offset;
+ fixed (Int64* registerBase = &this.register.int64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* castedPtr = (Single*)dataPointer;
+ castedPtr += offset;
+ fixed (Single* registerBase = &this.register.single_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* castedPtr = (Double*)dataPointer;
+ castedPtr += offset;
+ fixed (Double* registerBase = &this.register.double_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+#pragma warning restore 3001 // void* is not a CLS-Compliant argument type
+
+ private Vector(ref Register existingRegister)
+ {
+ this.register = existingRegister;
+ }
+ #endregion Constructors
+
+ #region Public Instance Methods
+ /// <summary>
+ /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
+ /// </summary>
+ /// <param name="destination">The destination array which the values are copied into</param>
+ /// <exception cref="ArgumentNullException">If the destination array is null</exception>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array</exception>
+ [JitIntrinsic]
+ public unsafe void CopyTo(T[] destination)
+ {
+ CopyTo(destination, 0);
+ }
+
+ /// <summary>
+ /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
+ /// </summary>
+ /// <param name="destination">The destination array which the values are copied into</param>
+ /// <param name="startIndex">The index to start copying to</param>
+ /// <exception cref="ArgumentNullException">If the destination array is null</exception>
+ /// <exception cref="ArgumentOutOfRangeException">If index is greater than end of the array or index is less than zero</exception>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array</exception>
+ [JitIntrinsic]
+ public unsafe void CopyTo(T[] destination, int startIndex)
+ {
+ if (destination == null)
+ {
+ // Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
+ throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
+ }
+ if (startIndex < 0 || startIndex >= destination.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.Format(SR.Arg_ArgumentOutOfRangeException, startIndex));
+ }
+ if ((destination.Length - startIndex) < Count)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
+ }
+
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte[] byteArray = (Byte[])(object)destination;
+ fixed (Byte* destinationBase = byteArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Byte)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte[] sbyteArray = (SByte[])(object)destination;
+ fixed (SByte* destinationBase = sbyteArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (SByte)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16[] uint16Array = (UInt16[])(object)destination;
+ fixed (UInt16* destinationBase = uint16Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (UInt16)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16[] int16Array = (Int16[])(object)destination;
+ fixed (Int16* destinationBase = int16Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Int16)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32[] uint32Array = (UInt32[])(object)destination;
+ fixed (UInt32* destinationBase = uint32Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (UInt32)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32[] int32Array = (Int32[])(object)destination;
+ fixed (Int32* destinationBase = int32Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Int32)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64[] uint64Array = (UInt64[])(object)destination;
+ fixed (UInt64* destinationBase = uint64Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (UInt64)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64[] int64Array = (Int64[])(object)destination;
+ fixed (Int64* destinationBase = int64Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Int64)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single[] singleArray = (Single[])(object)destination;
+ fixed (Single* destinationBase = singleArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Single)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double[] doubleArray = (Double[])(object)destination;
+ fixed (Double* destinationBase = doubleArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Double)(object)this[g];
+ }
+ }
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte[] byteArray = (Byte[])(object)destination;
+ fixed (Byte* destinationBase = byteArray)
+ {
+ destinationBase[startIndex + 0] = this.register.byte_0;
+ destinationBase[startIndex + 1] = this.register.byte_1;
+ destinationBase[startIndex + 2] = this.register.byte_2;
+ destinationBase[startIndex + 3] = this.register.byte_3;
+ destinationBase[startIndex + 4] = this.register.byte_4;
+ destinationBase[startIndex + 5] = this.register.byte_5;
+ destinationBase[startIndex + 6] = this.register.byte_6;
+ destinationBase[startIndex + 7] = this.register.byte_7;
+ destinationBase[startIndex + 8] = this.register.byte_8;
+ destinationBase[startIndex + 9] = this.register.byte_9;
+ destinationBase[startIndex + 10] = this.register.byte_10;
+ destinationBase[startIndex + 11] = this.register.byte_11;
+ destinationBase[startIndex + 12] = this.register.byte_12;
+ destinationBase[startIndex + 13] = this.register.byte_13;
+ destinationBase[startIndex + 14] = this.register.byte_14;
+ destinationBase[startIndex + 15] = this.register.byte_15;
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte[] sbyteArray = (SByte[])(object)destination;
+ fixed (SByte* destinationBase = sbyteArray)
+ {
+ destinationBase[startIndex + 0] = this.register.sbyte_0;
+ destinationBase[startIndex + 1] = this.register.sbyte_1;
+ destinationBase[startIndex + 2] = this.register.sbyte_2;
+ destinationBase[startIndex + 3] = this.register.sbyte_3;
+ destinationBase[startIndex + 4] = this.register.sbyte_4;
+ destinationBase[startIndex + 5] = this.register.sbyte_5;
+ destinationBase[startIndex + 6] = this.register.sbyte_6;
+ destinationBase[startIndex + 7] = this.register.sbyte_7;
+ destinationBase[startIndex + 8] = this.register.sbyte_8;
+ destinationBase[startIndex + 9] = this.register.sbyte_9;
+ destinationBase[startIndex + 10] = this.register.sbyte_10;
+ destinationBase[startIndex + 11] = this.register.sbyte_11;
+ destinationBase[startIndex + 12] = this.register.sbyte_12;
+ destinationBase[startIndex + 13] = this.register.sbyte_13;
+ destinationBase[startIndex + 14] = this.register.sbyte_14;
+ destinationBase[startIndex + 15] = this.register.sbyte_15;
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16[] uint16Array = (UInt16[])(object)destination;
+ fixed (UInt16* destinationBase = uint16Array)
+ {
+ destinationBase[startIndex + 0] = this.register.uint16_0;
+ destinationBase[startIndex + 1] = this.register.uint16_1;
+ destinationBase[startIndex + 2] = this.register.uint16_2;
+ destinationBase[startIndex + 3] = this.register.uint16_3;
+ destinationBase[startIndex + 4] = this.register.uint16_4;
+ destinationBase[startIndex + 5] = this.register.uint16_5;
+ destinationBase[startIndex + 6] = this.register.uint16_6;
+ destinationBase[startIndex + 7] = this.register.uint16_7;
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16[] int16Array = (Int16[])(object)destination;
+ fixed (Int16* destinationBase = int16Array)
+ {
+ destinationBase[startIndex + 0] = this.register.int16_0;
+ destinationBase[startIndex + 1] = this.register.int16_1;
+ destinationBase[startIndex + 2] = this.register.int16_2;
+ destinationBase[startIndex + 3] = this.register.int16_3;
+ destinationBase[startIndex + 4] = this.register.int16_4;
+ destinationBase[startIndex + 5] = this.register.int16_5;
+ destinationBase[startIndex + 6] = this.register.int16_6;
+ destinationBase[startIndex + 7] = this.register.int16_7;
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32[] uint32Array = (UInt32[])(object)destination;
+ fixed (UInt32* destinationBase = uint32Array)
+ {
+ destinationBase[startIndex + 0] = this.register.uint32_0;
+ destinationBase[startIndex + 1] = this.register.uint32_1;
+ destinationBase[startIndex + 2] = this.register.uint32_2;
+ destinationBase[startIndex + 3] = this.register.uint32_3;
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32[] int32Array = (Int32[])(object)destination;
+ fixed (Int32* destinationBase = int32Array)
+ {
+ destinationBase[startIndex + 0] = this.register.int32_0;
+ destinationBase[startIndex + 1] = this.register.int32_1;
+ destinationBase[startIndex + 2] = this.register.int32_2;
+ destinationBase[startIndex + 3] = this.register.int32_3;
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64[] uint64Array = (UInt64[])(object)destination;
+ fixed (UInt64* destinationBase = uint64Array)
+ {
+ destinationBase[startIndex + 0] = this.register.uint64_0;
+ destinationBase[startIndex + 1] = this.register.uint64_1;
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64[] int64Array = (Int64[])(object)destination;
+ fixed (Int64* destinationBase = int64Array)
+ {
+ destinationBase[startIndex + 0] = this.register.int64_0;
+ destinationBase[startIndex + 1] = this.register.int64_1;
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single[] singleArray = (Single[])(object)destination;
+ fixed (Single* destinationBase = singleArray)
+ {
+ destinationBase[startIndex + 0] = this.register.single_0;
+ destinationBase[startIndex + 1] = this.register.single_1;
+ destinationBase[startIndex + 2] = this.register.single_2;
+ destinationBase[startIndex + 3] = this.register.single_3;
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double[] doubleArray = (Double[])(object)destination;
+ fixed (Double* destinationBase = doubleArray)
+ {
+ destinationBase[startIndex + 0] = this.register.double_0;
+ destinationBase[startIndex + 1] = this.register.double_1;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the element at the given index.
+ /// </summary>
+ [JitIntrinsic]
+ public unsafe T this[int index]
+ {
+ get
+ {
+ if (index >= Count || index < 0)
+ {
+ throw new IndexOutOfRangeException(SR.Format(SR.Arg_ArgumentOutOfRangeException, index));
+ }
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the given Object is equal to this vector instance.
+ /// </summary>
+ /// <param name="obj">The Object to compare against.</param>
+ /// <returns>True if the Object is equal to this vector; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Vector<T>))
+ {
+ return false;
+ }
+ return Equals((Vector<T>)obj);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the given vector is equal to this vector instance.
+ /// </summary>
+ /// <param name="other">The vector to compare this instance to.</param>
+ /// <returns>True if the other vector is equal to this instance; False otherwise.</returns>
+ [JitIntrinsic]
+ public bool Equals(Vector<T> other)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ if (!ScalarEquals(this[g], other[g]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return
+ this.register.byte_0 == other.register.byte_0
+ && this.register.byte_1 == other.register.byte_1
+ && this.register.byte_2 == other.register.byte_2
+ && this.register.byte_3 == other.register.byte_3
+ && this.register.byte_4 == other.register.byte_4
+ && this.register.byte_5 == other.register.byte_5
+ && this.register.byte_6 == other.register.byte_6
+ && this.register.byte_7 == other.register.byte_7
+ && this.register.byte_8 == other.register.byte_8
+ && this.register.byte_9 == other.register.byte_9
+ && this.register.byte_10 == other.register.byte_10
+ && this.register.byte_11 == other.register.byte_11
+ && this.register.byte_12 == other.register.byte_12
+ && this.register.byte_13 == other.register.byte_13
+ && this.register.byte_14 == other.register.byte_14
+ && this.register.byte_15 == other.register.byte_15;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return
+ this.register.sbyte_0 == other.register.sbyte_0
+ && this.register.sbyte_1 == other.register.sbyte_1
+ && this.register.sbyte_2 == other.register.sbyte_2
+ && this.register.sbyte_3 == other.register.sbyte_3
+ && this.register.sbyte_4 == other.register.sbyte_4
+ && this.register.sbyte_5 == other.register.sbyte_5
+ && this.register.sbyte_6 == other.register.sbyte_6
+ && this.register.sbyte_7 == other.register.sbyte_7
+ && this.register.sbyte_8 == other.register.sbyte_8
+ && this.register.sbyte_9 == other.register.sbyte_9
+ && this.register.sbyte_10 == other.register.sbyte_10
+ && this.register.sbyte_11 == other.register.sbyte_11
+ && this.register.sbyte_12 == other.register.sbyte_12
+ && this.register.sbyte_13 == other.register.sbyte_13
+ && this.register.sbyte_14 == other.register.sbyte_14
+ && this.register.sbyte_15 == other.register.sbyte_15;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return
+ this.register.uint16_0 == other.register.uint16_0
+ && this.register.uint16_1 == other.register.uint16_1
+ && this.register.uint16_2 == other.register.uint16_2
+ && this.register.uint16_3 == other.register.uint16_3
+ && this.register.uint16_4 == other.register.uint16_4
+ && this.register.uint16_5 == other.register.uint16_5
+ && this.register.uint16_6 == other.register.uint16_6
+ && this.register.uint16_7 == other.register.uint16_7;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return
+ this.register.int16_0 == other.register.int16_0
+ && this.register.int16_1 == other.register.int16_1
+ && this.register.int16_2 == other.register.int16_2
+ && this.register.int16_3 == other.register.int16_3
+ && this.register.int16_4 == other.register.int16_4
+ && this.register.int16_5 == other.register.int16_5
+ && this.register.int16_6 == other.register.int16_6
+ && this.register.int16_7 == other.register.int16_7;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return
+ this.register.uint32_0 == other.register.uint32_0
+ && this.register.uint32_1 == other.register.uint32_1
+ && this.register.uint32_2 == other.register.uint32_2
+ && this.register.uint32_3 == other.register.uint32_3;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return
+ this.register.int32_0 == other.register.int32_0
+ && this.register.int32_1 == other.register.int32_1
+ && this.register.int32_2 == other.register.int32_2
+ && this.register.int32_3 == other.register.int32_3;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return
+ this.register.uint64_0 == other.register.uint64_0
+ && this.register.uint64_1 == other.register.uint64_1;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return
+ this.register.int64_0 == other.register.int64_0
+ && this.register.int64_1 == other.register.int64_1;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return
+ this.register.single_0 == other.register.single_0
+ && this.register.single_1 == other.register.single_1
+ && this.register.single_2 == other.register.single_2
+ && this.register.single_3 == other.register.single_3;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return
+ this.register.double_0 == other.register.double_0
+ && this.register.double_1 == other.register.double_1;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the hash code for this instance.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ int hash = 0;
+
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Byte)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((SByte)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((UInt16)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Int16)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((UInt32)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Int32)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((UInt64)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Int64)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Single)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Double)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_7.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_8.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_9.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_10.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_11.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_12.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_13.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_14.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_15.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_7.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_8.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_9.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_10.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_11.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_12.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_13.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_14.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_15.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_7.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_7.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_3.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_3.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint64_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint64_1.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int64_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int64_1.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_3.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.double_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.double_1.GetHashCode());
+ return hash;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns a String representing this vector.
+ /// </summary>
+ /// <returns>The string representation.</returns>
+ public override string ToString()
+ {
+ return ToString("G", CultureInfo.CurrentCulture);
+ }
+
+ /// <summary>
+ /// Returns a String representing this vector, using the specified format string to format individual elements.
+ /// </summary>
+ /// <param name="format">The format of individual elements.</param>
+ /// <returns>The string representation.</returns>
+ public string ToString(string format)
+ {
+ return ToString(format, CultureInfo.CurrentCulture);
+ }
+
+ /// <summary>
+ /// Returns a String representing this vector, using the specified format string to format individual elements
+ /// and the given IFormatProvider.
+ /// </summary>
+ /// <param name="format">The format of individual elements.</param>
+ /// <param name="formatProvider">The format provider to use when formatting elements.</param>
+ /// <returns>The string representation.</returns>
+ public string ToString(string format, IFormatProvider formatProvider)
+ {
+ StringBuilder sb = new StringBuilder();
+ string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
+ sb.Append('<');
+ for (int g = 0; g < Count - 1; g++)
+ {
+ sb.Append(((IFormattable)this[g]).ToString(format, formatProvider));
+ sb.Append(separator);
+ sb.Append(' ');
+ }
+ // Append last element w/out separator
+ sb.Append(((IFormattable)this[Count - 1]).ToString(format, formatProvider));
+ sb.Append('>');
+ return sb.ToString();
+ }
+ #endregion Public Instance Methods
+
+ #region Arithmetic Operators
+ /// <summary>
+ /// Adds two vectors together.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The summed vector.</returns>
+ public static unsafe Vector<T> operator +(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> sum = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ sum.register.byte_0 = (Byte)(left.register.byte_0 + right.register.byte_0);
+ sum.register.byte_1 = (Byte)(left.register.byte_1 + right.register.byte_1);
+ sum.register.byte_2 = (Byte)(left.register.byte_2 + right.register.byte_2);
+ sum.register.byte_3 = (Byte)(left.register.byte_3 + right.register.byte_3);
+ sum.register.byte_4 = (Byte)(left.register.byte_4 + right.register.byte_4);
+ sum.register.byte_5 = (Byte)(left.register.byte_5 + right.register.byte_5);
+ sum.register.byte_6 = (Byte)(left.register.byte_6 + right.register.byte_6);
+ sum.register.byte_7 = (Byte)(left.register.byte_7 + right.register.byte_7);
+ sum.register.byte_8 = (Byte)(left.register.byte_8 + right.register.byte_8);
+ sum.register.byte_9 = (Byte)(left.register.byte_9 + right.register.byte_9);
+ sum.register.byte_10 = (Byte)(left.register.byte_10 + right.register.byte_10);
+ sum.register.byte_11 = (Byte)(left.register.byte_11 + right.register.byte_11);
+ sum.register.byte_12 = (Byte)(left.register.byte_12 + right.register.byte_12);
+ sum.register.byte_13 = (Byte)(left.register.byte_13 + right.register.byte_13);
+ sum.register.byte_14 = (Byte)(left.register.byte_14 + right.register.byte_14);
+ sum.register.byte_15 = (Byte)(left.register.byte_15 + right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ sum.register.sbyte_0 = (SByte)(left.register.sbyte_0 + right.register.sbyte_0);
+ sum.register.sbyte_1 = (SByte)(left.register.sbyte_1 + right.register.sbyte_1);
+ sum.register.sbyte_2 = (SByte)(left.register.sbyte_2 + right.register.sbyte_2);
+ sum.register.sbyte_3 = (SByte)(left.register.sbyte_3 + right.register.sbyte_3);
+ sum.register.sbyte_4 = (SByte)(left.register.sbyte_4 + right.register.sbyte_4);
+ sum.register.sbyte_5 = (SByte)(left.register.sbyte_5 + right.register.sbyte_5);
+ sum.register.sbyte_6 = (SByte)(left.register.sbyte_6 + right.register.sbyte_6);
+ sum.register.sbyte_7 = (SByte)(left.register.sbyte_7 + right.register.sbyte_7);
+ sum.register.sbyte_8 = (SByte)(left.register.sbyte_8 + right.register.sbyte_8);
+ sum.register.sbyte_9 = (SByte)(left.register.sbyte_9 + right.register.sbyte_9);
+ sum.register.sbyte_10 = (SByte)(left.register.sbyte_10 + right.register.sbyte_10);
+ sum.register.sbyte_11 = (SByte)(left.register.sbyte_11 + right.register.sbyte_11);
+ sum.register.sbyte_12 = (SByte)(left.register.sbyte_12 + right.register.sbyte_12);
+ sum.register.sbyte_13 = (SByte)(left.register.sbyte_13 + right.register.sbyte_13);
+ sum.register.sbyte_14 = (SByte)(left.register.sbyte_14 + right.register.sbyte_14);
+ sum.register.sbyte_15 = (SByte)(left.register.sbyte_15 + right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ sum.register.uint16_0 = (UInt16)(left.register.uint16_0 + right.register.uint16_0);
+ sum.register.uint16_1 = (UInt16)(left.register.uint16_1 + right.register.uint16_1);
+ sum.register.uint16_2 = (UInt16)(left.register.uint16_2 + right.register.uint16_2);
+ sum.register.uint16_3 = (UInt16)(left.register.uint16_3 + right.register.uint16_3);
+ sum.register.uint16_4 = (UInt16)(left.register.uint16_4 + right.register.uint16_4);
+ sum.register.uint16_5 = (UInt16)(left.register.uint16_5 + right.register.uint16_5);
+ sum.register.uint16_6 = (UInt16)(left.register.uint16_6 + right.register.uint16_6);
+ sum.register.uint16_7 = (UInt16)(left.register.uint16_7 + right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ sum.register.int16_0 = (Int16)(left.register.int16_0 + right.register.int16_0);
+ sum.register.int16_1 = (Int16)(left.register.int16_1 + right.register.int16_1);
+ sum.register.int16_2 = (Int16)(left.register.int16_2 + right.register.int16_2);
+ sum.register.int16_3 = (Int16)(left.register.int16_3 + right.register.int16_3);
+ sum.register.int16_4 = (Int16)(left.register.int16_4 + right.register.int16_4);
+ sum.register.int16_5 = (Int16)(left.register.int16_5 + right.register.int16_5);
+ sum.register.int16_6 = (Int16)(left.register.int16_6 + right.register.int16_6);
+ sum.register.int16_7 = (Int16)(left.register.int16_7 + right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ sum.register.uint32_0 = (UInt32)(left.register.uint32_0 + right.register.uint32_0);
+ sum.register.uint32_1 = (UInt32)(left.register.uint32_1 + right.register.uint32_1);
+ sum.register.uint32_2 = (UInt32)(left.register.uint32_2 + right.register.uint32_2);
+ sum.register.uint32_3 = (UInt32)(left.register.uint32_3 + right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ sum.register.int32_0 = (Int32)(left.register.int32_0 + right.register.int32_0);
+ sum.register.int32_1 = (Int32)(left.register.int32_1 + right.register.int32_1);
+ sum.register.int32_2 = (Int32)(left.register.int32_2 + right.register.int32_2);
+ sum.register.int32_3 = (Int32)(left.register.int32_3 + right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ sum.register.uint64_0 = (UInt64)(left.register.uint64_0 + right.register.uint64_0);
+ sum.register.uint64_1 = (UInt64)(left.register.uint64_1 + right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ sum.register.int64_0 = (Int64)(left.register.int64_0 + right.register.int64_0);
+ sum.register.int64_1 = (Int64)(left.register.int64_1 + right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ sum.register.single_0 = (Single)(left.register.single_0 + right.register.single_0);
+ sum.register.single_1 = (Single)(left.register.single_1 + right.register.single_1);
+ sum.register.single_2 = (Single)(left.register.single_2 + right.register.single_2);
+ sum.register.single_3 = (Single)(left.register.single_3 + right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ sum.register.double_0 = (Double)(left.register.double_0 + right.register.double_0);
+ sum.register.double_1 = (Double)(left.register.double_1 + right.register.double_1);
+ }
+ return sum;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Subtracts the second vector from the first.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The difference vector.</returns>
+ public static unsafe Vector<T> operator -(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> difference = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ difference.register.byte_0 = (Byte)(left.register.byte_0 - right.register.byte_0);
+ difference.register.byte_1 = (Byte)(left.register.byte_1 - right.register.byte_1);
+ difference.register.byte_2 = (Byte)(left.register.byte_2 - right.register.byte_2);
+ difference.register.byte_3 = (Byte)(left.register.byte_3 - right.register.byte_3);
+ difference.register.byte_4 = (Byte)(left.register.byte_4 - right.register.byte_4);
+ difference.register.byte_5 = (Byte)(left.register.byte_5 - right.register.byte_5);
+ difference.register.byte_6 = (Byte)(left.register.byte_6 - right.register.byte_6);
+ difference.register.byte_7 = (Byte)(left.register.byte_7 - right.register.byte_7);
+ difference.register.byte_8 = (Byte)(left.register.byte_8 - right.register.byte_8);
+ difference.register.byte_9 = (Byte)(left.register.byte_9 - right.register.byte_9);
+ difference.register.byte_10 = (Byte)(left.register.byte_10 - right.register.byte_10);
+ difference.register.byte_11 = (Byte)(left.register.byte_11 - right.register.byte_11);
+ difference.register.byte_12 = (Byte)(left.register.byte_12 - right.register.byte_12);
+ difference.register.byte_13 = (Byte)(left.register.byte_13 - right.register.byte_13);
+ difference.register.byte_14 = (Byte)(left.register.byte_14 - right.register.byte_14);
+ difference.register.byte_15 = (Byte)(left.register.byte_15 - right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ difference.register.sbyte_0 = (SByte)(left.register.sbyte_0 - right.register.sbyte_0);
+ difference.register.sbyte_1 = (SByte)(left.register.sbyte_1 - right.register.sbyte_1);
+ difference.register.sbyte_2 = (SByte)(left.register.sbyte_2 - right.register.sbyte_2);
+ difference.register.sbyte_3 = (SByte)(left.register.sbyte_3 - right.register.sbyte_3);
+ difference.register.sbyte_4 = (SByte)(left.register.sbyte_4 - right.register.sbyte_4);
+ difference.register.sbyte_5 = (SByte)(left.register.sbyte_5 - right.register.sbyte_5);
+ difference.register.sbyte_6 = (SByte)(left.register.sbyte_6 - right.register.sbyte_6);
+ difference.register.sbyte_7 = (SByte)(left.register.sbyte_7 - right.register.sbyte_7);
+ difference.register.sbyte_8 = (SByte)(left.register.sbyte_8 - right.register.sbyte_8);
+ difference.register.sbyte_9 = (SByte)(left.register.sbyte_9 - right.register.sbyte_9);
+ difference.register.sbyte_10 = (SByte)(left.register.sbyte_10 - right.register.sbyte_10);
+ difference.register.sbyte_11 = (SByte)(left.register.sbyte_11 - right.register.sbyte_11);
+ difference.register.sbyte_12 = (SByte)(left.register.sbyte_12 - right.register.sbyte_12);
+ difference.register.sbyte_13 = (SByte)(left.register.sbyte_13 - right.register.sbyte_13);
+ difference.register.sbyte_14 = (SByte)(left.register.sbyte_14 - right.register.sbyte_14);
+ difference.register.sbyte_15 = (SByte)(left.register.sbyte_15 - right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ difference.register.uint16_0 = (UInt16)(left.register.uint16_0 - right.register.uint16_0);
+ difference.register.uint16_1 = (UInt16)(left.register.uint16_1 - right.register.uint16_1);
+ difference.register.uint16_2 = (UInt16)(left.register.uint16_2 - right.register.uint16_2);
+ difference.register.uint16_3 = (UInt16)(left.register.uint16_3 - right.register.uint16_3);
+ difference.register.uint16_4 = (UInt16)(left.register.uint16_4 - right.register.uint16_4);
+ difference.register.uint16_5 = (UInt16)(left.register.uint16_5 - right.register.uint16_5);
+ difference.register.uint16_6 = (UInt16)(left.register.uint16_6 - right.register.uint16_6);
+ difference.register.uint16_7 = (UInt16)(left.register.uint16_7 - right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ difference.register.int16_0 = (Int16)(left.register.int16_0 - right.register.int16_0);
+ difference.register.int16_1 = (Int16)(left.register.int16_1 - right.register.int16_1);
+ difference.register.int16_2 = (Int16)(left.register.int16_2 - right.register.int16_2);
+ difference.register.int16_3 = (Int16)(left.register.int16_3 - right.register.int16_3);
+ difference.register.int16_4 = (Int16)(left.register.int16_4 - right.register.int16_4);
+ difference.register.int16_5 = (Int16)(left.register.int16_5 - right.register.int16_5);
+ difference.register.int16_6 = (Int16)(left.register.int16_6 - right.register.int16_6);
+ difference.register.int16_7 = (Int16)(left.register.int16_7 - right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ difference.register.uint32_0 = (UInt32)(left.register.uint32_0 - right.register.uint32_0);
+ difference.register.uint32_1 = (UInt32)(left.register.uint32_1 - right.register.uint32_1);
+ difference.register.uint32_2 = (UInt32)(left.register.uint32_2 - right.register.uint32_2);
+ difference.register.uint32_3 = (UInt32)(left.register.uint32_3 - right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ difference.register.int32_0 = (Int32)(left.register.int32_0 - right.register.int32_0);
+ difference.register.int32_1 = (Int32)(left.register.int32_1 - right.register.int32_1);
+ difference.register.int32_2 = (Int32)(left.register.int32_2 - right.register.int32_2);
+ difference.register.int32_3 = (Int32)(left.register.int32_3 - right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ difference.register.uint64_0 = (UInt64)(left.register.uint64_0 - right.register.uint64_0);
+ difference.register.uint64_1 = (UInt64)(left.register.uint64_1 - right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ difference.register.int64_0 = (Int64)(left.register.int64_0 - right.register.int64_0);
+ difference.register.int64_1 = (Int64)(left.register.int64_1 - right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ difference.register.single_0 = (Single)(left.register.single_0 - right.register.single_0);
+ difference.register.single_1 = (Single)(left.register.single_1 - right.register.single_1);
+ difference.register.single_2 = (Single)(left.register.single_2 - right.register.single_2);
+ difference.register.single_3 = (Single)(left.register.single_3 - right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ difference.register.double_0 = (Double)(left.register.double_0 - right.register.double_0);
+ difference.register.double_1 = (Double)(left.register.double_1 - right.register.double_1);
+ }
+ return difference;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Multiplies two vectors together.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The product vector.</returns>
+ public static unsafe Vector<T> operator *(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> product = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ product.register.byte_0 = (Byte)(left.register.byte_0 * right.register.byte_0);
+ product.register.byte_1 = (Byte)(left.register.byte_1 * right.register.byte_1);
+ product.register.byte_2 = (Byte)(left.register.byte_2 * right.register.byte_2);
+ product.register.byte_3 = (Byte)(left.register.byte_3 * right.register.byte_3);
+ product.register.byte_4 = (Byte)(left.register.byte_4 * right.register.byte_4);
+ product.register.byte_5 = (Byte)(left.register.byte_5 * right.register.byte_5);
+ product.register.byte_6 = (Byte)(left.register.byte_6 * right.register.byte_6);
+ product.register.byte_7 = (Byte)(left.register.byte_7 * right.register.byte_7);
+ product.register.byte_8 = (Byte)(left.register.byte_8 * right.register.byte_8);
+ product.register.byte_9 = (Byte)(left.register.byte_9 * right.register.byte_9);
+ product.register.byte_10 = (Byte)(left.register.byte_10 * right.register.byte_10);
+ product.register.byte_11 = (Byte)(left.register.byte_11 * right.register.byte_11);
+ product.register.byte_12 = (Byte)(left.register.byte_12 * right.register.byte_12);
+ product.register.byte_13 = (Byte)(left.register.byte_13 * right.register.byte_13);
+ product.register.byte_14 = (Byte)(left.register.byte_14 * right.register.byte_14);
+ product.register.byte_15 = (Byte)(left.register.byte_15 * right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ product.register.sbyte_0 = (SByte)(left.register.sbyte_0 * right.register.sbyte_0);
+ product.register.sbyte_1 = (SByte)(left.register.sbyte_1 * right.register.sbyte_1);
+ product.register.sbyte_2 = (SByte)(left.register.sbyte_2 * right.register.sbyte_2);
+ product.register.sbyte_3 = (SByte)(left.register.sbyte_3 * right.register.sbyte_3);
+ product.register.sbyte_4 = (SByte)(left.register.sbyte_4 * right.register.sbyte_4);
+ product.register.sbyte_5 = (SByte)(left.register.sbyte_5 * right.register.sbyte_5);
+ product.register.sbyte_6 = (SByte)(left.register.sbyte_6 * right.register.sbyte_6);
+ product.register.sbyte_7 = (SByte)(left.register.sbyte_7 * right.register.sbyte_7);
+ product.register.sbyte_8 = (SByte)(left.register.sbyte_8 * right.register.sbyte_8);
+ product.register.sbyte_9 = (SByte)(left.register.sbyte_9 * right.register.sbyte_9);
+ product.register.sbyte_10 = (SByte)(left.register.sbyte_10 * right.register.sbyte_10);
+ product.register.sbyte_11 = (SByte)(left.register.sbyte_11 * right.register.sbyte_11);
+ product.register.sbyte_12 = (SByte)(left.register.sbyte_12 * right.register.sbyte_12);
+ product.register.sbyte_13 = (SByte)(left.register.sbyte_13 * right.register.sbyte_13);
+ product.register.sbyte_14 = (SByte)(left.register.sbyte_14 * right.register.sbyte_14);
+ product.register.sbyte_15 = (SByte)(left.register.sbyte_15 * right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ product.register.uint16_0 = (UInt16)(left.register.uint16_0 * right.register.uint16_0);
+ product.register.uint16_1 = (UInt16)(left.register.uint16_1 * right.register.uint16_1);
+ product.register.uint16_2 = (UInt16)(left.register.uint16_2 * right.register.uint16_2);
+ product.register.uint16_3 = (UInt16)(left.register.uint16_3 * right.register.uint16_3);
+ product.register.uint16_4 = (UInt16)(left.register.uint16_4 * right.register.uint16_4);
+ product.register.uint16_5 = (UInt16)(left.register.uint16_5 * right.register.uint16_5);
+ product.register.uint16_6 = (UInt16)(left.register.uint16_6 * right.register.uint16_6);
+ product.register.uint16_7 = (UInt16)(left.register.uint16_7 * right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ product.register.int16_0 = (Int16)(left.register.int16_0 * right.register.int16_0);
+ product.register.int16_1 = (Int16)(left.register.int16_1 * right.register.int16_1);
+ product.register.int16_2 = (Int16)(left.register.int16_2 * right.register.int16_2);
+ product.register.int16_3 = (Int16)(left.register.int16_3 * right.register.int16_3);
+ product.register.int16_4 = (Int16)(left.register.int16_4 * right.register.int16_4);
+ product.register.int16_5 = (Int16)(left.register.int16_5 * right.register.int16_5);
+ product.register.int16_6 = (Int16)(left.register.int16_6 * right.register.int16_6);
+ product.register.int16_7 = (Int16)(left.register.int16_7 * right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ product.register.uint32_0 = (UInt32)(left.register.uint32_0 * right.register.uint32_0);
+ product.register.uint32_1 = (UInt32)(left.register.uint32_1 * right.register.uint32_1);
+ product.register.uint32_2 = (UInt32)(left.register.uint32_2 * right.register.uint32_2);
+ product.register.uint32_3 = (UInt32)(left.register.uint32_3 * right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ product.register.int32_0 = (Int32)(left.register.int32_0 * right.register.int32_0);
+ product.register.int32_1 = (Int32)(left.register.int32_1 * right.register.int32_1);
+ product.register.int32_2 = (Int32)(left.register.int32_2 * right.register.int32_2);
+ product.register.int32_3 = (Int32)(left.register.int32_3 * right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ product.register.uint64_0 = (UInt64)(left.register.uint64_0 * right.register.uint64_0);
+ product.register.uint64_1 = (UInt64)(left.register.uint64_1 * right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ product.register.int64_0 = (Int64)(left.register.int64_0 * right.register.int64_0);
+ product.register.int64_1 = (Int64)(left.register.int64_1 * right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ product.register.single_0 = (Single)(left.register.single_0 * right.register.single_0);
+ product.register.single_1 = (Single)(left.register.single_1 * right.register.single_1);
+ product.register.single_2 = (Single)(left.register.single_2 * right.register.single_2);
+ product.register.single_3 = (Single)(left.register.single_3 * right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ product.register.double_0 = (Double)(left.register.double_0 * right.register.double_0);
+ product.register.double_1 = (Double)(left.register.double_1 * right.register.double_1);
+ }
+ return product;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Multiplies a vector by the given scalar.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <param name="factor">The scalar value.</param>
+ /// <returns>The scaled vector.</returns>
+ public static Vector<T> operator *(Vector<T> value, T factor)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ return new Vector<T>(factor) * value;
+ }
+ else
+ {
+ Vector<T> product = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ product.register.byte_0 = (Byte)(value.register.byte_0 * (Byte)(object)factor);
+ product.register.byte_1 = (Byte)(value.register.byte_1 * (Byte)(object)factor);
+ product.register.byte_2 = (Byte)(value.register.byte_2 * (Byte)(object)factor);
+ product.register.byte_3 = (Byte)(value.register.byte_3 * (Byte)(object)factor);
+ product.register.byte_4 = (Byte)(value.register.byte_4 * (Byte)(object)factor);
+ product.register.byte_5 = (Byte)(value.register.byte_5 * (Byte)(object)factor);
+ product.register.byte_6 = (Byte)(value.register.byte_6 * (Byte)(object)factor);
+ product.register.byte_7 = (Byte)(value.register.byte_7 * (Byte)(object)factor);
+ product.register.byte_8 = (Byte)(value.register.byte_8 * (Byte)(object)factor);
+ product.register.byte_9 = (Byte)(value.register.byte_9 * (Byte)(object)factor);
+ product.register.byte_10 = (Byte)(value.register.byte_10 * (Byte)(object)factor);
+ product.register.byte_11 = (Byte)(value.register.byte_11 * (Byte)(object)factor);
+ product.register.byte_12 = (Byte)(value.register.byte_12 * (Byte)(object)factor);
+ product.register.byte_13 = (Byte)(value.register.byte_13 * (Byte)(object)factor);
+ product.register.byte_14 = (Byte)(value.register.byte_14 * (Byte)(object)factor);
+ product.register.byte_15 = (Byte)(value.register.byte_15 * (Byte)(object)factor);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ product.register.sbyte_0 = (SByte)(value.register.sbyte_0 * (SByte)(object)factor);
+ product.register.sbyte_1 = (SByte)(value.register.sbyte_1 * (SByte)(object)factor);
+ product.register.sbyte_2 = (SByte)(value.register.sbyte_2 * (SByte)(object)factor);
+ product.register.sbyte_3 = (SByte)(value.register.sbyte_3 * (SByte)(object)factor);
+ product.register.sbyte_4 = (SByte)(value.register.sbyte_4 * (SByte)(object)factor);
+ product.register.sbyte_5 = (SByte)(value.register.sbyte_5 * (SByte)(object)factor);
+ product.register.sbyte_6 = (SByte)(value.register.sbyte_6 * (SByte)(object)factor);
+ product.register.sbyte_7 = (SByte)(value.register.sbyte_7 * (SByte)(object)factor);
+ product.register.sbyte_8 = (SByte)(value.register.sbyte_8 * (SByte)(object)factor);
+ product.register.sbyte_9 = (SByte)(value.register.sbyte_9 * (SByte)(object)factor);
+ product.register.sbyte_10 = (SByte)(value.register.sbyte_10 * (SByte)(object)factor);
+ product.register.sbyte_11 = (SByte)(value.register.sbyte_11 * (SByte)(object)factor);
+ product.register.sbyte_12 = (SByte)(value.register.sbyte_12 * (SByte)(object)factor);
+ product.register.sbyte_13 = (SByte)(value.register.sbyte_13 * (SByte)(object)factor);
+ product.register.sbyte_14 = (SByte)(value.register.sbyte_14 * (SByte)(object)factor);
+ product.register.sbyte_15 = (SByte)(value.register.sbyte_15 * (SByte)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ product.register.uint16_0 = (UInt16)(value.register.uint16_0 * (UInt16)(object)factor);
+ product.register.uint16_1 = (UInt16)(value.register.uint16_1 * (UInt16)(object)factor);
+ product.register.uint16_2 = (UInt16)(value.register.uint16_2 * (UInt16)(object)factor);
+ product.register.uint16_3 = (UInt16)(value.register.uint16_3 * (UInt16)(object)factor);
+ product.register.uint16_4 = (UInt16)(value.register.uint16_4 * (UInt16)(object)factor);
+ product.register.uint16_5 = (UInt16)(value.register.uint16_5 * (UInt16)(object)factor);
+ product.register.uint16_6 = (UInt16)(value.register.uint16_6 * (UInt16)(object)factor);
+ product.register.uint16_7 = (UInt16)(value.register.uint16_7 * (UInt16)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ product.register.int16_0 = (Int16)(value.register.int16_0 * (Int16)(object)factor);
+ product.register.int16_1 = (Int16)(value.register.int16_1 * (Int16)(object)factor);
+ product.register.int16_2 = (Int16)(value.register.int16_2 * (Int16)(object)factor);
+ product.register.int16_3 = (Int16)(value.register.int16_3 * (Int16)(object)factor);
+ product.register.int16_4 = (Int16)(value.register.int16_4 * (Int16)(object)factor);
+ product.register.int16_5 = (Int16)(value.register.int16_5 * (Int16)(object)factor);
+ product.register.int16_6 = (Int16)(value.register.int16_6 * (Int16)(object)factor);
+ product.register.int16_7 = (Int16)(value.register.int16_7 * (Int16)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ product.register.uint32_0 = (UInt32)(value.register.uint32_0 * (UInt32)(object)factor);
+ product.register.uint32_1 = (UInt32)(value.register.uint32_1 * (UInt32)(object)factor);
+ product.register.uint32_2 = (UInt32)(value.register.uint32_2 * (UInt32)(object)factor);
+ product.register.uint32_3 = (UInt32)(value.register.uint32_3 * (UInt32)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ product.register.int32_0 = (Int32)(value.register.int32_0 * (Int32)(object)factor);
+ product.register.int32_1 = (Int32)(value.register.int32_1 * (Int32)(object)factor);
+ product.register.int32_2 = (Int32)(value.register.int32_2 * (Int32)(object)factor);
+ product.register.int32_3 = (Int32)(value.register.int32_3 * (Int32)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ product.register.uint64_0 = (UInt64)(value.register.uint64_0 * (UInt64)(object)factor);
+ product.register.uint64_1 = (UInt64)(value.register.uint64_1 * (UInt64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ product.register.int64_0 = (Int64)(value.register.int64_0 * (Int64)(object)factor);
+ product.register.int64_1 = (Int64)(value.register.int64_1 * (Int64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ product.register.single_0 = (Single)(value.register.single_0 * (Single)(object)factor);
+ product.register.single_1 = (Single)(value.register.single_1 * (Single)(object)factor);
+ product.register.single_2 = (Single)(value.register.single_2 * (Single)(object)factor);
+ product.register.single_3 = (Single)(value.register.single_3 * (Single)(object)factor);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ product.register.double_0 = (Double)(value.register.double_0 * (Double)(object)factor);
+ product.register.double_1 = (Double)(value.register.double_1 * (Double)(object)factor);
+ }
+ return product;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Multiplies a vector by the given scalar.
+ /// </summary>
+ /// <param name="factor">The scalar value.</param>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The scaled vector.</returns>
+ public static Vector<T> operator *(T factor, Vector<T> value)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ return new Vector<T>(factor) * value;
+ }
+ else
+ {
+ Vector<T> product = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ product.register.byte_0 = (Byte)(value.register.byte_0 * (Byte)(object)factor);
+ product.register.byte_1 = (Byte)(value.register.byte_1 * (Byte)(object)factor);
+ product.register.byte_2 = (Byte)(value.register.byte_2 * (Byte)(object)factor);
+ product.register.byte_3 = (Byte)(value.register.byte_3 * (Byte)(object)factor);
+ product.register.byte_4 = (Byte)(value.register.byte_4 * (Byte)(object)factor);
+ product.register.byte_5 = (Byte)(value.register.byte_5 * (Byte)(object)factor);
+ product.register.byte_6 = (Byte)(value.register.byte_6 * (Byte)(object)factor);
+ product.register.byte_7 = (Byte)(value.register.byte_7 * (Byte)(object)factor);
+ product.register.byte_8 = (Byte)(value.register.byte_8 * (Byte)(object)factor);
+ product.register.byte_9 = (Byte)(value.register.byte_9 * (Byte)(object)factor);
+ product.register.byte_10 = (Byte)(value.register.byte_10 * (Byte)(object)factor);
+ product.register.byte_11 = (Byte)(value.register.byte_11 * (Byte)(object)factor);
+ product.register.byte_12 = (Byte)(value.register.byte_12 * (Byte)(object)factor);
+ product.register.byte_13 = (Byte)(value.register.byte_13 * (Byte)(object)factor);
+ product.register.byte_14 = (Byte)(value.register.byte_14 * (Byte)(object)factor);
+ product.register.byte_15 = (Byte)(value.register.byte_15 * (Byte)(object)factor);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ product.register.sbyte_0 = (SByte)(value.register.sbyte_0 * (SByte)(object)factor);
+ product.register.sbyte_1 = (SByte)(value.register.sbyte_1 * (SByte)(object)factor);
+ product.register.sbyte_2 = (SByte)(value.register.sbyte_2 * (SByte)(object)factor);
+ product.register.sbyte_3 = (SByte)(value.register.sbyte_3 * (SByte)(object)factor);
+ product.register.sbyte_4 = (SByte)(value.register.sbyte_4 * (SByte)(object)factor);
+ product.register.sbyte_5 = (SByte)(value.register.sbyte_5 * (SByte)(object)factor);
+ product.register.sbyte_6 = (SByte)(value.register.sbyte_6 * (SByte)(object)factor);
+ product.register.sbyte_7 = (SByte)(value.register.sbyte_7 * (SByte)(object)factor);
+ product.register.sbyte_8 = (SByte)(value.register.sbyte_8 * (SByte)(object)factor);
+ product.register.sbyte_9 = (SByte)(value.register.sbyte_9 * (SByte)(object)factor);
+ product.register.sbyte_10 = (SByte)(value.register.sbyte_10 * (SByte)(object)factor);
+ product.register.sbyte_11 = (SByte)(value.register.sbyte_11 * (SByte)(object)factor);
+ product.register.sbyte_12 = (SByte)(value.register.sbyte_12 * (SByte)(object)factor);
+ product.register.sbyte_13 = (SByte)(value.register.sbyte_13 * (SByte)(object)factor);
+ product.register.sbyte_14 = (SByte)(value.register.sbyte_14 * (SByte)(object)factor);
+ product.register.sbyte_15 = (SByte)(value.register.sbyte_15 * (SByte)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ product.register.uint16_0 = (UInt16)(value.register.uint16_0 * (UInt16)(object)factor);
+ product.register.uint16_1 = (UInt16)(value.register.uint16_1 * (UInt16)(object)factor);
+ product.register.uint16_2 = (UInt16)(value.register.uint16_2 * (UInt16)(object)factor);
+ product.register.uint16_3 = (UInt16)(value.register.uint16_3 * (UInt16)(object)factor);
+ product.register.uint16_4 = (UInt16)(value.register.uint16_4 * (UInt16)(object)factor);
+ product.register.uint16_5 = (UInt16)(value.register.uint16_5 * (UInt16)(object)factor);
+ product.register.uint16_6 = (UInt16)(value.register.uint16_6 * (UInt16)(object)factor);
+ product.register.uint16_7 = (UInt16)(value.register.uint16_7 * (UInt16)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ product.register.int16_0 = (Int16)(value.register.int16_0 * (Int16)(object)factor);
+ product.register.int16_1 = (Int16)(value.register.int16_1 * (Int16)(object)factor);
+ product.register.int16_2 = (Int16)(value.register.int16_2 * (Int16)(object)factor);
+ product.register.int16_3 = (Int16)(value.register.int16_3 * (Int16)(object)factor);
+ product.register.int16_4 = (Int16)(value.register.int16_4 * (Int16)(object)factor);
+ product.register.int16_5 = (Int16)(value.register.int16_5 * (Int16)(object)factor);
+ product.register.int16_6 = (Int16)(value.register.int16_6 * (Int16)(object)factor);
+ product.register.int16_7 = (Int16)(value.register.int16_7 * (Int16)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ product.register.uint32_0 = (UInt32)(value.register.uint32_0 * (UInt32)(object)factor);
+ product.register.uint32_1 = (UInt32)(value.register.uint32_1 * (UInt32)(object)factor);
+ product.register.uint32_2 = (UInt32)(value.register.uint32_2 * (UInt32)(object)factor);
+ product.register.uint32_3 = (UInt32)(value.register.uint32_3 * (UInt32)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ product.register.int32_0 = (Int32)(value.register.int32_0 * (Int32)(object)factor);
+ product.register.int32_1 = (Int32)(value.register.int32_1 * (Int32)(object)factor);
+ product.register.int32_2 = (Int32)(value.register.int32_2 * (Int32)(object)factor);
+ product.register.int32_3 = (Int32)(value.register.int32_3 * (Int32)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ product.register.uint64_0 = (UInt64)(value.register.uint64_0 * (UInt64)(object)factor);
+ product.register.uint64_1 = (UInt64)(value.register.uint64_1 * (UInt64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ product.register.int64_0 = (Int64)(value.register.int64_0 * (Int64)(object)factor);
+ product.register.int64_1 = (Int64)(value.register.int64_1 * (Int64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ product.register.single_0 = (Single)(value.register.single_0 * (Single)(object)factor);
+ product.register.single_1 = (Single)(value.register.single_1 * (Single)(object)factor);
+ product.register.single_2 = (Single)(value.register.single_2 * (Single)(object)factor);
+ product.register.single_3 = (Single)(value.register.single_3 * (Single)(object)factor);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ product.register.double_0 = (Double)(value.register.double_0 * (Double)(object)factor);
+ product.register.double_1 = (Double)(value.register.double_1 * (Double)(object)factor);
+ }
+ return product;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Divides the first vector by the second.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The vector resulting from the division.</returns>
+ public static unsafe Vector<T> operator /(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> quotient = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ quotient.register.byte_0 = (Byte)(left.register.byte_0 / right.register.byte_0);
+ quotient.register.byte_1 = (Byte)(left.register.byte_1 / right.register.byte_1);
+ quotient.register.byte_2 = (Byte)(left.register.byte_2 / right.register.byte_2);
+ quotient.register.byte_3 = (Byte)(left.register.byte_3 / right.register.byte_3);
+ quotient.register.byte_4 = (Byte)(left.register.byte_4 / right.register.byte_4);
+ quotient.register.byte_5 = (Byte)(left.register.byte_5 / right.register.byte_5);
+ quotient.register.byte_6 = (Byte)(left.register.byte_6 / right.register.byte_6);
+ quotient.register.byte_7 = (Byte)(left.register.byte_7 / right.register.byte_7);
+ quotient.register.byte_8 = (Byte)(left.register.byte_8 / right.register.byte_8);
+ quotient.register.byte_9 = (Byte)(left.register.byte_9 / right.register.byte_9);
+ quotient.register.byte_10 = (Byte)(left.register.byte_10 / right.register.byte_10);
+ quotient.register.byte_11 = (Byte)(left.register.byte_11 / right.register.byte_11);
+ quotient.register.byte_12 = (Byte)(left.register.byte_12 / right.register.byte_12);
+ quotient.register.byte_13 = (Byte)(left.register.byte_13 / right.register.byte_13);
+ quotient.register.byte_14 = (Byte)(left.register.byte_14 / right.register.byte_14);
+ quotient.register.byte_15 = (Byte)(left.register.byte_15 / right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ quotient.register.sbyte_0 = (SByte)(left.register.sbyte_0 / right.register.sbyte_0);
+ quotient.register.sbyte_1 = (SByte)(left.register.sbyte_1 / right.register.sbyte_1);
+ quotient.register.sbyte_2 = (SByte)(left.register.sbyte_2 / right.register.sbyte_2);
+ quotient.register.sbyte_3 = (SByte)(left.register.sbyte_3 / right.register.sbyte_3);
+ quotient.register.sbyte_4 = (SByte)(left.register.sbyte_4 / right.register.sbyte_4);
+ quotient.register.sbyte_5 = (SByte)(left.register.sbyte_5 / right.register.sbyte_5);
+ quotient.register.sbyte_6 = (SByte)(left.register.sbyte_6 / right.register.sbyte_6);
+ quotient.register.sbyte_7 = (SByte)(left.register.sbyte_7 / right.register.sbyte_7);
+ quotient.register.sbyte_8 = (SByte)(left.register.sbyte_8 / right.register.sbyte_8);
+ quotient.register.sbyte_9 = (SByte)(left.register.sbyte_9 / right.register.sbyte_9);
+ quotient.register.sbyte_10 = (SByte)(left.register.sbyte_10 / right.register.sbyte_10);
+ quotient.register.sbyte_11 = (SByte)(left.register.sbyte_11 / right.register.sbyte_11);
+ quotient.register.sbyte_12 = (SByte)(left.register.sbyte_12 / right.register.sbyte_12);
+ quotient.register.sbyte_13 = (SByte)(left.register.sbyte_13 / right.register.sbyte_13);
+ quotient.register.sbyte_14 = (SByte)(left.register.sbyte_14 / right.register.sbyte_14);
+ quotient.register.sbyte_15 = (SByte)(left.register.sbyte_15 / right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ quotient.register.uint16_0 = (UInt16)(left.register.uint16_0 / right.register.uint16_0);
+ quotient.register.uint16_1 = (UInt16)(left.register.uint16_1 / right.register.uint16_1);
+ quotient.register.uint16_2 = (UInt16)(left.register.uint16_2 / right.register.uint16_2);
+ quotient.register.uint16_3 = (UInt16)(left.register.uint16_3 / right.register.uint16_3);
+ quotient.register.uint16_4 = (UInt16)(left.register.uint16_4 / right.register.uint16_4);
+ quotient.register.uint16_5 = (UInt16)(left.register.uint16_5 / right.register.uint16_5);
+ quotient.register.uint16_6 = (UInt16)(left.register.uint16_6 / right.register.uint16_6);
+ quotient.register.uint16_7 = (UInt16)(left.register.uint16_7 / right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ quotient.register.int16_0 = (Int16)(left.register.int16_0 / right.register.int16_0);
+ quotient.register.int16_1 = (Int16)(left.register.int16_1 / right.register.int16_1);
+ quotient.register.int16_2 = (Int16)(left.register.int16_2 / right.register.int16_2);
+ quotient.register.int16_3 = (Int16)(left.register.int16_3 / right.register.int16_3);
+ quotient.register.int16_4 = (Int16)(left.register.int16_4 / right.register.int16_4);
+ quotient.register.int16_5 = (Int16)(left.register.int16_5 / right.register.int16_5);
+ quotient.register.int16_6 = (Int16)(left.register.int16_6 / right.register.int16_6);
+ quotient.register.int16_7 = (Int16)(left.register.int16_7 / right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ quotient.register.uint32_0 = (UInt32)(left.register.uint32_0 / right.register.uint32_0);
+ quotient.register.uint32_1 = (UInt32)(left.register.uint32_1 / right.register.uint32_1);
+ quotient.register.uint32_2 = (UInt32)(left.register.uint32_2 / right.register.uint32_2);
+ quotient.register.uint32_3 = (UInt32)(left.register.uint32_3 / right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ quotient.register.int32_0 = (Int32)(left.register.int32_0 / right.register.int32_0);
+ quotient.register.int32_1 = (Int32)(left.register.int32_1 / right.register.int32_1);
+ quotient.register.int32_2 = (Int32)(left.register.int32_2 / right.register.int32_2);
+ quotient.register.int32_3 = (Int32)(left.register.int32_3 / right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ quotient.register.uint64_0 = (UInt64)(left.register.uint64_0 / right.register.uint64_0);
+ quotient.register.uint64_1 = (UInt64)(left.register.uint64_1 / right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ quotient.register.int64_0 = (Int64)(left.register.int64_0 / right.register.int64_0);
+ quotient.register.int64_1 = (Int64)(left.register.int64_1 / right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ quotient.register.single_0 = (Single)(left.register.single_0 / right.register.single_0);
+ quotient.register.single_1 = (Single)(left.register.single_1 / right.register.single_1);
+ quotient.register.single_2 = (Single)(left.register.single_2 / right.register.single_2);
+ quotient.register.single_3 = (Single)(left.register.single_3 / right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ quotient.register.double_0 = (Double)(left.register.double_0 / right.register.double_0);
+ quotient.register.double_1 = (Double)(left.register.double_1 / right.register.double_1);
+ }
+ return quotient;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Negates a given vector.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The negated vector.</returns>
+ public static Vector<T> operator -(Vector<T> value)
+ {
+ return Zero - value;
+ }
+ #endregion Arithmetic Operators
+
+ #region Bitwise Operators
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [JitIntrinsic]
+ public static unsafe Vector<T> operator &(Vector<T> left, Vector<T> right)
+ {
+ Vector<T> result = new Vector<T>();
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ Int64* resultBase = &result.register.int64_0;
+ Int64* leftBase = &left.register.int64_0;
+ Int64* rightBase = &right.register.int64_0;
+ for (int g = 0; g < Vector<Int64>.Count; g++)
+ {
+ resultBase[g] = leftBase[g] & rightBase[g];
+ }
+ }
+ else
+ {
+ result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
+ result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [JitIntrinsic]
+ public static unsafe Vector<T> operator |(Vector<T> left, Vector<T> right)
+ {
+ Vector<T> result = new Vector<T>();
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ Int64* resultBase = &result.register.int64_0;
+ Int64* leftBase = &left.register.int64_0;
+ Int64* rightBase = &right.register.int64_0;
+ for (int g = 0; g < Vector<Int64>.Count; g++)
+ {
+ resultBase[g] = leftBase[g] | rightBase[g];
+ }
+ }
+ else
+ {
+ result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
+ result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [JitIntrinsic]
+ public static unsafe Vector<T> operator ^(Vector<T> left, Vector<T> right)
+ {
+ Vector<T> result = new Vector<T>();
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ Int64* resultBase = &result.register.int64_0;
+ Int64* leftBase = &left.register.int64_0;
+ Int64* rightBase = &right.register.int64_0;
+ for (int g = 0; g < Vector<Int64>.Count; g++)
+ {
+ resultBase[g] = leftBase[g] ^ rightBase[g];
+ }
+ }
+ else
+ {
+ result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
+ result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The one's complement vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> operator ~(Vector<T> value)
+ {
+ return allOnes ^ value;
+ }
+ #endregion Bitwise Operators
+
+ #region Logical Operators
+ /// <summary>
+ /// Returns a boolean indicating whether each pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The first vector to compare.</param>
+ /// <returns>True if all elements are equal; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool operator ==(Vector<T> left, Vector<T> right)
+ {
+ return left.Equals(right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any element pairs are equal; False if no element pairs are equal.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool operator !=(Vector<T> left, Vector<T> right)
+ {
+ return !(left == right);
+ }
+ #endregion Logical Operators
+
+ #region Conversions
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Byte>(Vector<T> value)
+ {
+ return new Vector<Byte>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<SByte>(Vector<T> value)
+ {
+ return new Vector<SByte>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<UInt16>(Vector<T> value)
+ {
+ return new Vector<UInt16>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Int16>(Vector<T> value)
+ {
+ return new Vector<Int16>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<UInt32>(Vector<T> value)
+ {
+ return new Vector<UInt32>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Int32>(Vector<T> value)
+ {
+ return new Vector<Int32>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<UInt64>(Vector<T> value)
+ {
+ return new Vector<UInt64>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Int64>(Vector<T> value)
+ {
+ return new Vector<Int64>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Single>(Vector<T> value)
+ {
+ return new Vector<Single>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Double>(Vector<T> value)
+ {
+ return new Vector<Double>(ref value.register);
+ }
+
+ #endregion Conversions
+
+ #region Internal Comparison Methods
+ [JitIntrinsic]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe Vector<T> Equals(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Register register = new Register();
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = left.register.byte_0 == right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_1 = left.register.byte_1 == right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_2 = left.register.byte_2 == right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_3 = left.register.byte_3 == right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_4 = left.register.byte_4 == right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_5 = left.register.byte_5 == right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_6 = left.register.byte_6 == right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_7 = left.register.byte_7 == right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_8 = left.register.byte_8 == right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_9 = left.register.byte_9 == right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_10 = left.register.byte_10 == right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_11 = left.register.byte_11 == right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_12 = left.register.byte_12 == right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_13 = left.register.byte_13 == right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_14 = left.register.byte_14 == right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_15 = left.register.byte_15 == right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = left.register.sbyte_0 == right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_1 = left.register.sbyte_1 == right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_2 = left.register.sbyte_2 == right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_3 = left.register.sbyte_3 == right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_4 = left.register.sbyte_4 == right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_5 = left.register.sbyte_5 == right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_6 = left.register.sbyte_6 == right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_7 = left.register.sbyte_7 == right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_8 = left.register.sbyte_8 == right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_9 = left.register.sbyte_9 == right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_10 = left.register.sbyte_10 == right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_11 = left.register.sbyte_11 == right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_12 = left.register.sbyte_12 == right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_13 = left.register.sbyte_13 == right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_14 = left.register.sbyte_14 == right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_15 = left.register.sbyte_15 == right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = left.register.uint16_0 == right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_1 = left.register.uint16_1 == right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_2 = left.register.uint16_2 == right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_3 = left.register.uint16_3 == right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_4 = left.register.uint16_4 == right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_5 = left.register.uint16_5 == right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_6 = left.register.uint16_6 == right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_7 = left.register.uint16_7 == right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = left.register.int16_0 == right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_1 = left.register.int16_1 == right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_2 = left.register.int16_2 == right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_3 = left.register.int16_3 == right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_4 = left.register.int16_4 == right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_5 = left.register.int16_5 == right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_6 = left.register.int16_6 == right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_7 = left.register.int16_7 == right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = left.register.uint32_0 == right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_1 = left.register.uint32_1 == right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_2 = left.register.uint32_2 == right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_3 = left.register.uint32_3 == right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = left.register.int32_0 == right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_1 = left.register.int32_1 == right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_2 = left.register.int32_2 == right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_3 = left.register.int32_3 == right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = left.register.uint64_0 == right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ register.uint64_1 = left.register.uint64_1 == right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = left.register.int64_0 == right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ register.int64_1 = left.register.int64_1 == right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = left.register.single_0 == right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_1 = left.register.single_1 == right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_2 = left.register.single_2 == right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_3 = left.register.single_3 == right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = left.register.double_0 == right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ register.double_1 = left.register.double_1 == right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ return new Vector<T>(ref register);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe Vector<T> LessThan(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Register register = new Register();
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = left.register.byte_0 < right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_1 = left.register.byte_1 < right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_2 = left.register.byte_2 < right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_3 = left.register.byte_3 < right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_4 = left.register.byte_4 < right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_5 = left.register.byte_5 < right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_6 = left.register.byte_6 < right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_7 = left.register.byte_7 < right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_8 = left.register.byte_8 < right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_9 = left.register.byte_9 < right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_10 = left.register.byte_10 < right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_11 = left.register.byte_11 < right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_12 = left.register.byte_12 < right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_13 = left.register.byte_13 < right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_14 = left.register.byte_14 < right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_15 = left.register.byte_15 < right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = left.register.sbyte_0 < right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_1 = left.register.sbyte_1 < right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_2 = left.register.sbyte_2 < right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_3 = left.register.sbyte_3 < right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_4 = left.register.sbyte_4 < right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_5 = left.register.sbyte_5 < right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_6 = left.register.sbyte_6 < right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_7 = left.register.sbyte_7 < right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_8 = left.register.sbyte_8 < right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_9 = left.register.sbyte_9 < right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_10 = left.register.sbyte_10 < right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_11 = left.register.sbyte_11 < right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_12 = left.register.sbyte_12 < right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_13 = left.register.sbyte_13 < right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_14 = left.register.sbyte_14 < right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_15 = left.register.sbyte_15 < right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = left.register.uint16_0 < right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_1 = left.register.uint16_1 < right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_2 = left.register.uint16_2 < right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_3 = left.register.uint16_3 < right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_4 = left.register.uint16_4 < right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_5 = left.register.uint16_5 < right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_6 = left.register.uint16_6 < right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_7 = left.register.uint16_7 < right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = left.register.int16_0 < right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_1 = left.register.int16_1 < right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_2 = left.register.int16_2 < right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_3 = left.register.int16_3 < right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_4 = left.register.int16_4 < right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_5 = left.register.int16_5 < right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_6 = left.register.int16_6 < right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_7 = left.register.int16_7 < right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = left.register.uint32_0 < right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_1 = left.register.uint32_1 < right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_2 = left.register.uint32_2 < right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_3 = left.register.uint32_3 < right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = left.register.int32_0 < right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_1 = left.register.int32_1 < right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_2 = left.register.int32_2 < right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_3 = left.register.int32_3 < right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = left.register.uint64_0 < right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ register.uint64_1 = left.register.uint64_1 < right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = left.register.int64_0 < right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ register.int64_1 = left.register.int64_1 < right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = left.register.single_0 < right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_1 = left.register.single_1 < right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_2 = left.register.single_2 < right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_3 = left.register.single_3 < right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = left.register.double_0 < right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ register.double_1 = left.register.double_1 < right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ return new Vector<T>(ref register);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe Vector<T> GreaterThan(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Register register = new Register();
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = left.register.byte_0 > right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_1 = left.register.byte_1 > right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_2 = left.register.byte_2 > right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_3 = left.register.byte_3 > right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_4 = left.register.byte_4 > right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_5 = left.register.byte_5 > right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_6 = left.register.byte_6 > right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_7 = left.register.byte_7 > right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_8 = left.register.byte_8 > right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_9 = left.register.byte_9 > right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_10 = left.register.byte_10 > right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_11 = left.register.byte_11 > right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_12 = left.register.byte_12 > right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_13 = left.register.byte_13 > right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_14 = left.register.byte_14 > right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_15 = left.register.byte_15 > right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = left.register.sbyte_0 > right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_1 = left.register.sbyte_1 > right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_2 = left.register.sbyte_2 > right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_3 = left.register.sbyte_3 > right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_4 = left.register.sbyte_4 > right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_5 = left.register.sbyte_5 > right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_6 = left.register.sbyte_6 > right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_7 = left.register.sbyte_7 > right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_8 = left.register.sbyte_8 > right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_9 = left.register.sbyte_9 > right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_10 = left.register.sbyte_10 > right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_11 = left.register.sbyte_11 > right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_12 = left.register.sbyte_12 > right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_13 = left.register.sbyte_13 > right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_14 = left.register.sbyte_14 > right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_15 = left.register.sbyte_15 > right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = left.register.uint16_0 > right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_1 = left.register.uint16_1 > right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_2 = left.register.uint16_2 > right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_3 = left.register.uint16_3 > right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_4 = left.register.uint16_4 > right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_5 = left.register.uint16_5 > right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_6 = left.register.uint16_6 > right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_7 = left.register.uint16_7 > right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = left.register.int16_0 > right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_1 = left.register.int16_1 > right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_2 = left.register.int16_2 > right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_3 = left.register.int16_3 > right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_4 = left.register.int16_4 > right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_5 = left.register.int16_5 > right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_6 = left.register.int16_6 > right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_7 = left.register.int16_7 > right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = left.register.uint32_0 > right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_1 = left.register.uint32_1 > right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_2 = left.register.uint32_2 > right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_3 = left.register.uint32_3 > right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = left.register.int32_0 > right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_1 = left.register.int32_1 > right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_2 = left.register.int32_2 > right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_3 = left.register.int32_3 > right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = left.register.uint64_0 > right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ register.uint64_1 = left.register.uint64_1 > right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = left.register.int64_0 > right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ register.int64_1 = left.register.int64_1 > right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = left.register.single_0 > right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_1 = left.register.single_1 > right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_2 = left.register.single_2 > right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_3 = left.register.single_3 > right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = left.register.double_0 > right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ register.double_1 = left.register.double_1 > right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ return new Vector<T>(ref register);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static Vector<T> GreaterThanOrEqual(Vector<T> left, Vector<T> right)
+ {
+ return Equals(left, right) | GreaterThan(left, right);
+ }
+
+ [JitIntrinsic]
+ internal static Vector<T> LessThanOrEqual(Vector<T> left, Vector<T> right)
+ {
+ return Equals(left, right) | LessThan(left, right);
+ }
+
+ [JitIntrinsic]
+ internal static Vector<T> ConditionalSelect(Vector<T> condition, Vector<T> left, Vector<T> right)
+ {
+ return (left & condition) | (Vector.AndNot(right, condition));
+ }
+ #endregion Comparison Methods
+
+ #region Internal Math Methods
+ [JitIntrinsic]
+ internal static unsafe Vector<T> Abs(Vector<T> value)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return value;
+ }
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)(Math.Abs((SByte)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)(Math.Abs((Int16)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)(Math.Abs((Int32)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)(Math.Abs((Int64)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)(Math.Abs((Single)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)(Math.Abs((Double)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(SByte))
+ {
+ value.register.sbyte_0 = (SByte)(Math.Abs(value.register.sbyte_0));
+ value.register.sbyte_1 = (SByte)(Math.Abs(value.register.sbyte_1));
+ value.register.sbyte_2 = (SByte)(Math.Abs(value.register.sbyte_2));
+ value.register.sbyte_3 = (SByte)(Math.Abs(value.register.sbyte_3));
+ value.register.sbyte_4 = (SByte)(Math.Abs(value.register.sbyte_4));
+ value.register.sbyte_5 = (SByte)(Math.Abs(value.register.sbyte_5));
+ value.register.sbyte_6 = (SByte)(Math.Abs(value.register.sbyte_6));
+ value.register.sbyte_7 = (SByte)(Math.Abs(value.register.sbyte_7));
+ value.register.sbyte_8 = (SByte)(Math.Abs(value.register.sbyte_8));
+ value.register.sbyte_9 = (SByte)(Math.Abs(value.register.sbyte_9));
+ value.register.sbyte_10 = (SByte)(Math.Abs(value.register.sbyte_10));
+ value.register.sbyte_11 = (SByte)(Math.Abs(value.register.sbyte_11));
+ value.register.sbyte_12 = (SByte)(Math.Abs(value.register.sbyte_12));
+ value.register.sbyte_13 = (SByte)(Math.Abs(value.register.sbyte_13));
+ value.register.sbyte_14 = (SByte)(Math.Abs(value.register.sbyte_14));
+ value.register.sbyte_15 = (SByte)(Math.Abs(value.register.sbyte_15));
+ return value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ value.register.int16_0 = (Int16)(Math.Abs(value.register.int16_0));
+ value.register.int16_1 = (Int16)(Math.Abs(value.register.int16_1));
+ value.register.int16_2 = (Int16)(Math.Abs(value.register.int16_2));
+ value.register.int16_3 = (Int16)(Math.Abs(value.register.int16_3));
+ value.register.int16_4 = (Int16)(Math.Abs(value.register.int16_4));
+ value.register.int16_5 = (Int16)(Math.Abs(value.register.int16_5));
+ value.register.int16_6 = (Int16)(Math.Abs(value.register.int16_6));
+ value.register.int16_7 = (Int16)(Math.Abs(value.register.int16_7));
+ return value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ value.register.int32_0 = (Int32)(Math.Abs(value.register.int32_0));
+ value.register.int32_1 = (Int32)(Math.Abs(value.register.int32_1));
+ value.register.int32_2 = (Int32)(Math.Abs(value.register.int32_2));
+ value.register.int32_3 = (Int32)(Math.Abs(value.register.int32_3));
+ return value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ value.register.int64_0 = (Int64)(Math.Abs(value.register.int64_0));
+ value.register.int64_1 = (Int64)(Math.Abs(value.register.int64_1));
+ return value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ value.register.single_0 = (Single)(Math.Abs(value.register.single_0));
+ value.register.single_1 = (Single)(Math.Abs(value.register.single_1));
+ value.register.single_2 = (Single)(Math.Abs(value.register.single_2));
+ value.register.single_3 = (Single)(Math.Abs(value.register.single_3));
+ return value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ value.register.double_0 = (Double)(Math.Abs(value.register.double_0));
+ value.register.double_1 = (Double)(Math.Abs(value.register.double_1));
+ return value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static unsafe Vector<T> Min(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Byte)(object)left[g] : (Byte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (SByte)(object)left[g] : (SByte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (UInt16)(object)left[g] : (UInt16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Int16)(object)left[g] : (Int16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (UInt32)(object)left[g] : (UInt32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Int32)(object)left[g] : (Int32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (UInt64)(object)left[g] : (UInt64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Int64)(object)left[g] : (Int64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Single)(object)left[g] : (Single)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Double)(object)left[g] : (Double)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> vec = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ vec.register.byte_0 = left.register.byte_0 < right.register.byte_0 ? left.register.byte_0 : right.register.byte_0;
+ vec.register.byte_1 = left.register.byte_1 < right.register.byte_1 ? left.register.byte_1 : right.register.byte_1;
+ vec.register.byte_2 = left.register.byte_2 < right.register.byte_2 ? left.register.byte_2 : right.register.byte_2;
+ vec.register.byte_3 = left.register.byte_3 < right.register.byte_3 ? left.register.byte_3 : right.register.byte_3;
+ vec.register.byte_4 = left.register.byte_4 < right.register.byte_4 ? left.register.byte_4 : right.register.byte_4;
+ vec.register.byte_5 = left.register.byte_5 < right.register.byte_5 ? left.register.byte_5 : right.register.byte_5;
+ vec.register.byte_6 = left.register.byte_6 < right.register.byte_6 ? left.register.byte_6 : right.register.byte_6;
+ vec.register.byte_7 = left.register.byte_7 < right.register.byte_7 ? left.register.byte_7 : right.register.byte_7;
+ vec.register.byte_8 = left.register.byte_8 < right.register.byte_8 ? left.register.byte_8 : right.register.byte_8;
+ vec.register.byte_9 = left.register.byte_9 < right.register.byte_9 ? left.register.byte_9 : right.register.byte_9;
+ vec.register.byte_10 = left.register.byte_10 < right.register.byte_10 ? left.register.byte_10 : right.register.byte_10;
+ vec.register.byte_11 = left.register.byte_11 < right.register.byte_11 ? left.register.byte_11 : right.register.byte_11;
+ vec.register.byte_12 = left.register.byte_12 < right.register.byte_12 ? left.register.byte_12 : right.register.byte_12;
+ vec.register.byte_13 = left.register.byte_13 < right.register.byte_13 ? left.register.byte_13 : right.register.byte_13;
+ vec.register.byte_14 = left.register.byte_14 < right.register.byte_14 ? left.register.byte_14 : right.register.byte_14;
+ vec.register.byte_15 = left.register.byte_15 < right.register.byte_15 ? left.register.byte_15 : right.register.byte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ vec.register.sbyte_0 = left.register.sbyte_0 < right.register.sbyte_0 ? left.register.sbyte_0 : right.register.sbyte_0;
+ vec.register.sbyte_1 = left.register.sbyte_1 < right.register.sbyte_1 ? left.register.sbyte_1 : right.register.sbyte_1;
+ vec.register.sbyte_2 = left.register.sbyte_2 < right.register.sbyte_2 ? left.register.sbyte_2 : right.register.sbyte_2;
+ vec.register.sbyte_3 = left.register.sbyte_3 < right.register.sbyte_3 ? left.register.sbyte_3 : right.register.sbyte_3;
+ vec.register.sbyte_4 = left.register.sbyte_4 < right.register.sbyte_4 ? left.register.sbyte_4 : right.register.sbyte_4;
+ vec.register.sbyte_5 = left.register.sbyte_5 < right.register.sbyte_5 ? left.register.sbyte_5 : right.register.sbyte_5;
+ vec.register.sbyte_6 = left.register.sbyte_6 < right.register.sbyte_6 ? left.register.sbyte_6 : right.register.sbyte_6;
+ vec.register.sbyte_7 = left.register.sbyte_7 < right.register.sbyte_7 ? left.register.sbyte_7 : right.register.sbyte_7;
+ vec.register.sbyte_8 = left.register.sbyte_8 < right.register.sbyte_8 ? left.register.sbyte_8 : right.register.sbyte_8;
+ vec.register.sbyte_9 = left.register.sbyte_9 < right.register.sbyte_9 ? left.register.sbyte_9 : right.register.sbyte_9;
+ vec.register.sbyte_10 = left.register.sbyte_10 < right.register.sbyte_10 ? left.register.sbyte_10 : right.register.sbyte_10;
+ vec.register.sbyte_11 = left.register.sbyte_11 < right.register.sbyte_11 ? left.register.sbyte_11 : right.register.sbyte_11;
+ vec.register.sbyte_12 = left.register.sbyte_12 < right.register.sbyte_12 ? left.register.sbyte_12 : right.register.sbyte_12;
+ vec.register.sbyte_13 = left.register.sbyte_13 < right.register.sbyte_13 ? left.register.sbyte_13 : right.register.sbyte_13;
+ vec.register.sbyte_14 = left.register.sbyte_14 < right.register.sbyte_14 ? left.register.sbyte_14 : right.register.sbyte_14;
+ vec.register.sbyte_15 = left.register.sbyte_15 < right.register.sbyte_15 ? left.register.sbyte_15 : right.register.sbyte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ vec.register.uint16_0 = left.register.uint16_0 < right.register.uint16_0 ? left.register.uint16_0 : right.register.uint16_0;
+ vec.register.uint16_1 = left.register.uint16_1 < right.register.uint16_1 ? left.register.uint16_1 : right.register.uint16_1;
+ vec.register.uint16_2 = left.register.uint16_2 < right.register.uint16_2 ? left.register.uint16_2 : right.register.uint16_2;
+ vec.register.uint16_3 = left.register.uint16_3 < right.register.uint16_3 ? left.register.uint16_3 : right.register.uint16_3;
+ vec.register.uint16_4 = left.register.uint16_4 < right.register.uint16_4 ? left.register.uint16_4 : right.register.uint16_4;
+ vec.register.uint16_5 = left.register.uint16_5 < right.register.uint16_5 ? left.register.uint16_5 : right.register.uint16_5;
+ vec.register.uint16_6 = left.register.uint16_6 < right.register.uint16_6 ? left.register.uint16_6 : right.register.uint16_6;
+ vec.register.uint16_7 = left.register.uint16_7 < right.register.uint16_7 ? left.register.uint16_7 : right.register.uint16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ vec.register.int16_0 = left.register.int16_0 < right.register.int16_0 ? left.register.int16_0 : right.register.int16_0;
+ vec.register.int16_1 = left.register.int16_1 < right.register.int16_1 ? left.register.int16_1 : right.register.int16_1;
+ vec.register.int16_2 = left.register.int16_2 < right.register.int16_2 ? left.register.int16_2 : right.register.int16_2;
+ vec.register.int16_3 = left.register.int16_3 < right.register.int16_3 ? left.register.int16_3 : right.register.int16_3;
+ vec.register.int16_4 = left.register.int16_4 < right.register.int16_4 ? left.register.int16_4 : right.register.int16_4;
+ vec.register.int16_5 = left.register.int16_5 < right.register.int16_5 ? left.register.int16_5 : right.register.int16_5;
+ vec.register.int16_6 = left.register.int16_6 < right.register.int16_6 ? left.register.int16_6 : right.register.int16_6;
+ vec.register.int16_7 = left.register.int16_7 < right.register.int16_7 ? left.register.int16_7 : right.register.int16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ vec.register.uint32_0 = left.register.uint32_0 < right.register.uint32_0 ? left.register.uint32_0 : right.register.uint32_0;
+ vec.register.uint32_1 = left.register.uint32_1 < right.register.uint32_1 ? left.register.uint32_1 : right.register.uint32_1;
+ vec.register.uint32_2 = left.register.uint32_2 < right.register.uint32_2 ? left.register.uint32_2 : right.register.uint32_2;
+ vec.register.uint32_3 = left.register.uint32_3 < right.register.uint32_3 ? left.register.uint32_3 : right.register.uint32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ vec.register.int32_0 = left.register.int32_0 < right.register.int32_0 ? left.register.int32_0 : right.register.int32_0;
+ vec.register.int32_1 = left.register.int32_1 < right.register.int32_1 ? left.register.int32_1 : right.register.int32_1;
+ vec.register.int32_2 = left.register.int32_2 < right.register.int32_2 ? left.register.int32_2 : right.register.int32_2;
+ vec.register.int32_3 = left.register.int32_3 < right.register.int32_3 ? left.register.int32_3 : right.register.int32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ vec.register.uint64_0 = left.register.uint64_0 < right.register.uint64_0 ? left.register.uint64_0 : right.register.uint64_0;
+ vec.register.uint64_1 = left.register.uint64_1 < right.register.uint64_1 ? left.register.uint64_1 : right.register.uint64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ vec.register.int64_0 = left.register.int64_0 < right.register.int64_0 ? left.register.int64_0 : right.register.int64_0;
+ vec.register.int64_1 = left.register.int64_1 < right.register.int64_1 ? left.register.int64_1 : right.register.int64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ vec.register.single_0 = left.register.single_0 < right.register.single_0 ? left.register.single_0 : right.register.single_0;
+ vec.register.single_1 = left.register.single_1 < right.register.single_1 ? left.register.single_1 : right.register.single_1;
+ vec.register.single_2 = left.register.single_2 < right.register.single_2 ? left.register.single_2 : right.register.single_2;
+ vec.register.single_3 = left.register.single_3 < right.register.single_3 ? left.register.single_3 : right.register.single_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ vec.register.double_0 = left.register.double_0 < right.register.double_0 ? left.register.double_0 : right.register.double_0;
+ vec.register.double_1 = left.register.double_1 < right.register.double_1 ? left.register.double_1 : right.register.double_1;
+ return vec;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static unsafe Vector<T> Max(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Byte)(object)left[g] : (Byte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (SByte)(object)left[g] : (SByte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (UInt16)(object)left[g] : (UInt16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Int16)(object)left[g] : (Int16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (UInt32)(object)left[g] : (UInt32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Int32)(object)left[g] : (Int32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (UInt64)(object)left[g] : (UInt64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Int64)(object)left[g] : (Int64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Single)(object)left[g] : (Single)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Double)(object)left[g] : (Double)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> vec = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ vec.register.byte_0 = left.register.byte_0 > right.register.byte_0 ? left.register.byte_0 : right.register.byte_0;
+ vec.register.byte_1 = left.register.byte_1 > right.register.byte_1 ? left.register.byte_1 : right.register.byte_1;
+ vec.register.byte_2 = left.register.byte_2 > right.register.byte_2 ? left.register.byte_2 : right.register.byte_2;
+ vec.register.byte_3 = left.register.byte_3 > right.register.byte_3 ? left.register.byte_3 : right.register.byte_3;
+ vec.register.byte_4 = left.register.byte_4 > right.register.byte_4 ? left.register.byte_4 : right.register.byte_4;
+ vec.register.byte_5 = left.register.byte_5 > right.register.byte_5 ? left.register.byte_5 : right.register.byte_5;
+ vec.register.byte_6 = left.register.byte_6 > right.register.byte_6 ? left.register.byte_6 : right.register.byte_6;
+ vec.register.byte_7 = left.register.byte_7 > right.register.byte_7 ? left.register.byte_7 : right.register.byte_7;
+ vec.register.byte_8 = left.register.byte_8 > right.register.byte_8 ? left.register.byte_8 : right.register.byte_8;
+ vec.register.byte_9 = left.register.byte_9 > right.register.byte_9 ? left.register.byte_9 : right.register.byte_9;
+ vec.register.byte_10 = left.register.byte_10 > right.register.byte_10 ? left.register.byte_10 : right.register.byte_10;
+ vec.register.byte_11 = left.register.byte_11 > right.register.byte_11 ? left.register.byte_11 : right.register.byte_11;
+ vec.register.byte_12 = left.register.byte_12 > right.register.byte_12 ? left.register.byte_12 : right.register.byte_12;
+ vec.register.byte_13 = left.register.byte_13 > right.register.byte_13 ? left.register.byte_13 : right.register.byte_13;
+ vec.register.byte_14 = left.register.byte_14 > right.register.byte_14 ? left.register.byte_14 : right.register.byte_14;
+ vec.register.byte_15 = left.register.byte_15 > right.register.byte_15 ? left.register.byte_15 : right.register.byte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ vec.register.sbyte_0 = left.register.sbyte_0 > right.register.sbyte_0 ? left.register.sbyte_0 : right.register.sbyte_0;
+ vec.register.sbyte_1 = left.register.sbyte_1 > right.register.sbyte_1 ? left.register.sbyte_1 : right.register.sbyte_1;
+ vec.register.sbyte_2 = left.register.sbyte_2 > right.register.sbyte_2 ? left.register.sbyte_2 : right.register.sbyte_2;
+ vec.register.sbyte_3 = left.register.sbyte_3 > right.register.sbyte_3 ? left.register.sbyte_3 : right.register.sbyte_3;
+ vec.register.sbyte_4 = left.register.sbyte_4 > right.register.sbyte_4 ? left.register.sbyte_4 : right.register.sbyte_4;
+ vec.register.sbyte_5 = left.register.sbyte_5 > right.register.sbyte_5 ? left.register.sbyte_5 : right.register.sbyte_5;
+ vec.register.sbyte_6 = left.register.sbyte_6 > right.register.sbyte_6 ? left.register.sbyte_6 : right.register.sbyte_6;
+ vec.register.sbyte_7 = left.register.sbyte_7 > right.register.sbyte_7 ? left.register.sbyte_7 : right.register.sbyte_7;
+ vec.register.sbyte_8 = left.register.sbyte_8 > right.register.sbyte_8 ? left.register.sbyte_8 : right.register.sbyte_8;
+ vec.register.sbyte_9 = left.register.sbyte_9 > right.register.sbyte_9 ? left.register.sbyte_9 : right.register.sbyte_9;
+ vec.register.sbyte_10 = left.register.sbyte_10 > right.register.sbyte_10 ? left.register.sbyte_10 : right.register.sbyte_10;
+ vec.register.sbyte_11 = left.register.sbyte_11 > right.register.sbyte_11 ? left.register.sbyte_11 : right.register.sbyte_11;
+ vec.register.sbyte_12 = left.register.sbyte_12 > right.register.sbyte_12 ? left.register.sbyte_12 : right.register.sbyte_12;
+ vec.register.sbyte_13 = left.register.sbyte_13 > right.register.sbyte_13 ? left.register.sbyte_13 : right.register.sbyte_13;
+ vec.register.sbyte_14 = left.register.sbyte_14 > right.register.sbyte_14 ? left.register.sbyte_14 : right.register.sbyte_14;
+ vec.register.sbyte_15 = left.register.sbyte_15 > right.register.sbyte_15 ? left.register.sbyte_15 : right.register.sbyte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ vec.register.uint16_0 = left.register.uint16_0 > right.register.uint16_0 ? left.register.uint16_0 : right.register.uint16_0;
+ vec.register.uint16_1 = left.register.uint16_1 > right.register.uint16_1 ? left.register.uint16_1 : right.register.uint16_1;
+ vec.register.uint16_2 = left.register.uint16_2 > right.register.uint16_2 ? left.register.uint16_2 : right.register.uint16_2;
+ vec.register.uint16_3 = left.register.uint16_3 > right.register.uint16_3 ? left.register.uint16_3 : right.register.uint16_3;
+ vec.register.uint16_4 = left.register.uint16_4 > right.register.uint16_4 ? left.register.uint16_4 : right.register.uint16_4;
+ vec.register.uint16_5 = left.register.uint16_5 > right.register.uint16_5 ? left.register.uint16_5 : right.register.uint16_5;
+ vec.register.uint16_6 = left.register.uint16_6 > right.register.uint16_6 ? left.register.uint16_6 : right.register.uint16_6;
+ vec.register.uint16_7 = left.register.uint16_7 > right.register.uint16_7 ? left.register.uint16_7 : right.register.uint16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ vec.register.int16_0 = left.register.int16_0 > right.register.int16_0 ? left.register.int16_0 : right.register.int16_0;
+ vec.register.int16_1 = left.register.int16_1 > right.register.int16_1 ? left.register.int16_1 : right.register.int16_1;
+ vec.register.int16_2 = left.register.int16_2 > right.register.int16_2 ? left.register.int16_2 : right.register.int16_2;
+ vec.register.int16_3 = left.register.int16_3 > right.register.int16_3 ? left.register.int16_3 : right.register.int16_3;
+ vec.register.int16_4 = left.register.int16_4 > right.register.int16_4 ? left.register.int16_4 : right.register.int16_4;
+ vec.register.int16_5 = left.register.int16_5 > right.register.int16_5 ? left.register.int16_5 : right.register.int16_5;
+ vec.register.int16_6 = left.register.int16_6 > right.register.int16_6 ? left.register.int16_6 : right.register.int16_6;
+ vec.register.int16_7 = left.register.int16_7 > right.register.int16_7 ? left.register.int16_7 : right.register.int16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ vec.register.uint32_0 = left.register.uint32_0 > right.register.uint32_0 ? left.register.uint32_0 : right.register.uint32_0;
+ vec.register.uint32_1 = left.register.uint32_1 > right.register.uint32_1 ? left.register.uint32_1 : right.register.uint32_1;
+ vec.register.uint32_2 = left.register.uint32_2 > right.register.uint32_2 ? left.register.uint32_2 : right.register.uint32_2;
+ vec.register.uint32_3 = left.register.uint32_3 > right.register.uint32_3 ? left.register.uint32_3 : right.register.uint32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ vec.register.int32_0 = left.register.int32_0 > right.register.int32_0 ? left.register.int32_0 : right.register.int32_0;
+ vec.register.int32_1 = left.register.int32_1 > right.register.int32_1 ? left.register.int32_1 : right.register.int32_1;
+ vec.register.int32_2 = left.register.int32_2 > right.register.int32_2 ? left.register.int32_2 : right.register.int32_2;
+ vec.register.int32_3 = left.register.int32_3 > right.register.int32_3 ? left.register.int32_3 : right.register.int32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ vec.register.uint64_0 = left.register.uint64_0 > right.register.uint64_0 ? left.register.uint64_0 : right.register.uint64_0;
+ vec.register.uint64_1 = left.register.uint64_1 > right.register.uint64_1 ? left.register.uint64_1 : right.register.uint64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ vec.register.int64_0 = left.register.int64_0 > right.register.int64_0 ? left.register.int64_0 : right.register.int64_0;
+ vec.register.int64_1 = left.register.int64_1 > right.register.int64_1 ? left.register.int64_1 : right.register.int64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ vec.register.single_0 = left.register.single_0 > right.register.single_0 ? left.register.single_0 : right.register.single_0;
+ vec.register.single_1 = left.register.single_1 > right.register.single_1 ? left.register.single_1 : right.register.single_1;
+ vec.register.single_2 = left.register.single_2 > right.register.single_2 ? left.register.single_2 : right.register.single_2;
+ vec.register.single_3 = left.register.single_3 > right.register.single_3 ? left.register.single_3 : right.register.single_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ vec.register.double_0 = left.register.double_0 > right.register.double_0 ? left.register.double_0 : right.register.double_0;
+ vec.register.double_1 = left.register.double_1 > right.register.double_1 ? left.register.double_1 : right.register.double_1;
+ return vec;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static T DotProduct(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ T product = GetZeroValue();
+ for (int g = 0; g < Count; g++)
+ {
+ product = ScalarAdd(product, ScalarMultiply(left[g], right[g]));
+ }
+ return product;
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte product = 0;
+ product += (Byte)(left.register.byte_0 * right.register.byte_0);
+ product += (Byte)(left.register.byte_1 * right.register.byte_1);
+ product += (Byte)(left.register.byte_2 * right.register.byte_2);
+ product += (Byte)(left.register.byte_3 * right.register.byte_3);
+ product += (Byte)(left.register.byte_4 * right.register.byte_4);
+ product += (Byte)(left.register.byte_5 * right.register.byte_5);
+ product += (Byte)(left.register.byte_6 * right.register.byte_6);
+ product += (Byte)(left.register.byte_7 * right.register.byte_7);
+ product += (Byte)(left.register.byte_8 * right.register.byte_8);
+ product += (Byte)(left.register.byte_9 * right.register.byte_9);
+ product += (Byte)(left.register.byte_10 * right.register.byte_10);
+ product += (Byte)(left.register.byte_11 * right.register.byte_11);
+ product += (Byte)(left.register.byte_12 * right.register.byte_12);
+ product += (Byte)(left.register.byte_13 * right.register.byte_13);
+ product += (Byte)(left.register.byte_14 * right.register.byte_14);
+ product += (Byte)(left.register.byte_15 * right.register.byte_15);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte product = 0;
+ product += (SByte)(left.register.sbyte_0 * right.register.sbyte_0);
+ product += (SByte)(left.register.sbyte_1 * right.register.sbyte_1);
+ product += (SByte)(left.register.sbyte_2 * right.register.sbyte_2);
+ product += (SByte)(left.register.sbyte_3 * right.register.sbyte_3);
+ product += (SByte)(left.register.sbyte_4 * right.register.sbyte_4);
+ product += (SByte)(left.register.sbyte_5 * right.register.sbyte_5);
+ product += (SByte)(left.register.sbyte_6 * right.register.sbyte_6);
+ product += (SByte)(left.register.sbyte_7 * right.register.sbyte_7);
+ product += (SByte)(left.register.sbyte_8 * right.register.sbyte_8);
+ product += (SByte)(left.register.sbyte_9 * right.register.sbyte_9);
+ product += (SByte)(left.register.sbyte_10 * right.register.sbyte_10);
+ product += (SByte)(left.register.sbyte_11 * right.register.sbyte_11);
+ product += (SByte)(left.register.sbyte_12 * right.register.sbyte_12);
+ product += (SByte)(left.register.sbyte_13 * right.register.sbyte_13);
+ product += (SByte)(left.register.sbyte_14 * right.register.sbyte_14);
+ product += (SByte)(left.register.sbyte_15 * right.register.sbyte_15);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16 product = 0;
+ product += (UInt16)(left.register.uint16_0 * right.register.uint16_0);
+ product += (UInt16)(left.register.uint16_1 * right.register.uint16_1);
+ product += (UInt16)(left.register.uint16_2 * right.register.uint16_2);
+ product += (UInt16)(left.register.uint16_3 * right.register.uint16_3);
+ product += (UInt16)(left.register.uint16_4 * right.register.uint16_4);
+ product += (UInt16)(left.register.uint16_5 * right.register.uint16_5);
+ product += (UInt16)(left.register.uint16_6 * right.register.uint16_6);
+ product += (UInt16)(left.register.uint16_7 * right.register.uint16_7);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16 product = 0;
+ product += (Int16)(left.register.int16_0 * right.register.int16_0);
+ product += (Int16)(left.register.int16_1 * right.register.int16_1);
+ product += (Int16)(left.register.int16_2 * right.register.int16_2);
+ product += (Int16)(left.register.int16_3 * right.register.int16_3);
+ product += (Int16)(left.register.int16_4 * right.register.int16_4);
+ product += (Int16)(left.register.int16_5 * right.register.int16_5);
+ product += (Int16)(left.register.int16_6 * right.register.int16_6);
+ product += (Int16)(left.register.int16_7 * right.register.int16_7);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32 product = 0;
+ product += (UInt32)(left.register.uint32_0 * right.register.uint32_0);
+ product += (UInt32)(left.register.uint32_1 * right.register.uint32_1);
+ product += (UInt32)(left.register.uint32_2 * right.register.uint32_2);
+ product += (UInt32)(left.register.uint32_3 * right.register.uint32_3);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32 product = 0;
+ product += (Int32)(left.register.int32_0 * right.register.int32_0);
+ product += (Int32)(left.register.int32_1 * right.register.int32_1);
+ product += (Int32)(left.register.int32_2 * right.register.int32_2);
+ product += (Int32)(left.register.int32_3 * right.register.int32_3);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64 product = 0;
+ product += (UInt64)(left.register.uint64_0 * right.register.uint64_0);
+ product += (UInt64)(left.register.uint64_1 * right.register.uint64_1);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64 product = 0;
+ product += (Int64)(left.register.int64_0 * right.register.int64_0);
+ product += (Int64)(left.register.int64_1 * right.register.int64_1);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single product = 0;
+ product += (Single)(left.register.single_0 * right.register.single_0);
+ product += (Single)(left.register.single_1 * right.register.single_1);
+ product += (Single)(left.register.single_2 * right.register.single_2);
+ product += (Single)(left.register.single_3 * right.register.single_3);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double product = 0;
+ product += (Double)(left.register.double_0 * right.register.double_0);
+ product += (Double)(left.register.double_1 * right.register.double_1);
+ return (T)(object)product;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static unsafe Vector<T> SquareRoot(Vector<T> value)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)Math.Sqrt((Byte)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)Math.Sqrt((SByte)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)Math.Sqrt((UInt16)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)Math.Sqrt((Int16)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)Math.Sqrt((UInt32)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)Math.Sqrt((Int32)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)Math.Sqrt((UInt64)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)Math.Sqrt((Int64)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)Math.Sqrt((Single)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)Math.Sqrt((Double)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ value.register.byte_0 = (Byte)Math.Sqrt(value.register.byte_0);
+ value.register.byte_1 = (Byte)Math.Sqrt(value.register.byte_1);
+ value.register.byte_2 = (Byte)Math.Sqrt(value.register.byte_2);
+ value.register.byte_3 = (Byte)Math.Sqrt(value.register.byte_3);
+ value.register.byte_4 = (Byte)Math.Sqrt(value.register.byte_4);
+ value.register.byte_5 = (Byte)Math.Sqrt(value.register.byte_5);
+ value.register.byte_6 = (Byte)Math.Sqrt(value.register.byte_6);
+ value.register.byte_7 = (Byte)Math.Sqrt(value.register.byte_7);
+ value.register.byte_8 = (Byte)Math.Sqrt(value.register.byte_8);
+ value.register.byte_9 = (Byte)Math.Sqrt(value.register.byte_9);
+ value.register.byte_10 = (Byte)Math.Sqrt(value.register.byte_10);
+ value.register.byte_11 = (Byte)Math.Sqrt(value.register.byte_11);
+ value.register.byte_12 = (Byte)Math.Sqrt(value.register.byte_12);
+ value.register.byte_13 = (Byte)Math.Sqrt(value.register.byte_13);
+ value.register.byte_14 = (Byte)Math.Sqrt(value.register.byte_14);
+ value.register.byte_15 = (Byte)Math.Sqrt(value.register.byte_15);
+ return value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ value.register.sbyte_0 = (SByte)Math.Sqrt(value.register.sbyte_0);
+ value.register.sbyte_1 = (SByte)Math.Sqrt(value.register.sbyte_1);
+ value.register.sbyte_2 = (SByte)Math.Sqrt(value.register.sbyte_2);
+ value.register.sbyte_3 = (SByte)Math.Sqrt(value.register.sbyte_3);
+ value.register.sbyte_4 = (SByte)Math.Sqrt(value.register.sbyte_4);
+ value.register.sbyte_5 = (SByte)Math.Sqrt(value.register.sbyte_5);
+ value.register.sbyte_6 = (SByte)Math.Sqrt(value.register.sbyte_6);
+ value.register.sbyte_7 = (SByte)Math.Sqrt(value.register.sbyte_7);
+ value.register.sbyte_8 = (SByte)Math.Sqrt(value.register.sbyte_8);
+ value.register.sbyte_9 = (SByte)Math.Sqrt(value.register.sbyte_9);
+ value.register.sbyte_10 = (SByte)Math.Sqrt(value.register.sbyte_10);
+ value.register.sbyte_11 = (SByte)Math.Sqrt(value.register.sbyte_11);
+ value.register.sbyte_12 = (SByte)Math.Sqrt(value.register.sbyte_12);
+ value.register.sbyte_13 = (SByte)Math.Sqrt(value.register.sbyte_13);
+ value.register.sbyte_14 = (SByte)Math.Sqrt(value.register.sbyte_14);
+ value.register.sbyte_15 = (SByte)Math.Sqrt(value.register.sbyte_15);
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ value.register.uint16_0 = (UInt16)Math.Sqrt(value.register.uint16_0);
+ value.register.uint16_1 = (UInt16)Math.Sqrt(value.register.uint16_1);
+ value.register.uint16_2 = (UInt16)Math.Sqrt(value.register.uint16_2);
+ value.register.uint16_3 = (UInt16)Math.Sqrt(value.register.uint16_3);
+ value.register.uint16_4 = (UInt16)Math.Sqrt(value.register.uint16_4);
+ value.register.uint16_5 = (UInt16)Math.Sqrt(value.register.uint16_5);
+ value.register.uint16_6 = (UInt16)Math.Sqrt(value.register.uint16_6);
+ value.register.uint16_7 = (UInt16)Math.Sqrt(value.register.uint16_7);
+ return value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ value.register.int16_0 = (Int16)Math.Sqrt(value.register.int16_0);
+ value.register.int16_1 = (Int16)Math.Sqrt(value.register.int16_1);
+ value.register.int16_2 = (Int16)Math.Sqrt(value.register.int16_2);
+ value.register.int16_3 = (Int16)Math.Sqrt(value.register.int16_3);
+ value.register.int16_4 = (Int16)Math.Sqrt(value.register.int16_4);
+ value.register.int16_5 = (Int16)Math.Sqrt(value.register.int16_5);
+ value.register.int16_6 = (Int16)Math.Sqrt(value.register.int16_6);
+ value.register.int16_7 = (Int16)Math.Sqrt(value.register.int16_7);
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ value.register.uint32_0 = (UInt32)Math.Sqrt(value.register.uint32_0);
+ value.register.uint32_1 = (UInt32)Math.Sqrt(value.register.uint32_1);
+ value.register.uint32_2 = (UInt32)Math.Sqrt(value.register.uint32_2);
+ value.register.uint32_3 = (UInt32)Math.Sqrt(value.register.uint32_3);
+ return value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ value.register.int32_0 = (Int32)Math.Sqrt(value.register.int32_0);
+ value.register.int32_1 = (Int32)Math.Sqrt(value.register.int32_1);
+ value.register.int32_2 = (Int32)Math.Sqrt(value.register.int32_2);
+ value.register.int32_3 = (Int32)Math.Sqrt(value.register.int32_3);
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ value.register.uint64_0 = (UInt64)Math.Sqrt(value.register.uint64_0);
+ value.register.uint64_1 = (UInt64)Math.Sqrt(value.register.uint64_1);
+ return value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ value.register.int64_0 = (Int64)Math.Sqrt(value.register.int64_0);
+ value.register.int64_1 = (Int64)Math.Sqrt(value.register.int64_1);
+ return value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ value.register.single_0 = (Single)Math.Sqrt(value.register.single_0);
+ value.register.single_1 = (Single)Math.Sqrt(value.register.single_1);
+ value.register.single_2 = (Single)Math.Sqrt(value.register.single_2);
+ value.register.single_3 = (Single)Math.Sqrt(value.register.single_3);
+ return value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ value.register.double_0 = (Double)Math.Sqrt(value.register.double_0);
+ value.register.double_1 = (Double)Math.Sqrt(value.register.double_1);
+ return value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+ #endregion Internal Math Methods
+
+ #region Helper Methods
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static bool ScalarEquals(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (Byte)(object)left == (Byte)(object)right;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (SByte)(object)left == (SByte)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (UInt16)(object)left == (UInt16)(object)right;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (Int16)(object)left == (Int16)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (UInt32)(object)left == (UInt32)(object)right;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (Int32)(object)left == (Int32)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (UInt64)(object)left == (UInt64)(object)right;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (Int64)(object)left == (Int64)(object)right;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (Single)(object)left == (Single)(object)right;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (Double)(object)left == (Double)(object)right;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static bool ScalarLessThan(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (Byte)(object)left < (Byte)(object)right;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (SByte)(object)left < (SByte)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (UInt16)(object)left < (UInt16)(object)right;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (Int16)(object)left < (Int16)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (UInt32)(object)left < (UInt32)(object)right;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (Int32)(object)left < (Int32)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (UInt64)(object)left < (UInt64)(object)right;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (Int64)(object)left < (Int64)(object)right;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (Single)(object)left < (Single)(object)right;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (Double)(object)left < (Double)(object)right;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static bool ScalarGreaterThan(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (Byte)(object)left > (Byte)(object)right;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (SByte)(object)left > (SByte)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (UInt16)(object)left > (UInt16)(object)right;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (Int16)(object)left > (Int16)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (UInt32)(object)left > (UInt32)(object)right;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (Int32)(object)left > (Int32)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (UInt64)(object)left > (UInt64)(object)right;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (Int64)(object)left > (Int64)(object)right;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (Single)(object)left > (Single)(object)right;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (Double)(object)left > (Double)(object)right;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarAdd(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left + (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left + (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left + (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left + (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left + (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left + (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left + (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left + (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left + (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left + (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarSubtract(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left - (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left - (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left - (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left - (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left - (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left - (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left - (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left - (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left - (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left - (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarMultiply(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left * (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left * (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left * (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left * (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left * (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left * (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left * (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left * (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left * (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left * (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarDivide(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left / (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left / (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left / (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left / (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left / (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left / (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left / (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left / (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left / (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left / (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T GetZeroValue()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double value = 0;
+ return (T)(object)value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T GetOneValue()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double value = 1;
+ return (T)(object)value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T GetAllBitsSetValue()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)ConstantHelper.GetByteWithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)ConstantHelper.GetSByteWithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)ConstantHelper.GetUInt16WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)ConstantHelper.GetInt16WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)ConstantHelper.GetUInt32WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)ConstantHelper.GetInt32WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)ConstantHelper.GetUInt64WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)ConstantHelper.GetInt64WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)ConstantHelper.GetSingleWithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)ConstantHelper.GetDoubleWithAllBitsSet();
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ #endregion
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.CompilerServices;
+
+namespace System.Numerics
+{
+ /// <summary>
+ /// Contains various methods useful for creating, manipulating, combining, and converting generic vectors with one another.
+ /// </summary>
+ public static class Vector
+ {
+ // JIT is not looking at the Vector class methods
+ // all methods here should be inlined and they must be implemented in terms of Vector<T> intrinsics
+ #region Select Methods
+ /// <summary>
+ /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector.
+ /// </summary>
+ /// <param name="condition">The integral mask vector used to drive selection.</param>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The new vector with elements selected based on the mask.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Single> ConditionalSelect(Vector<int> condition, Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<Single>)Vector<Single>.ConditionalSelect((Vector<Single>)condition, left, right);
+ }
+
+ /// <summary>
+ /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector.
+ /// </summary>
+ /// <param name="condition">The integral mask vector used to drive selection.</param>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The new vector with elements selected based on the mask.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<double> ConditionalSelect(Vector<long> condition, Vector<double> left, Vector<double> right)
+ {
+ return (Vector<double>)Vector<double>.ConditionalSelect((Vector<double>)condition, left, right);
+ }
+
+ /// <summary>
+ /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector.
+ /// </summary>
+ /// <param name="condition">The mask vector used to drive selection.</param>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The new vector with elements selected based on the mask.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> ConditionalSelect<T>(Vector<T> condition, Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.ConditionalSelect(condition, left, right);
+ }
+ #endregion Select Methods
+
+ #region Comparison methods
+ #region Equals methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left and right were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Equals<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> Equals(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left and right were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> Equals(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> Equals(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left and right were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> Equals(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether each pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The first vector to compare.</param>
+ /// <returns>True if all elements are equal; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool EqualsAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left == right;
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any element pairs are equal; False if no element pairs are equal.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool EqualsAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return !Vector<T>.Equals(left, right).Equals(Vector<T>.Zero);
+ }
+ #endregion Equals methods
+
+ #region Lessthan Methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> LessThan<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThan(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThan(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThan(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThan(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all of the elements in left are less than their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are less than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThan(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is less than its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are less than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThan(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion LessthanMethods
+
+ #region Lessthanorequal methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> LessThanOrEqual<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThanOrEqual(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThanOrEqual(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThanOrEqual(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThanOrEqual(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all elements in left are less than or equal to their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are less than or equal to their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanOrEqualAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThanOrEqual(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is less than or equal to its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are less than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanOrEqualAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThanOrEqual(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion Lessthanorequal methods
+
+ #region Greaterthan methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> GreaterThan<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThan(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThan(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThan(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThan(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all elements in left are greater than the corresponding elements in right.
+ /// elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are greater than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThan(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is greater than its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are greater than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThan(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion Greaterthan methods
+
+ #region Greaterthanorequal methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> GreaterThanOrEqual<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThanOrEqual(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThanOrEqual(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThanOrEqual(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to
+ /// their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThanOrEqual(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all of the elements in left are greater than or equal to
+ /// their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are greater than or equal to their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanOrEqualAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThanOrEqual(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is greater than or equal to its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are greater than or equal to their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanOrEqualAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThanOrEqual(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion Greaterthanorequal methods
+ #endregion Comparison methods
+
+ #region Vector Math Methods
+ // Every operation must either be a JIT intrinsic or implemented over a JIT intrinsic
+ // as a thin wrapper
+ // Operations implemented over a JIT intrinsic should be inlined
+ // Methods that do not have a <T> type parameter are recognized as intrinsics
+ /// <summary>
+ /// Returns whether or not vector operations are subject to hardware acceleration through JIT intrinsic support.
+ /// </summary>
+ [JitIntrinsic]
+ public static bool IsHardwareAccelerated
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ // Vector<T>
+ // Basic Math
+ // All Math operations for Vector<T> are aggressively inlined here
+
+ /// <summary>
+ /// Returns a new vector whose elements are the absolute values of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The absolute value vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Abs<T>(Vector<T> value) where T : struct
+ {
+ return Vector<T>.Abs(value);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the minimum of each pair of elements in the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The minimum vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Min<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.Min(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the maximum of each pair of elements in the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The maximum vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Max<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.Max(left, right);
+ }
+
+ // Specialized vector operations
+
+ /// <summary>
+ /// Returns the dot product of two vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The dot product.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static T Dot<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.DotProduct(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the square roots of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The square root vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> SquareRoot<T>(Vector<T> value) where T : struct
+ {
+ return Vector<T>.SquareRoot(value);
+ }
+ #endregion Vector Math Methods
+
+ #region Named Arithmetic Operators
+ /// <summary>
+ /// Creates a new vector whose values are the sum of each pair of elements from the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The summed vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Add<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left + right;
+ }
+
+ /// <summary>
+ /// Creates a new vector whose values are the difference between each pairs of elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The difference vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Subtract<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left - right;
+ }
+
+ /// <summary>
+ /// Creates a new vector whose values are the product of each pair of elements from the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The summed vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Multiply<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left * right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value.
+ /// </summary>
+ /// <param name="left">The source vector.</param>
+ /// <param name="right">The scalar factor.</param>
+ /// <returns>The scaled vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Multiply<T>(Vector<T> left, T right) where T : struct
+ {
+ return left * right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value.
+ /// </summary>
+ /// <param name="left">The scalar factor.</param>
+ /// <param name="right">The source vector.</param>
+ /// <returns>The scaled vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Multiply<T>(T left, Vector<T> right) where T : struct
+ {
+ return left * right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose values are the result of dividing the first vector's elements
+ /// by the corresponding elements in the second vector.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The divided vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Divide<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left / right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the given vector's elements negated.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The negated vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Negate<T>(Vector<T> value) where T : struct
+ {
+ return -value;
+ }
+ #endregion Named Arithmetic Operators
+
+ #region Named Bitwise Operators
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> BitwiseAnd<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left & right;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> BitwiseOr<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left | right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The one's complement vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> OnesComplement<T>(Vector<T> value) where T : struct
+ {
+ return ~value;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Xor<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left ^ right;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-and-not operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> AndNot<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left & ~right;
+ }
+ #endregion Named Bitwise Operators
+
+ #region Conversion Methods
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of unsigned bytes.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Byte> AsVectorByte<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Byte>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed bytes.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<SByte> AsVectorSByte<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<SByte>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of 16-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<UInt16> AsVectorUInt16<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<UInt16>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed 16-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Int16> AsVectorInt16<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Int16>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of unsigned 32-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<UInt32> AsVectorUInt32<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<UInt32>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed 32-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Int32> AsVectorInt32<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Int32>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of unsigned 64-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<UInt64> AsVectorUInt64<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<UInt64>)value;
+ }
+
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed 64-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Int64> AsVectorInt64<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Int64>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of 32-bit floating point numbers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Single> AsVectorSingle<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Single>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of 64-bit floating point numbers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Double> AsVectorDouble<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Double>)value;
+ }
+ #endregion Conversion Methods
+ }
+}
--- /dev/null
+SR.cs
+System.Numerics/ConstantHelper.cs
+System.Numerics/HashCodeHelper.cs
+System.Numerics/JitIntrinsicAttribute.cs
+System.Numerics/Register.cs
+System.Numerics/Vector_Operations.cs
+System.Numerics/Vector.cs
--- /dev/null
+#include System.Numerics.Vectors.dll.sources
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Reflection.Context.dll")]
+[assembly: AssemblyDescription ("System.Reflection.Context.dll")]
+[assembly: AssemblyDefaultAlias ("System.Reflection.Context.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Reflection.Context
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Reflection.Context.dll
+LIB_REFS = System
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+System.Reflection.Context/CustomReflectionContext.cs
--- /dev/null
+//
+// CustomReflectionContext.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace System.Reflection.Context
+{
+ public abstract class CustomReflectionContext : ReflectionContext
+ {
+ [MonoTODO]
+ protected CustomReflectionContext ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected CustomReflectionContext (ReflectionContext source)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual IEnumerable<PropertyInfo> AddProperties (Type type)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected PropertyInfo CreateProperty (Type propertyType, string name, Func<object, object> getter, Action<object, object> setter)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected PropertyInfo CreateProperty (Type propertyType, string name, Func<object, object> getter, Action<object, object> setter, IEnumerable<Attribute> propertyCustomAttributes, IEnumerable<Attribute> getterCustomAttributes, IEnumerable<Attribute> setterCustomAttributes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual IEnumerable<object> GetCustomAttributes (MemberInfo member, IEnumerable<object> declaredAttributes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual IEnumerable<object> GetCustomAttributes (ParameterInfo parameter, IEnumerable<object> declaredAttributes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override Assembly MapAssembly (Assembly assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override TypeInfo MapType (TypeInfo type)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Reflection.DispatchProxy.dll")]
+[assembly: AssemblyDescription ("System.Reflection.DispatchProxy.dll")]
+[assembly: AssemblyDefaultAlias ("System.Reflection.DispatchProxy.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Reflection.DispatchProxy
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Reflection.DispatchProxy.dll
+LIB_REFS = System
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+System.Reflection/DispatchProxy.cs
--- /dev/null
+//
+// DispatchProxy.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Reflection
+{
+ public abstract class DispatchProxy
+ {
+ [MonoTODO]
+ protected DispatchProxy()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static T Create<T, TProxy> () where TProxy : DispatchProxy
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected abstract object Invoke (MethodInfo targetMethod, object[] args);
+ }
+}
-//
-// ProtectedData.cs: Protect (encrypt) data without (user involved) key management
-//
+//\r
+// ProtectedData.cs: Protect (encrypt) data without (user involved) key management\r
+//\r
// Author:\r
// Sebastien Pouliot <sebastien@ximian.com>\r
-//
+//\r
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)\r
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)\r
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
\r
using System.Runtime.InteropServices;\r
-using System.Security.Permissions;
-
-using Mono.Security.Cryptography;
-
-namespace System.Security.Cryptography {
-
- // References:
- // a. Windows Data Protection
- // http://msdn.microsoft.com/library/en-us/dnsecure/html/windataprotection-dpapi.asp?frame=true
-
- public sealed class ProtectedData {
-
- private ProtectedData ()
- {
- }
-
+using System.Security.Permissions;\r
+\r
+using Mono.Security.Cryptography;\r
+\r
+namespace System.Security.Cryptography {\r
+\r
+ // References:\r
+ // a. Windows Data Protection\r
+ // http://msdn.microsoft.com/library/en-us/dnsecure/html/windataprotection-dpapi.asp?frame=true\r
+\r
+ public sealed class ProtectedData {\r
+\r
+ private ProtectedData ()\r
+ {\r
+ }\r
+\r
// FIXME [DataProtectionPermission (SecurityAction.Demand, ProtectData = true)]\r
- public static byte[] Protect (byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
- {
- if (userData == null)
- throw new ArgumentNullException ("userData");
-
+ public static byte[] Protect (byte[] userData, byte[] optionalEntropy, DataProtectionScope scope) \r
+ {\r
+ if (userData == null)\r
+ throw new ArgumentNullException ("userData");\r
+\r
// on Windows this is supported only under 2000 and later OS\r
Check (scope);\r
\r
switch (impl) {\r
+#if !MOBILE\r
case DataProtectionImplementation.ManagedProtection:\r
try {\r
return ManagedProtection.Protect (userData, optionalEntropy, scope);\r
string msg = Locale.GetText ("Data protection failed.");\r
throw new CryptographicException (msg, e);\r
}\r
+#endif\r
default:\r
throw new PlatformNotSupportedException ();\r
}\r
}\r
\r
// FIXME [DataProtectionPermission (SecurityAction.Demand, UnprotectData = true)]\r
- public static byte[] Unprotect (byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope)
- {
- if (encryptedData == null)
- throw new ArgumentNullException ("encryptedData");
-
+ public static byte[] Unprotect (byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) \r
+ {\r
+ if (encryptedData == null)\r
+ throw new ArgumentNullException ("encryptedData");\r
+\r
// on Windows this is supported only under 2000 and later OS\r
Check (scope);\r
\r
switch (impl) {\r
+#if !MOBILE\r
case DataProtectionImplementation.ManagedProtection:\r
try {\r
return ManagedProtection.Unprotect (encryptedData, optionalEntropy, scope);\r
string msg = Locale.GetText ("Data unprotection failed.");\r
throw new CryptographicException (msg, e);\r
}\r
+#endif\r
default:\r
throw new PlatformNotSupportedException ();\r
}\r
- }
-
+ }\r
+\r
// private stuff\r
\r
enum DataProtectionImplementation {\r
throw new PlatformNotSupportedException ();\r
}\r
}\r
- }
-}
-
+ }\r
+}\r
+\r
--- /dev/null
+Assembly/AssemblyInfo.cs
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+System.Security.Cryptography/CryptographicAttribute.cs
+System.Security.Cryptography/CryptographicAttributeCollection.cs
+System.Security.Cryptography/CryptographicAttributeEnumerator.cs
+System.Security.Cryptography/DataProtectionScope.cs
+System.Security.Cryptography/ProtectedData.cs
+System.Security.Cryptography.Pkcs/AlgorithmIdentifier.cs
+System.Security.Cryptography.Pkcs/CmsRecipient.cs
+System.Security.Cryptography.Pkcs/CmsRecipientCollection.cs
+System.Security.Cryptography.Pkcs/CmsRecipientEnumerator.cs
+System.Security.Cryptography.Pkcs/ContentInfo.cs
+System.Security.Cryptography.Pkcs/EnvelopedCms.cs
+System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs
+System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs
+System.Security.Cryptography.Pkcs/Pkcs9Attribute.cs
+System.Security.Cryptography.Pkcs/Pkcs9ContentType.cs
+System.Security.Cryptography.Pkcs/Pkcs9DocumentDescription.cs
+System.Security.Cryptography.Pkcs/Pkcs9DocumentName.cs
+System.Security.Cryptography.Pkcs/Pkcs9MessageDigest.cs
+System.Security.Cryptography.Pkcs/Pkcs9SigningTime.cs
+System.Security.Cryptography.Pkcs/PublicKeyInfo.cs
+System.Security.Cryptography.Pkcs/RecipientInfo.cs
+System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs
+System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs
+System.Security.Cryptography.Pkcs/RecipientInfoType.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifier.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifierOrKeyType.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifierType.cs
+System.Security.Cryptography.Xml/X509IssuerSerial.cs
+
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Xml;
+#if !MOBILE && !XAMMAC_4_5
using WS = System.Web.Services.Description;
+#endif
namespace System.ServiceModel.Channels
{
return false;
}
+#if !MOBILE && !XAMMAC_4_5
public override bool CanBuildChannelListener<TChannel> (
BindingContext context)
{
}
return false;
}
+#endif
public override T GetProperty<T> (BindingContext context)
{
return base.GetProperty<T> (context);
}
+#if !MOBILE && !XAMMAC_4_5
void IWsdlExportExtension.ExportContract (WsdlExporter exporter,
WsdlContractConversionContext context)
{
transfer_mode == TransferMode.StreamedResponse)
assertions.Add (doc.CreateElement ("msf", "Streamed", "http://schemas.microsoft.com/ws/2006/05/framing/policy"));
}
+#endif
}
}
{
public SslStreamSecurityBindingElement ()
{
+#if !MOBILE && !XAMMAC_4_5
verifier = IdentityVerifier.CreateDefault ();
+#endif
}
+#if !MOBILE && !XAMMAC_4_5
IdentityVerifier verifier;
- bool require_client_certificate;
public IdentityVerifier IdentityVerifier {
get { return verifier; }
set { verifier = value; }
}
+#endif
+
+ bool require_client_certificate;
public bool RequireClientCertificate {
get { return require_client_certificate; }
SslStreamSecurityBindingElement other)
: base (other)
{
+#if !MOBILE && !XAMMAC_4_5
verifier = other.verifier;
+#endif
require_client_certificate = other.require_client_certificate;
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public StreamUpgradeProvider BuildClientStreamUpgradeProvider (BindingContext context)
{
"msf", "SslTransportSecurity", PolicyImportHelper.FramingPolicyNS);
return element;
}
+#endif
[MonoTODO]
public override IChannelFactory<TChannel>
throw new NotImplementedException ();
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public override IChannelListener<TChannel>
BuildChannelListener<TChannel> (
{
throw new NotImplementedException ();
}
+#endif
[MonoTODO]
public override bool CanBuildChannelFactory<TChannel> (
throw new NotImplementedException ();
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public override bool CanBuildChannelListener<TChannel> (
BindingContext context)
{
throw new NotImplementedException ();
}
+#endif
public override BindingElement Clone ()
{
throw new NotImplementedException ();
}
+#if !MOBILE && !XAMMAC_4_5
#region explicit interface implementations
[MonoTODO]
void IPolicyExportExtension.ExportPolicy (
context.GetBindingAssertions ().Add (transportBinding);
}
#endregion
+#endif
}
}
using System.Collections.Generic;
using System.Net;
using System.ServiceModel.Channels;
+#if !MOBILE && !XAMMAC_4_5
using System.ServiceModel.Channels.NetTcp;
+#endif
using System.ServiceModel.Description;
namespace System.ServiceModel.Channels
{
if (!CanBuildChannelFactory<TChannel> (context))
throw new InvalidOperationException (String.Format ("Not supported channel factory type '{0}'", typeof (TChannel)));
+
+#if !MOBILE && !XAMMAC_4_5
return new TcpChannelFactory<TChannel> (this, context);
+#else
+ throw new NotImplementedException ();
+#endif
}
+#if !MOBILE && !XAMMAC_4_5
public override IChannelListener<TChannel>
BuildChannelListener<TChannel> (
BindingContext context)
throw new InvalidOperationException (String.Format ("Not supported channel listener type '{0}'", typeof (TChannel)));
return new TcpChannelListener<TChannel> (this, context);
}
+#endif
public override BindingElement Clone ()
{
max_recv_message_size = other.max_recv_message_size;
}
- public bool ManualAddressing {
+ public virtual bool ManualAddressing {
get { return manual_addressing; }
set { manual_addressing = value; }
}
return context.BuildInnerChannelFactory<TChannel> ();
}
+#if !MOBILE && !XAMMAC_4_5
public override IChannelListener<TChannel>
BuildChannelListener<TChannel> (
BindingContext context)
{
return context.BuildInnerChannelListener<TChannel> ();
}
+#endif
public override bool CanBuildChannelFactory<TChannel> (
BindingContext context)
return context.CanBuildInnerChannelFactory<TChannel> ();
}
+#if !MOBILE && !XAMMAC_4_5
public override bool CanBuildChannelListener<TChannel> (
BindingContext context)
{
return context.CanBuildInnerChannelListener<TChannel> ();
}
+#endif
public override BindingElement Clone ()
{
{
if (typeof (T) == typeof (ISecurityCapabilities))
return (T) (object) this;
+#if !MOBILE && !XAMMAC_4_5
if (typeof (T) == typeof (IdentityVerifier))
return (T) (object) IdentityVerifier.CreateDefault ();
+#endif
return null;
}
get { throw new NotImplementedException (); }
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
void IPolicyExportExtension.ExportPolicy (
MetadataExporter exporter,
element.AppendChild (protectionLevel);
return element;
}
+#endif
#endregion
}
}
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
+#if !MOBILE && !XAMMAC_4_5
using ReqType = System.ServiceModel.Security.Tokens.ServiceModelSecurityTokenRequirement;
+#endif
namespace System.ServiceModel.Security.Tokens
{
public class SecureConversationSecurityTokenParameters : SecurityTokenParameters
{
+#if !MOBILE && !XAMMAC_4_5
static readonly ChannelProtectionRequirements default_channel_protection_requirements;
+#endif
static readonly BindingContext dummy_context;
static SecureConversationSecurityTokenParameters ()
{
+#if !MOBILE && !XAMMAC_4_5
ChannelProtectionRequirements r =
new ChannelProtectionRequirements ();
r.IncomingSignatureParts.ChannelParts.IsBodyIncluded = true;
r.OutgoingEncryptionParts.ChannelParts.IsBodyIncluded = true;
r.MakeReadOnly ();
default_channel_protection_requirements = r;
+#endif
dummy_context = new BindingContext (
new CustomBinding (),
}
SecurityBindingElement element;
+#if !MOBILE && !XAMMAC_4_5
ChannelProtectionRequirements requirements;
+#endif
bool cancellable;
public SecureConversationSecurityTokenParameters ()
{
}
+#if !MOBILE && !XAMMAC_4_5
public SecureConversationSecurityTokenParameters (
SecurityBindingElement element,
bool requireCancellation,
else
this.requirements = new ChannelProtectionRequirements (requirements);
}
+#else
+ internal SecureConversationSecurityTokenParameters (
+ SecurityBindingElement element,
+ bool requireCancellation,
+ object dummy)
+ {
+ this.element = element;
+ this.cancellable = requireCancellation;
+ }
+#endif
protected SecureConversationSecurityTokenParameters (SecureConversationSecurityTokenParameters source)
: base (source)
{
this.element = (SecurityBindingElement) source.element.Clone ();
this.cancellable = source.cancellable;
+#if !MOBILE && !XAMMAC_4_5
this.requirements = new ChannelProtectionRequirements (default_channel_protection_requirements);
+#endif
}
public bool RequireCancellation {
set { element = value; }
}
+#if !MOBILE && !XAMMAC_4_5
public ChannelProtectionRequirements BootstrapProtectionRequirements {
get { return requirements; }
}
+#endif
// SecurityTokenParameters
return new SecureConversationSecurityTokenParameters (this);
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause (
SecurityToken token, SecurityTokenReferenceStyle referenceStyle)
{
throw new NotImplementedException ();
}
-
[MonoTODO]
protected internal override void InitializeSecurityTokenRequirement (SecurityTokenRequirement requirement)
{
requirement.Properties [ReqType.IssuedSecurityTokenParametersProperty] = this.Clone ();
requirement.KeyType = SecurityKeyType.SymmetricKey;
}
+#endif
public override string ToString ()
{
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using System.Text;
protected abstract SecurityTokenParameters CloneCore ();
+#if !MOBILE && !XAMMAC_4_5
protected abstract SecurityKeyIdentifierClause CreateKeyIdentifierClause (
SecurityToken token, SecurityTokenReferenceStyle referenceStyle);
}
protected internal abstract void InitializeSecurityTokenRequirement (SecurityTokenRequirement requirement);
+#endif
internal BindingContext IssuerBindingContext {
set { issuer_binding_context = value; }
}
+#if !MOBILE && !XAMMAC_4_5
internal void CallInitializeSecurityTokenRequirement (SecurityTokenRequirement requirement)
{
if (issuer_binding_context != null)
{
throw new NotImplementedException ();
}
+#endif
}
}
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Security;
namespace System.ServiceModel.Security.Tokens
return new UserNameSecurityTokenParameters (this);
}
+#if !MOBILE && !XAMMAC_4_5
protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause (
SecurityToken token, SecurityTokenReferenceStyle referenceStyle)
{
requirement.TokenType = SecurityTokenTypes.UserName;
requirement.RequireCryptographicToken = true;
}
+#endif
}
}
System.ServiceModel/BasicHttpsBinding.cs
System.ServiceModel/BasicHttpsSecurity.cs
System.ServiceModel/NetHttpBinding.cs
+System.ServiceModel/NetHttpsBinding.cs
System.ServiceModel/NetHttpMessageEncoding.cs
System.ServiceModel.Channels/CompressionFormat.cs
System.ServiceModel.Channels/WebSocketTransportSettings.cs
public BasicHttpsSecurity Security {
get { return security; }
+ set { security = value; }
}
public override BindingElementCollection
public HttpTransportSecurity Transport {
get { return transport; }
+ set { transport = value; }
}
}
}
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
+#if !MOBILE && !XAMMAC_4_5
using System.Transactions;
+#endif
namespace System.ServiceModel
{
MaxItemsInObjectGraph = 0x10000;
UseSynchronizationContext = true;
ValidateMustUnderstand = true;
+#if !MOBILE && !XAMMAC_4_5
TransactionIsolationLevel = IsolationLevel.Unspecified;
+#endif
}
[MonoTODO]
[MonoTODO]
public int MaxItemsInObjectGraph { get; set; }
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public IsolationLevel TransactionIsolationLevel { get; set; }
+#endif
[MonoTODO]
public string TransactionTimeout { get; set; }
//
using System;
using System.Collections.Generic;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Claims;
+#endif
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
{
public class DnsEndpointIdentity : EndpointIdentity
{
+#if !MOBILE && !XAMMAC_4_5
public DnsEndpointIdentity (Claim identity)
{
Initialize (identity);
: this (Claim.CreateDnsClaim (dns))
{
}
+#else
+ public DnsEndpointIdentity (string dns)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
}
}
// no special magic), we have to use different approach
// that should work either.
object proxy = Activator.CreateInstance (type, new object [] {Endpoint, this, address, via});
-#else
+#elif !MOBILE && !XAMMAC_4_5
object proxy = new ClientRealProxy (typeof (TChannel), new DuplexClientRuntimeChannel (Endpoint, this, address, via), true).GetTransparentProxy ();
+#else
+ object proxy;
+ throw new NotImplementedException ();
#endif
((IDuplexContextChannel) proxy).CallbackInstance = callbackInstance;
} catch (Exception ex) {
// FIXME: log it.
Console.WriteLine (ex);
- } finally {
- // unless it is closed by session/call manager, move it back to the loop to receive the next message.
- if (loop && input.State != CommunicationState.Closed)
- ProcessRequestOrInput (input);
}
}
set { reader_quotas = value; }
}
- public override abstract string Scheme {
+ public override string Scheme {
get;
}
{
public sealed class MessageSecurityOverTcp
{
+#if !MOBILE && !XAMMAC_4_5
SecurityAlgorithmSuite alg_suite;
+#endif
MessageCredentialType client_credential_type;
internal MessageSecurityOverTcp ()
{
+#if !MOBILE && !XAMMAC_4_5
alg_suite = SecurityAlgorithmSuite.Default;
+#endif
// This default value is *silly* but anyways
// such code that does not change this ClientCredentialType
// won't work on Mono.
client_credential_type = MessageCredentialType.Windows;
}
+#if !MOBILE && !XAMMAC_4_5
public SecurityAlgorithmSuite AlgorithmSuite {
get { return alg_suite; }
set { alg_suite = value; }
}
+#endif
public MessageCredentialType ClientCredentialType {
get { return client_credential_type; }
//
using System.Collections.Generic;
using System.Collections.ObjectModel;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
{
public abstract class MessageSecurityVersion
{
+#if !MOBILE && !XAMMAC_4_5
// Types
class MessageSecurityTokenVersion : SecurityTokenVersion
{
SecureConversationVersion = SecureConversationVersion.WSSecureConversationFeb2005;
TrustVersion = TrustVersion.WSTrustFeb2005;
}
+ this.SecurityVersion = wss11 ? SecurityVersion.WSSecurity11 : SecurityVersion.WSSecurity10;
}
public override BasicSecurityProfileVersion BasicSecurityProfileVersion {
get { return MessageSecurityTokenVersion.GetVersion (wss11, basic_profile); }
}
- public override SecurityVersion SecurityVersion {
- get { return wss11 ? SecurityVersion.WSSecurity11 : SecurityVersion.WSSecurity10; }
- }
-
public override SecurityPolicyVersion SecurityPolicyVersion {
get { return use2007 ? SecurityPolicyVersion.WSSecurityPolicy12 : SecurityPolicyVersion.WSSecurityPolicy11; }
}
}
+#endif
// Static members
static MessageSecurityVersion ()
{
+#if !MOBILE && !XAMMAC_4_5
wss10_basic = new MessageSecurityVersionImpl (false, true, false);
wss11 = new MessageSecurityVersionImpl (true, false, false);
wss11_basic = new MessageSecurityVersionImpl (true, true, false);
wss10_2007_basic = new MessageSecurityVersionImpl (false, true, true);
wss11_2007_basic = new MessageSecurityVersionImpl (true, true, true);
wss11_2007 = new MessageSecurityVersionImpl (true, false, true);
+#else
+ throw new NotImplementedException ();
+#endif
}
public static MessageSecurityVersion Default {
public abstract BasicSecurityProfileVersion BasicSecurityProfileVersion { get; }
+#if !MOBILE && !XAMMAC_4_5
public abstract SecurityTokenVersion SecurityTokenVersion { get; }
+#endif
- public abstract SecurityVersion SecurityVersion { get; }
+ public SecurityVersion SecurityVersion { get; internal set; }
public SecureConversationVersion SecureConversationVersion { get; internal set; }
--- /dev/null
+// Authors:
+// Martin Baulig (martin.baulig@xamarin.com)
+//
+// Copyright 2012 Xamarin Inc. (http://www.xamarin.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.ServiceModel.Channels;
+
+namespace System.ServiceModel {
+ [MonoTODO]
+ public class NetHttpsBinding : HttpBindingBase {
+ public NetHttpsBinding ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpsBinding (BasicHttpsSecurityMode securityMode)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpsBinding (string configurationName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpsBinding (
+ BasicHttpsSecurityMode securityMode, bool reliableSessionEnabled)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpMessageEncoding MessageEncoding { get; set; }
+ public OptionalReliableSession ReliableSession { get; set; }
+ public BasicHttpsSecurity Security { get; set; }
+
+ public WebSocketTransportSettings WebSocketSettings {
+ get { throw new NotImplementedException (); }
+ }
+
+ public override string Scheme {
+ get { throw new NotImplementedException (); }
+ }
+
+ public override BindingElementCollection CreateBindingElements ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public bool ShouldSerializeReliableSession ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public bool ShouldSerializeSecurity ()
+ {
+ throw new NotImplementedException ();
+ }
+
+
+
+ }
+}
\ No newline at end of file
XmlDictionaryReaderQuotas reader_quotas
= new XmlDictionaryReaderQuotas ();
bool transaction_flow;
+#if !MOBILE && !XAMMAC_4_5
TransactionProtocol transaction_protocol;
+#endif
TcpTransportBindingElement transport;
public NetTcpBinding ()
public NetTcpBinding (string configurationName)
: this ()
{
+#if !MOBILE && !XAMMAC_4_5
var bindingsSection = ConfigUtil.BindingsSection;
var el = bindingsSection.NetTcpBinding.Bindings [configurationName];
el.ApplyConfiguration (this);
+#else
+ throw new NotImplementedException ();
+#endif
}
internal NetTcpBinding (TcpTransportBindingElement transport,
set { transaction_flow = value; }
}
+#if !MOBILE && !XAMMAC_4_5
public TransactionProtocol TransactionProtocol {
get { return transaction_protocol; }
set { transaction_protocol = value; }
}
+#endif
// overrides
public override BindingElementCollection CreateBindingElements ()
{
+#if !MOBILE && !XAMMAC_4_5
BindingElement tx = new TransactionFlowBindingElement (TransactionProtocol.WSAtomicTransactionOctober2004);
SecurityBindingElement sec = CreateMessageSecurity ();
+#endif
var msg = new BinaryMessageEncodingBindingElement ();
if (ReaderQuotas != null)
ReaderQuotas.CopyTo (msg.ReaderQuotas);
var trsec = CreateTransportSecurity ();
BindingElement tr = GetTransport ();
List<BindingElement> list = new List<BindingElement> ();
+#if !MOBILE && !XAMMAC_4_5
if (tx != null)
list.Add (tx);
if (sec != null)
list.Add (sec);
+#endif
list.Add (msg);
if (trsec != null)
list.Add (trsec);
return transport.Clone ();
}
+#if !MOBILE && !XAMMAC_4_5
// It is problematic, but there is no option to disable establishing security context in this binding unlike WSHttpBinding...
SecurityBindingElement CreateMessageSecurity ()
{
// FIXME: requireCancellation
element, true, reqs);
}
+#endif
BindingElement CreateTransportSecurity ()
{
//
using System;
using System.Collections.Generic;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Claims;
+#endif
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
{
public class SpnEndpointIdentity : EndpointIdentity
{
+#if !MOBILE && !XAMMAC_4_5
public SpnEndpointIdentity (Claim identity)
{
Initialize (identity);
: this (Claim.CreateSpnClaim (spn))
{
}
+#else
+ public SpnEndpointIdentity (string spn)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
[MonoTODO]
public static TimeSpan SpnLookupTime {
//
using System;
using System.Collections.Generic;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Claims;
+#endif
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
{
public class UpnEndpointIdentity : EndpointIdentity
{
+#if !MOBILE && !XAMMAC_4_5
public UpnEndpointIdentity (Claim identity)
{
Initialize (identity);
: this (Claim.CreateUpnClaim (upn))
{
}
+#else
+ public UpnEndpointIdentity (string upn)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
}
}
System.ServiceModel/BasicHttpMessageSecurity.cs
System.ServiceModel/BasicHttpsBinding.cs
System.ServiceModel/BasicHttpsSecurity.cs
+System.ServiceModel/CallbackBehaviorAttribute.cs
System.ServiceModel/ChannelFactory.cs
System.ServiceModel/ChannelFactory_1.cs
System.ServiceModel/ClientBase.cs
System.ServiceModel/DataContractFormatAttribute.cs
System.ServiceModel/DefaultCommunicationTimeouts.cs
System.ServiceModel/Dummy.cs
+System.ServiceModel/DuplexClientBase.cs
+System.ServiceModel/DuplexChannelFactory.cs
System.ServiceModel/EndpointAddress.cs
System.ServiceModel/EndpointAddress10.cs
System.ServiceModel/EndpointAddressBuilder.cs
System.ServiceModel/ICommunicationObject.cs
System.ServiceModel/IContextChannel.cs
System.ServiceModel/IDefaultCommunicationTimeouts.cs
+System.ServiceModel/IDuplexClientChannel.cs
System.ServiceModel/IExtensibleObject.cs
System.ServiceModel/IExtension.cs
System.ServiceModel/IExtensionCollection.cs
System.ServiceModel/MessageParameterAttribute.cs
System.ServiceModel/MessagePropertyAttribute.cs
System.ServiceModel/NetHttpBinding.cs
+System.ServiceModel/NetHttpsBinding.cs
System.ServiceModel/NetHttpMessageEncoding.cs
System.ServiceModel/OperationContext.cs
System.ServiceModel/OperationContextScope.cs
System.ServiceModel/XmlSerializerFormatAttribute.cs
System.ServiceModel.Description/XmlSerializerOperationBehavior.cs
System.ServiceModel.Dispatcher/XmlMessagesFormatter.cs
+
+System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs
+System.ServiceModel.Channels/SslStreamSecurityBindingElement.cs
+System.ServiceModel.Channels/TcpConnectionPoolSettings.cs
+System.ServiceModel.Channels/TcpTransportBindingElement.cs
+System.ServiceModel.Channels/WindowsStreamSecurityBindingElement.cs
+
+System.ServiceModel/MessageSecurityOverTcp.cs
+System.ServiceModel/NetTcpBinding.cs
+System.ServiceModel/NetTcpSecurity.cs
+System.ServiceModel/TcpTransportSecurity.cs
+System.ServiceModel/DnsEndpointIdentity.cs
+System.ServiceModel/SpnEndpointIdentity.cs
+System.ServiceModel/UpnEndpointIdentity.cs
+System.ServiceModel/MessageSecurityVersion.cs
+
+System.ServiceModel.Security/BasicSecurityProfileVersion.cs
+System.ServiceModel.Security/SecurityVersion.cs
+System.ServiceModel.Security/TrustVersion.cs
+System.ServiceModel.Security/SecureConversationVersion.cs
+System.ServiceModel.Security/SecurityPolicyVersion.cs
+
+System.ServiceModel.Security.Tokens/SecurityTokenParameters.cs
+System.ServiceModel.Security.Tokens/SecurityTokenReferenceStyle.cs
+System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs
+System.ServiceModel.Security.Tokens/SupportingTokenParameters.cs
+System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Xml.XPath.XmlDocument.dll")]
+[assembly: AssemblyDescription ("System.Xml.XPath.XmlDocument.dll")]
+[assembly: AssemblyDefaultAlias ("System.Xml.XPath.XmlDocument.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Xml.XPath.XmlDocument
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Xml.XPath.XmlDocument.dll
+LIB_REFS = System System.Xml
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+System.Xml/XmlDocumentXPathExtensions.cs
--- /dev/null
+//
+// XmlDocumentXPathExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Xml
+{
+ public static class XmlDocumentXPathExtensions
+ {
+ [MonoTODO]
+ public static XmlNodeList SelectNodes (this XmlNode node, string xpath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XmlNodeList SelectNodes (this XmlNode node, string xpath, XmlNamespaceManager nsmgr)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XmlNode SelectSingleNode (this XmlNode node, string xpath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XmlNode SelectSingleNode (this XmlNode node, string xpath, XmlNamespaceManager nsmgr)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.XPathNavigator CreateNavigator (this XmlNode node)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.IXPathNavigable ToXPathNavigable (this XmlNode node)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.XPathNavigator CreateNavigator (this XmlDocument document)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.XPathNavigator CreateNavigator (this XmlDocument document, XmlNode node)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
--- /dev/null
+//
+// FileSystemWatcher.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.IO
+{
+ public class FileSystemWatcher
+ {
+ public FileSystemWatcher () { throw new NotImplementedException (); }
+ public FileSystemWatcher (string path) { throw new NotImplementedException (); }
+ public FileSystemWatcher (string path, string filter) { throw new NotImplementedException (); }
+ public bool EnableRaisingEvents { get { throw new NotImplementedException (); } set { throw new NotImplementedException (); } }
+ public string Filter { get { throw new NotImplementedException (); } set { } }
+ public bool IncludeSubdirectories { get { throw new NotImplementedException (); } set { } }
+ public int InternalBufferSize { get { throw new NotImplementedException (); } set { } }
+ public NotifyFilters NotifyFilter { get { throw new NotImplementedException (); } set { } }
+ public string Path { get { throw new NotImplementedException (); } set { } }
+ public event FileSystemEventHandler Changed;
+ public event FileSystemEventHandler Created;
+ public event FileSystemEventHandler Deleted;
+ public event ErrorEventHandler Error;
+ public event RenamedEventHandler Renamed;
+ protected void OnChanged (FileSystemEventArgs e) { throw new NotImplementedException (); }
+ protected void OnCreated (FileSystemEventArgs e) { throw new NotImplementedException (); }
+ protected void OnDeleted (System.IO.FileSystemEventArgs e) { throw new NotImplementedException (); }
+ protected void OnError (ErrorEventArgs e) { throw new NotImplementedException (); }
+ protected void OnRenamed (RenamedEventArgs e) { throw new NotImplementedException (); }
+ public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType) { throw new NotImplementedException (); }
+ public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType, int timeout) { throw new NotImplementedException (); }
+ }
+}
\ No newline at end of file
EndpointUnavailable = 1001,
ProtocolError = 1002,
InvalidMessageType = 1003,
- Empty,
+ Empty = 1005,
InvalidPayloadData = 1007,
PolicyViolation = 1008,
- MessageTooBig = 1004,
+ MessageTooBig = 1009,
MandatoryExtension = 1010,
- InternalServerError
+ InternalServerError = 1011
}
}
{
Stream s = null;
lock (this) {
+ if (request.Aborted)
+ throw new WebException ("Request aborted", WebExceptionStatus.RequestCanceled);
if (Data.request != request)
throw new ObjectDisposedException (typeof (NetworkStream).FullName);
if (nstream == null)
{
public enum ChannelBindingKind
{
- Unknown,
- Unique,
- Endpoint
+ Unknown = 0,
+ Unique = 25,
+ Endpoint = 26
}
}
//\r
\r
using NUnit.Framework;\r
+using MonoTests.Helpers;
using System;\r
using System.Net;\r
+using System.Threading;
using System.Collections;\r
using System.Runtime.Serialization;\r
using Socks = System.Net.Sockets;\r
{\r
internal TestWebRequest3 () { }\r
}\r
+
+ [Test] // Covers #41477
+ public void TestReceiveCancelation ()
+ {
+ var uri = "http://localhost:" + NetworkHelpers.FindFreePort () + "/";
+
+ HttpListener listener = new HttpListener ();
+ listener.Prefixes.Add (uri);
+ listener.Start ();
+
+ try {
+ for (var i = 0; i < 10; i++) {
+ var request = WebRequest.CreateHttp (uri);
+ request.Method = "GET";
+
+ var tokenSource = new CancellationTokenSource ();
+ tokenSource.Token.Register(() => request.Abort ());
+
+ var responseTask = request.GetResponseAsync ();
+
+ var context = listener.GetContext ();
+ byte[] outBuffer = new byte[8 * 1024];
+ context.Response.OutputStream.WriteAsync (outBuffer, 0, outBuffer.Length);
+
+ Assert.IsTrue (responseTask.Wait (1000), "Timeout #1");
+
+ WebResponse response = responseTask.Result;
+ var stream = response.GetResponseStream ();
+
+ byte[] buffer = new byte[8 * 1024];
+ var taskRead = stream.ReadAsync (buffer, 0, buffer.Length, tokenSource.Token);
+
+ tokenSource.Cancel ();
+
+ Assert.IsTrue (taskRead.Wait (1000), "Timeout #2");
+
+ var byteRead = taskRead.Result;
+ }
+ } catch (AggregateException ex) {
+ var webEx = ex.InnerException as WebException;
+ Assert.IsNotNull(webEx, "Inner exception is not a WebException");
+ Assert.AreEqual (webEx.Status, WebExceptionStatus.RequestCanceled);
+ }
+
+ listener.Close ();
+ }
}\r
\r
}\r
System.IO.Compression/GZipStream.cs
System.IO/InternalBufferOverflowException.cs
System.IO/InvalidDataException.cs
+System.IO/ErrorEventArgs.cs
+System.IO/ErrorEventHandler.cs
+System.IO/FileSystemEventArgs.cs
+System.IO/FileSystemEventHandler.cs
+System.IO/FileSystemWatcher_mobile.cs
+System.IO/NotifyFilters.cs
+System.IO/RenamedEventArgs.cs
+System.IO/RenamedEventHandler.cs
+System.IO/WaitForChangedResult.cs
+System.IO/WatcherChangeTypes.cs
System.Net.Mail/AlternateView.cs
System.Net.Mail/AlternateViewCollection.cs
System.Net.Mail/Attachment.cs
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
using System.Runtime.InteropServices;
}
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
using System.Runtime.InteropServices;
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
using System.IO;
using System.Collections;
namespace Microsoft.Win32
{
+
+#if MOBILE
+ public sealed class RegistryKey : IDisposable
+ {
+ internal RegistryKey (RegistryHive hiveId)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public void Dispose ()
+ {
+ }
+
+ public RegistryKey CreateSubKey (string subkey)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public object GetValue (string name, object defaultValue)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public static object GetValue (string keyName, string valueName, object defaultValue)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public RegistryKey OpenSubKey (string name, bool writable)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public void SetValue (string name, object value)
+ {
+ }
+
+ public void SetValue (string name, object value, RegistryValueKind valueKind)
+ {
+ }
+
+ // TODO: Finish full contract API
+ }
+#else
/// <summary>
/// Wrapper class for Windows Registry Entry.
/// </summary>
}
}
+#endif
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System.Runtime.InteropServices;
namespace Microsoft.Win32
}
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
namespace Microsoft.Win32
}
}
-#endif // NET_2_1
-
//
using System;
+using System.Reflection;
using System.Runtime.CompilerServices;
namespace Mono {
}
}
}
+
+ internal struct RuntimeGenericParamInfoHandle {
+ unsafe RuntimeStructs.GenericParamInfo* value;
+
+ internal unsafe RuntimeGenericParamInfoHandle (RuntimeStructs.GenericParamInfo* value)
+ {
+ this.value = value;
+ }
+
+ internal unsafe RuntimeGenericParamInfoHandle (IntPtr ptr)
+ {
+ this.value = (RuntimeStructs.GenericParamInfo*) ptr;
+ }
+
+
+ internal Type[] Constraints { get { return GetConstraints (); } }
+
+ internal GenericParameterAttributes Attributes {
+ get {
+ unsafe {
+ return (GenericParameterAttributes) value->flags;
+ }
+ }
+ }
+
+ Type[] GetConstraints () {
+ int n = GetConstraintsCount ();
+ var a = new Type[n];
+ for (int i = 0; i < n; i++) {
+ unsafe {
+ RuntimeClassHandle c = new RuntimeClassHandle (value->constraints[i]);
+ a[i] = Type.GetTypeFromHandle (c.GetTypeHandle ());
+ }
+ }
+ return a;
+ }
+
+ int GetConstraintsCount () {
+ int i = 0;
+ unsafe {
+ RuntimeStructs.MonoClass** p = value->constraints;
+ while (p != null && *p != null) {
+ p++; i++;
+ }
+ }
+ return i;
+ }
+ }
}
internal struct 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 */
+ }
}
}
throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
Contract.EndContractBlock();
- Type[] constraints = GetGenericParameterConstraints_impl ();
+ var paramInfo = new Mono.RuntimeGenericParamInfoHandle (RuntimeTypeHandle.GetGenericParameterInfo (this));
+ Type[] constraints = paramInfo.Constraints;
if (constraints == null)
constraints = EmptyArray<Type>.Value;
[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 ();
{
public class EventSource : IDisposable
{
+ protected internal struct EventData
+ {
+ public IntPtr DataPointer { get; set; }
+ public int Size { get; set; }
+ }
+
protected EventSource ()
{
this.Name = this.GetType().Name;
using System.Security.Permissions;
using System.Text;
using System.Threading;
+using System.IO;
namespace System.Diagnostics {
readonly StackTrace[] captured_traces;
private bool debug_info;
+ private static Dictionary<string, Func<StackTrace, string>> metadataHandlers;
+
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public StackTrace ()
{
if (!t.AddFrames (sb))
continue;
+ t.AddMetadata (sb);
+
sb.Append (Environment.NewLine);
sb.Append ("--- End of stack trace from previous location where exception was thrown ---");
sb.Append (Environment.NewLine);
}
AddFrames (sb);
+ AddMetadata (sb);
+
return sb.ToString ();
}
+ void AddMetadata (StringBuilder sb)
+ {
+ if (metadataHandlers == null)
+ InitMetadataHandlers ();
+
+ foreach (var handler in metadataHandlers) {
+ var lines = handler.Value (this);
+ using (var reader = new StringReader (lines)) {
+ string line;
+ while ((line = reader.ReadLine()) != null) {
+ sb.AppendLine ();
+ sb.AppendFormat ("[{0}] {1}", handler.Key, line);
+ }
+ }
+ }
+ }
+
internal String ToString (TraceFormat traceFormat)
{
// TODO:
return ToString ();
}
+
+ static void InitMetadataHandlers ()
+ {
+ metadataHandlers = new Dictionary<string, Func<StackTrace, string>> (StringComparer.Ordinal);
+
+ var aotid = Assembly.GetAotId ();
+ if (aotid != null)
+ AddMetadataHandler ("AOTID", st => { return new Guid (aotid).ToString ("N"); });
+
+ AddMetadataHandler ("MVID", st => {
+ var mvidLines = new Dictionary<Guid, List<int>> ();
+ var frames = st.GetFrames ();
+ for (var lineNumber = 0; lineNumber < frames.Length; lineNumber++) {
+ var method = frames[lineNumber].GetMethod ();
+ if (method == null)
+ continue;
+ var mvid = method.Module.ModuleVersionId;
+
+ List<int> lines = null;
+ if (!mvidLines.TryGetValue (mvid, out lines)) {
+ lines = new List<int> ();
+ mvidLines.Add (mvid, lines);
+ }
+
+ lines.Add (lineNumber);
+ }
+
+ var mvids = new List<Guid> (mvidLines.Keys);
+ mvids.Sort ();
+
+ var sb = new StringBuilder ();
+ foreach (var mvid in mvids)
+ sb.AppendLine (string.Format ("{0} {1}", mvid.ToString ("N"), string.Join (",", mvidLines[mvid])));
+
+ return sb.ToString ();
+ });
+ }
+
+ // This method signature should not change, apps can use it with reflection to add custom metadata handlers.
+ private static void AddMetadataHandler (string id, Func<StackTrace, string> handler)
+ {
+ if (metadataHandlers == null)
+ InitMetadataHandlers ();
+
+ metadataHandlers.Add (id, handler);
+ }
}
}
get {
return Thread.CurrentThread.CurrentCulture;
}
+#if NETSTANDARD
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
public static CultureInfo CurrentUICulture {
get {
return Thread.CurrentThread.CurrentUICulture;
}
+#if NETSTANDARD
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
internal static CultureInfo ConstructCurrentCulture ()
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-
-#endif
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
-
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
}
-#endif
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
namespace System.Reflection.Emit {
static class OpCodeNames {
internal static readonly string [] names = {
};
}
}
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-#endif
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
}
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-
-
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-#endif
--- /dev/null
+//
+// AssemblyExtensions.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NETSTANDARD
+
+namespace System.Reflection.Metadata
+{
+ public static class AssemblyExtensions
+ {
+ //
+ // System.Runtime.Loader netstandard typeforwarders dependency
+ //
+ [CLSCompliant(false)]
+ public unsafe static bool TryGetRawMetadata (this System.Reflection.Assembly assembly, out byte* blob, out int length)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern string InternalImageRuntimeVersion ();
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ static internal extern string GetAotId ();
+
// SECURITY: this should be the only caller to icall get_code_base
private string GetCodeBase (bool escaped)
{
get {
return (cultureinfo == null)? null : cultureinfo.Name;
}
+#if NETSTANDARD
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
[ComVisibleAttribute(false)]
--- /dev/null
+//
+// AssemblyLoadContext.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NETSTANDARD
+
+namespace System.Runtime.Loader
+{
+ //
+ // System.Runtime.Loader netstandard typeforwarders dependency
+ //
+ public abstract class AssemblyLoadContext
+ {
+ protected AssemblyLoadContext ()
+ {
+ }
+
+ public static System.Runtime.Loader.AssemblyLoadContext Default {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public static System.Reflection.AssemblyName GetAssemblyName (string assemblyPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static AssemblyLoadContext GetLoadContext (System.Reflection.Assembly assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected abstract System.Reflection.Assembly Load (System.Reflection.AssemblyName assemblyName);
+
+ public System.Reflection.Assembly LoadFromAssemblyName(System.Reflection.AssemblyName assemblyName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromAssemblyPath (string assemblyPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromNativeImagePath (string nativeImagePath, string assemblyPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromStream (System.IO.Stream assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromStream (System.IO.Stream assembly, System.IO.Stream assemblySymbols)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected IntPtr LoadUnmanagedDllFromPath (string unmanagedDllPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected virtual IntPtr LoadUnmanagedDll (string unmanagedDllName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void SetProfileOptimizationRoot (string directoryPath)
+ {
+ }
+
+ public void StartProfileOptimization (string profile)
+ {
+ }
+
+ public event Func<AssemblyLoadContext, System.Reflection.AssemblyName, System.Reflection.Assembly> Resolving;
+ public event Action<AssemblyLoadContext> Unloading;
+ }
+}
+
+#endif
\ No newline at end of file
bool _bReEntrant;
int _flavor;
- [NonSerialized]
- bool _locked;
[NonSerialized]
int _lockCount;
{
get
{
- return _locked;
+ return _lockCount > 0;
}
set
{
if (value)
{
- _mutex.WaitOne ();
+ AcquireLock ();
lock (this)
{
- _lockCount++;
if (_lockCount > 1)
ReleaseLock (); // Thread already had the lock
-
- _ownerThread = Thread.CurrentThread;
}
}
else
{
lock (this)
{
- while (_lockCount > 0 && _ownerThread == Thread.CurrentThread)
- {
- _lockCount--;
- _mutex.ReleaseMutex ();
- _ownerThread = null;
+ while (_lockCount > 0 && _ownerThread == Thread.CurrentThread) {
+ ReleaseLock ();
}
}
}
if (_lockCount > 0 && _ownerThread == Thread.CurrentThread) {
_lockCount--;
_mutex.ReleaseMutex ();
- _ownerThread = null;
+ if (_lockCount == 0) {
+ _ownerThread = null;
+ }
}
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericTypeDefinition (RuntimeType type);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr GetGenericParameterInfo (RuntimeType type);
+
}
}
using System.Text;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
+using System.Linq;
using NUnit.Framework;
invoke (456324);
Assert.IsNotNull (ExceptionHandling_Test_Support.Caught, "#1");
- Assert.AreEqual (2, ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None).Length, "#2");
+
+ var lines = ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None);
+ lines = lines.Where (l => !l.StartsWith ("[")).ToArray ();
+ Assert.AreEqual (2, lines.Length, "#2");
var st = new StackTrace (ExceptionHandling_Test_Support.Caught, 0, true);
public static void Handler (Exception e)
{
- var split = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (5, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
+ var lines = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ // Ignore Metadata
+ lines = lines.Where (l => !l.StartsWith ("[")).ToArray ();
+
+ Assert.AreEqual (5, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
}
}
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using System.Diagnostics;
+using System.Linq;
namespace MonoTests.System.Runtime.ExceptionServices
{
[Category ("BitcodeNotWorking")]
public class ExceptionDispatchInfoTest
{
+ static string[] GetLines (string str)
+ {
+ var lines = str.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+
+ // Ignore Metadata
+ return lines.Where (l => !l.StartsWith ("[")).ToArray ();
+ }
+
[Test]
public void Capture_InvalidArguments ()
{
ed.Throw ();
Assert.Fail ("#0");
} catch (Exception e) {
- var s = e.StackTrace.Split ('\n');
+ var s = GetLines (e.StackTrace);
Assert.AreEqual (4, s.Length, "#1");
Assert.AreEqual (orig, e, "#2");
Assert.AreNotEqual (orig_stack, e.StackTrace, "#3");
edi.Throw ();
Assert.Fail ("#0");
} catch (OperationCanceledException e) {
- Assert.IsFalse (e.StackTrace.Contains ("---"));
- Assert.AreEqual (2, e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Length);
+ Assert.IsTrue (!e.StackTrace.Contains("---"));
+ var lines = GetLines (e.StackTrace);
+ Assert.AreEqual (2, lines.Length, "#1");
}
}
try {
edi.Throw ();
} catch (Exception ex) {
- var split = ex.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (4, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
+ var lines = GetLines (ex.StackTrace);
+ Assert.AreEqual (4, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
}
}
try {
edi.Throw ();
} catch (Exception ex) {
- var split = ex.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (7, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
- Assert.IsTrue (split [4].Contains ("---"), "#3");
+ var lines = GetLines (ex.StackTrace);
+ Assert.AreEqual (7, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
+ Assert.IsTrue (lines [4].Contains ("---"), "#3");
}
}
}
} catch (Exception ex) {
var st = new StackTrace (ex, true);
- var split = st.ToString ().Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (4, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
+ var lines = GetLines (st.ToString ());
+ Assert.AreEqual (4, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
}
}
}
Assert.IsFalse (sa.Locked, "Locked");
}
+ [Test]
+ public void SetLocked()
+ {
+ SynchronizationAttribute sa = new SynchronizationAttribute(SynchronizationAttribute.REQUIRES_NEW);
+ sa.Locked = true;
+ Assert.IsTrue(sa.Locked, "Locked");
+ sa.Locked = false;
+ Assert.IsFalse(sa.Locked, "Locked");
+
+ sa.Locked = true;
+ Assert.IsTrue(sa.Locked, "Locked");
+ sa.Locked = true;
+ Assert.IsTrue(sa.Locked, "Locked");
+ sa.Locked = false;
+ Assert.IsFalse(sa.Locked, "Locked");
+ }
+
[Test]
public void SerializationRoundtrip ()
{
public void TestLocked1 ()
{
sincob.Lock (false);
+
Thread tr = new Thread (new ThreadStart (FirstSyncThread));
tr.Start ();
Thread.Sleep (200);
Assert.IsTrue (!otResult, "Concurrency detected in CallbackThread");
}
+ [Test]
+ public void TestSynchronizationReleasedOnMultipleAcquire ()
+ {
+
+ otResult = notreentrant.TestCallback ();
+
+ Thread tr = new Thread (new ThreadStart (CallbackThread));
+ tr.Start();
+
+ bool terminated = tr.Join(2000);
+ Assert.IsTrue(terminated, "Thread didn't get lock of context bound object.");
+
+ Assert.IsTrue (!otResult, "Concurrency detected in CallbackThread");
+ }
+
void CallbackThread ()
{
otResult = notreentrant.TestCallback ();
System.Reflection.Emit/TypeBuilder.cs
System.Reflection.Emit/TypeToken.cs
System.Reflection.Emit/UnmanagedMarshal.cs
+System.Reflection.Metadata/AssemblyExtensions.cs
System.Resources/Win32Resources.cs
System.Runtime/GCLargeObjectHeapCompactionMode.cs
System.Runtime/GCLatencyMode.cs
System.Runtime.Remoting.Services/EnterpriseServicesHelper.cs
System.Runtime.Remoting.Services/ITrackingHandler.cs
System.Runtime.Remoting.Services/TrackingServices.cs
+System.Runtime.Loader/AssemblyLoadContext.cs
System.Runtime.Versioning/CompatibilitySwitch.cs
System.Security/CodeAccessPermission.cs
System.Security/HostProtectionException.cs
public const string Sha512 = "SHA512"; // BCRYPT_SHA512_ALGORITHM
internal const string Rsa = "RSA"; // BCRYPT_RSA_ALGORITHM
}
-
+#if !MONO
/// <summary>
/// Well known key blob tyes
/// </summary>
}
return keyBlob;
}
+#endif
}
}
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public sealed class CngKey : IDisposable {
+#if MONO
+ public void Dispose() {
+ }
+#else
private SafeNCryptKeyHandle m_keyHandle;
private SafeNCryptProviderHandle m_kspHandle;
Contract.Assert(m_keyHandle != null);
NCryptNative.SetProperty(m_keyHandle, property.Name, property.Value, property.Options);
}
+#endif
}
}
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public sealed class ECDsaCng : ECDsa {
+#if MONO
+ public override byte[] SignHash(byte[] hash) {
+ throw new NotImplementedException();
+ }
+
+ public override bool VerifyHash(byte[] hash, byte[] signature) {
+ throw new NotImplementedException();
+ }
+#else
private static KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(256, 384, 128), new KeySizes(521, 521, 0) };
private CngKey m_key;
return hasher.HashFinal();
}
}
+ #endif
}
}
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+#if !MONO
using System.Numerics;
+#endif
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
ProtectKey = 0x00000001, // NCRYPT_UI_PROTECT_KEY_FLAG
ForceHighProtection = 0x00000002 // NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG
}
-
+#if !MONO
/// <summary>
/// Native interop with CNG's NCrypt layer. Native definitions are in ncrypt.h
/// </summary>
return error == ErrorCode.Success;
}
}
+#endif
}
{
public sealed class RSACng : RSA
{
+#if MONO
+ public override RSAParameters ExportParameters(bool includePrivateParameters)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void ImportParameters(RSAParameters parameters)
+ {
+ throw new NotImplementedException();
+ }
+#else
+
// See https://msdn.microsoft.com/en-us/library/windows/desktop/bb931354(v=vs.85).aspx
private static KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(512, 16384, 64) };
throw new CryptographicException(SR.GetString(SR.Cryptography_UnsupportedPaddingMode));
}
}
+#endif
}
}
public static bool IgnoreVirtualChanges { get; set; }
public static bool IgnoreAddedPropertySetters { get; set; }
+ public static bool IgnoreNonbreaking { get; set; }
+
public static bool Lax;
public static bool Colorize = true;
}
-
class Program {
public static int Main (string[] args)
v => State.IgnoreVirtualChanges = v != null
},
{ "c|colorize:", "Colorize HTML output", v => State.Colorize = string.IsNullOrEmpty (v) ? true : bool.Parse (v) },
- { "x|lax", "Ignore duplicate XML entries", v => State.Lax = true }
+ { "x|lax", "Ignore duplicate XML entries", v => State.Lax = true },
+ { "ignore-nonbreaking", "Ignore all nonbreaking changes", v => State.IgnoreNonbreaking = true }
};
try {
showHelp = true;
}
+ if (State.IgnoreNonbreaking) {
+ State.IgnoreAddedPropertySetters = true;
+ State.IgnoreVirtualChanges = true;
+ State.IgnoreNew.Add (new Regex (".*"));
+ State.IgnoreAdded.Add (new Regex (".*"));
+ }
+
if (showHelp || extra == null || extra.Count < 2 || extra.Count > 3) {
Console.WriteLine (@"Usage: mono-api-html [options] <reference.xml> <assembly.xml> [diff.html]");
Console.WriteLine ();
} else {
file.WriteLine ("<h1>{0}.dll vs {1}.dll</h1>", ac.SourceAssembly, ac.TargetAssembly);
}
- file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
- file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
- file.WriteLine ("<br/>");
+ if (!State.IgnoreNonbreaking) {
+ file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
+ file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
+ file.WriteLine ("<br/>");
+ }
file.WriteLine ("<div data-is-topmost>");
file.Write (diffHtml);
file.WriteLine ("</div> <!-- end topmost div -->");
Indent ().WriteLine ("}");
}
+ //HACK: we don't have hierarchy information here so just check some basic heuristics for now
+ bool IsBaseChangeCompatible (string source, string target)
+ {
+ if (source == "System.Object")
+ return true;
+ if (source == "System.Exception" && target.EndsWith ("Exception", StringComparison.Ordinal))
+ return true;
+ if (source == "System.EventArgs" && target.EndsWith ("EventArgs", StringComparison.Ordinal))
+ return true;
+ if (source == "System.Runtime.InteropServices.SafeHandle" && target.StartsWith ("Microsoft.Win32.SafeHandles.SafeHandle", StringComparison.Ordinal))
+ return true;
+ return false;
+ }
+
public override void Modified (XElement source, XElement target, ApiChanges diff)
{
// hack - there could be changes that we're not monitoring (e.g. attributes properties)
var sb = source.GetAttribute ("base");
var tb = target.GetAttribute ("base");
- if (sb != tb) {
+ if (sb != tb && !(State.IgnoreNonbreaking && IsBaseChangeCompatible (sb, tb))) {
Output.Write ("Modified base type: ");
Output.WriteLine (new ApiChange ().AppendModified (sb, tb, true).Member.ToString ());
}
void RenderFieldAttributes (FieldAttributes source, FieldAttributes target, ApiChange change)
{
- var srcNotSerialized = (source & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
- var tgtNotSerialized = (target & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
- if (srcNotSerialized != tgtNotSerialized) {
- // this is not a breaking change, so only render it if it changed.
- if (srcNotSerialized) {
- change.AppendRemoved ("[NonSerialized]\n");
- } else {
- change.AppendAdded ("[NonSerialized]\n");
+ if (!State.IgnoreNonbreaking) {
+ var srcNotSerialized = (source & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
+ var tgtNotSerialized = (target & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
+ if (srcNotSerialized != tgtNotSerialized) {
+ // this is not a breaking change, so only render it if it changed.
+ if (srcNotSerialized) {
+ change.AppendRemoved ("[NonSerialized]\n");
+ } else {
+ change.AppendAdded ("[NonSerialized]\n");
+ }
}
}
void Modify (ApiChanges modified)
{
foreach (var changes in modified) {
+ if (State.IgnoreNonbreaking && changes.Value.All (c => !c.Breaking))
+ continue;
Output.WriteLine ("<p>{0}:</p>", changes.Key);
Output.WriteLine ("<pre>");
foreach (var element in changes.Value) {
+ if (State.IgnoreNonbreaking && !element.Breaking)
+ continue;
Output.Write ("<div {0}>", element.Breaking ? "data-is-breaking" : "data-is-non-breaking");
foreach (var line in element.Member.ToString ().Split ('\n'))
Output.WriteLine ("\t{0}", line);
if (State.IgnoreRemoved.Any (re => re.IsMatch (GetDescription (item))))
continue;
SetContext (item);
+ if (State.IgnoreNonbreaking && !IsBreakingRemoval (item))
+ continue;
if (!r) {
BeforeRemoving (elements);
r = true;
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<ParameterDefinition> candidate, string expected)
- {
- var builder = new StringBuilder ();
- builder.Append ("(");
-
- for (int i = 0; i < candidate.Count; i++) {
- var parameter = candidate [i];
- if (i > 0)
- builder.Append (", ");
-
- if (parameter.ParameterType.IsSentinel)
- builder.Append ("...,");
-
- var pt = parameter.ParameterType;
- if (!string.IsNullOrEmpty (pt.Namespace)) {
- builder.Append (pt.Namespace);
- builder.Append (".");
- }
-
- 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<ParameterDefinition> 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<string, AssemblyLocationProvider> assemblies;
- HashSet<string> directories;
+ builder.Append (")");
- public LocationProvider () {
- assemblies = new Dictionary<string, AssemblyLocationProvider> ();
- directories = new HashSet<string> ();
+ return builder.ToString () == expected;
}
- public void AddAssembly (string assemblyPath)
+ static void FormatElementType (TypeReference tr, StringBuilder builder)
{
- assemblyPath = Path.GetFullPath (assemblyPath);
- if (assemblies.ContainsKey (assemblyPath))
- return;
-
- if (!File.Exists (assemblyPath))
- throw new ArgumentException ("assemblyPath does not exist: "+ assemblyPath);
-
- var readerParameters = new ReaderParameters { ReadSymbols = true };
- var assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParameters);
-
- var seqPointDataPath = assemblyPath + ".msym";
- if (!File.Exists (seqPointDataPath))
- seqPointDataPath = null;
-
- assemblies.Add (assemblyPath, new AssemblyLocationProvider (assembly, seqPointDataPath));
-
- // TODO: Should use AssemblyName with .net unification rules
- directories.Add (Path.GetDirectoryName (assemblyPath));
-
- foreach (var assemblyRef in assembly.MainModule.AssemblyReferences) {
- string refPath = null;
- foreach (var dir in directories) {
- refPath = Path.Combine (dir, assemblyRef.Name);
- if (File.Exists (refPath))
- break;
- refPath = Path.Combine (dir, assemblyRef.Name + ".dll");
- if (File.Exists (refPath))
- break;
- refPath = Path.Combine (dir, assemblyRef.Name + ".exe");
- if (File.Exists (refPath))
- break;
- refPath = null;
+ var ts = tr as TypeSpecification;
+ if (ts != null) {
+ if (ts.IsByReference) {
+ FormatElementType (ts.ElementType, builder);
+ builder.Append ("&");
+ return;
}
- if (refPath != null)
- AddAssembly (refPath);
- }
- }
- public void AddDirectory (string directory)
- {
- directory = Path.GetFullPath (directory);
- if (!Directory.Exists (directory)) {
- Console.Error.WriteLine ("Directory " + directory + " does not exist.");
- return;
- }
+ var array = ts as ArrayType;
+ if (array != null) {
+ FormatElementType (ts.ElementType, builder);
+ builder.Append ("[");
- directories.Add (directory);
- }
+ for (int ii = 0; ii < array.Rank - 1; ++ii) {
+ builder.Append (",");
+ }
- public SequencePoint TryGetLocation (string typeFullName, string methodSignature, int offset, bool isOffsetIL, uint methodIndex)
- {
- foreach (var assembly in assemblies.Values) {
- var loc = assembly.TryGetLocation (typeFullName, methodSignature, offset, isOffsetIL, methodIndex);
- if (loc != null)
- return loc;
+ builder.Append ("]");
+ return;
+ }
}
- return null;
+ builder.Append (tr.Name);
}
}
}
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
using System.IO;
using System.Collections.Generic;
-namespace Symbolicate
+namespace Mono
{
static class BinaryReaderExtensions
{
--- /dev/null
+using System.Text.RegularExpressions;
+using System.Globalization;
+
+namespace Mono
+{
+ class StackFrameData
+ {
+ static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
+
+ public readonly string TypeFullName;
+ public readonly string MethodSignature;
+ public readonly int Offset;
+ public readonly bool IsILOffset;
+ public readonly uint MethodIndex;
+ public readonly string Line;
+
+ public 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 ("<filename unknown>:0") && LineNumber != -1)
+ return Line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", File, LineNumber));
+
+ return Line;
+ }
+ }
+}
--- /dev/null
+using System.Text.RegularExpressions;
+
+namespace Mono
+{
+ class StackTraceMetadata
+ {
+ static Regex regex = new Regex (@"\[(?<Id>.+)\] (?<Value>.+)");
+
+ public readonly string Id;
+ public readonly string Value;
+ public readonly string Line;
+
+ private StackTraceMetadata (string line, string id, string val)
+ {
+ Line = line;
+ Id = id;
+ Value = val;
+ }
+
+ public static bool TryParse (string line, out StackTraceMetadata metadata)
+ {
+ metadata = null;
+
+ var match = regex.Match (line);
+ if (!match.Success)
+ return false;
+
+ string id = match.Groups ["Id"].Value;
+ string val = match.Groups ["Value"].Value;
+
+ metadata = new StackTraceMetadata (line, id, val);
+
+ return true;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Collections.Generic;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using Mono.Collections.Generic;
+
+namespace Mono
+{
+ public class SymbolManager
+ {
+ string msymDir;
+
+ 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<string, AssemblyLocationProvider> assemblies = new Dictionary<string, AssemblyLocationProvider> ();
+
+ private AssemblyLocationProvider GetOrCreateAssemblyLocationProvider (string mvid)
+ {
+ if (assemblies.ContainsKey (mvid))
+ return assemblies[mvid];
+
+ var mvidDir = Path.Combine (msymDir, mvid);
+ if (!Directory.Exists (mvidDir))
+ 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<string, SeqPointInfo> seqPointInfos = new Dictionary<string, SeqPointInfo> ();
+
+ private SeqPointInfo GetOrCreateSeqPointInfo (string aotid)
+ {
+ if (seqPointInfos.ContainsKey (aotid))
+ return seqPointInfos[aotid];
+
+ var aotidDir = Path.Combine (msymDir, aotid);
+ if (!Directory.Exists (aotidDir))
+ 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
+ }
+ }
+ }
+ }
+}
symbolicate.cs
LocationProvider.cs
SeqPointInfo.cs
+StackFrameData.cs
+StackTraceMetadata.cs
+SymbolManager.cs
+../../class/Mono.Options/Mono.Options/Options.cs
using System;
using System.IO;
+using System.Text;
+using System.Linq;
+using System.Collections.Generic;
using System.Globalization;
-using System.Text.RegularExpressions;
+using Mono.Options;
-namespace Symbolicate
+namespace Mono
{
- public class Program
+ public class Symbolicate
{
- static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
+ class Command {
+ public readonly int MinArgCount;
+ public readonly int MaxArgCount;
+ public readonly Action<List<string>> Action;
+
+ public Command (Action<List<string>> action, int minArgCount = 0, int maxArgCount = int.MaxValue)
+ {
+ Action = action;
+ MinArgCount = minArgCount;
+ MaxArgCount = maxArgCount;
+ }
+ }
public static int Main (String[] args)
{
- if (args.Length < 2) {
- Console.Error.WriteLine ("Usage: symbolicate <assembly path> <input file> [lookup directories]");
- return 1;
- }
+ var showHelp = false;
+ List<string> extra = null;
- var assemblyPath = args [0];
- var inputFile = args [1];
+ Command cmd = null;
- var 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 <msym dir> <input file>");
+ Console.Error.WriteLine (" symbolicate store-symbols <msym dir> [<dir>]+");
+ 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<string> args)
{
- var match = regex.Match (line);
- if (!match.Success)
- return line;
+ var msymDir = args [0];
+ var inputFile = args [1];
- string typeFullName, methodSignature;
- var methodStr = match.Groups ["Method"].Value.Trim ();
- if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
- return line;
+ var symbolManager = new SymbolManager (msymDir);
- var isOffsetIL = !string.IsNullOrEmpty (match.Groups ["IL"].Value);
- var offsetVarName = (isOffsetIL)? "IL" : "NativeOffset";
- var offset = int.Parse (match.Groups [offsetVarName].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+ using (StreamReader r = new StreamReader (inputFile)) {
+ var sb = Process (r, symbolManager);
+ Console.Write (sb.ToString ());
+ }
+ }
- uint methodIndex = 0xffffff;
- if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
- methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
+ private static void StoreSymbolsAction (List<string> args)
+ {
+ var msymDir = args[0];
+ var lookupDirs = args.Skip (1).ToArray ();
- var loc = locProvider.TryGetLocation (typeFullName, methodSignature, offset, isOffsetIL, methodIndex);
- if (loc == null)
- return line;
+ var symbolManager = new SymbolManager (msymDir);
- return line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", loc.Document.Url, loc.StartLine));
+ symbolManager.StoreSymbols (lookupDirs);
}
- static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
+ public static StringBuilder Process (StreamReader reader, SymbolManager symbolManager)
{
- var methodNameEnd = str.IndexOf ('(');
- if (methodNameEnd == -1) {
- typeFullName = methodSignature = null;
- return false;
+ List<StackFrameData> stackFrames = new List<StackFrameData>();
+ List<StackTraceMetadata> metadata = new List<StackTraceMetadata>();
+ StringBuilder sb = new StringBuilder ();
+ bool linesEnded = false;
+
+ for (var line = reader.ReadLine (); line != null; line = reader.ReadLine ()) {
+ StackFrameData sfData;
+ if (!linesEnded && StackFrameData.TryParse (line, out sfData)) {
+ stackFrames.Add (sfData);
+ continue;
+ }
+
+ if (stackFrames.Count > 0) {
+ linesEnded = true;
+
+ StackTraceMetadata stMetadata;
+ if (StackTraceMetadata.TryParse (line, out stMetadata)) {
+ metadata.Add (stMetadata);
+ continue;
+ }
+
+ DumpStackTrace (symbolManager, sb, stackFrames, metadata);
+
+ // Clear lists for next stack trace
+ stackFrames.Clear ();
+ metadata.Clear ();
+ }
+
+ linesEnded = false;
+
+ // Append last line
+ sb.AppendLine (line);
}
- var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
- if (typeNameEnd == -1) {
- typeFullName = methodSignature = null;
- return false;
- }
+ if (stackFrames.Count > 0)
+ DumpStackTrace (symbolManager, sb, stackFrames, metadata);
+
+ return sb;
+ }
+
+ private static void DumpStackTrace (SymbolManager symbolManager, StringBuilder sb, List<StackFrameData> stackFrames, List<StackTraceMetadata> metadata)
+ {
+ string aotid = null;
+ var aotidMetadata = metadata.FirstOrDefault ( m => m.Id == "AOTID" );
+ if (aotidMetadata != null)
+ aotid = aotidMetadata.Value;
- // 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<int, string> ProcessLinesMVID (List<StackTraceMetadata> metadata)
+ {
+ var linesMvid = new Dictionary<int, string> ();
+ var mvidData = metadata.Where ( m => m.Id == "MVID" ).Select ( m => m.Value );
+ foreach (var m in mvidData) {
+ var s1 = m.Split (new char[] {' '}, 2);
+ var mvid = s1 [0];
+ var lines = s1 [1].Split (',');
+ foreach (var line in lines)
+ linesMvid.Add (int.Parse (line), mvid);
+ }
- methodSignature = str.Substring (typeNameEnd + 1);
- return true;
+ return linesMvid;
}
}
-}
\ No newline at end of file
+}
context.h \
error.h \
events.h \
- handles.h \
io.h \
io-trace.h \
io-layer.h \
events.c \
events.h \
event-private.h \
- handles.c \
- handles.h \
- handles-private.h \
io.c \
io.h \
io-portability.c \
wapi_glob.c \
wapi.h \
wapi-private.h \
+ wapi.c \
wthreads.c
#include <errno.h>
#include "mono/io-layer/wapi.h"
+#include "mono/io-layer/wapi-private.h"
#include "mono/utils/mono-once.h"
static pthread_key_t error_key;
static mono_once_t error_key_once=MONO_ONCE_INIT;
-extern gboolean _wapi_has_shut_down;
static void error_init(void)
{
#include <glib.h>
#include <pthread.h>
-extern struct _WapiHandleOps _wapi_event_ops;
-extern struct _WapiHandleOps _wapi_namedevent_ops;
-
-extern void _wapi_event_details (gpointer handle_info);
+#include "wapi-private.h"
struct _WapiHandle_event
{
struct _WapiHandle_namedevent
{
+ struct _WapiHandle_event e;
WapiSharedNamespace sharedns;
- gboolean manual;
- guint32 set_count;
};
+void
+_wapi_event_init (void);
+
#endif /* _WAPI_EVENT_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/event-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static void event_signal(gpointer handle);
static gboolean event_own (gpointer handle);
+static void event_details (gpointer data);
+static const gchar* event_typename (void);
+static gsize event_typesize (void);
static void namedevent_signal (gpointer handle);
static gboolean namedevent_own (gpointer handle);
+static void namedevent_details (gpointer data);
+static const gchar* namedevent_typename (void);
+static gsize namedevent_typesize (void);
-struct _WapiHandleOps _wapi_event_ops = {
+static MonoW32HandleOps _wapi_event_ops = {
NULL, /* close */
event_signal, /* signal */
event_own, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ event_details, /* details */
+ event_typename, /* typename */
+ event_typesize, /* typesize */
};
-struct _WapiHandleOps _wapi_namedevent_ops = {
+static MonoW32HandleOps _wapi_namedevent_ops = {
NULL, /* close */
namedevent_signal, /* signal */
namedevent_own, /* own */
NULL, /* is_owned */
+ NULL, /* special_wait */
+ NULL, /* prewait */
+ namedevent_details, /* details */
+ namedevent_typename, /* typename */
+ namedevent_typesize, /* typesize */
};
-static gboolean event_pulse (gpointer handle);
-static gboolean event_reset (gpointer handle);
-static gboolean event_set (gpointer handle);
+void
+_wapi_event_init (void)
+{
+ mono_w32handle_register_ops (MONO_W32HANDLE_EVENT, &_wapi_event_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDEVENT, &_wapi_namedevent_ops);
-static gboolean namedevent_pulse (gpointer handle);
-static gboolean namedevent_reset (gpointer handle);
-static gboolean namedevent_set (gpointer handle);
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_EVENT,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDEVENT,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+}
-static struct
+static const char* event_handle_type_to_string (MonoW32HandleType type)
{
- gboolean (*pulse)(gpointer handle);
- gboolean (*reset)(gpointer handle);
- gboolean (*set)(gpointer handle);
-} event_ops[WAPI_HANDLE_COUNT] = {
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {event_pulse, event_reset, event_set},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {namedevent_pulse, namedevent_reset, namedevent_set},
-};
+ switch (type) {
+ case MONO_W32HANDLE_EVENT: return "event";
+ case MONO_W32HANDLE_NAMEDEVENT: return "named event";
+ default:
+ g_assert_not_reached ();
+ }
+}
-void _wapi_event_details (gpointer handle_info)
+static gboolean event_handle_own (gpointer handle, MonoW32HandleType type)
{
- struct _WapiHandle_event *event = (struct _WapiHandle_event *)handle_info;
-
- g_print ("manual: %s", event->manual?"TRUE":"FALSE");
-}
+ struct _WapiHandle_event *event_handle;
+ gboolean ok;
+
+ ok = mono_w32handle_lookup (handle, type, (gpointer *)&event_handle);
+ if (!ok) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
+ }
-static mono_once_t event_ops_once=MONO_ONCE_INIT;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
-static void event_ops_init (void)
-{
- _wapi_handle_register_capabilities (WAPI_HANDLE_EVENT,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
- _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDEVENT,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
+ if (!event_handle->manual) {
+ g_assert (event_handle->set_count > 0);
+ event_handle->set_count --;
+
+ if (event_handle->set_count == 0)
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+ }
+
+ return TRUE;
}
static void event_signal(gpointer handle)
static gboolean event_own (gpointer handle)
{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up event handle %p", __func__,
- handle);
- return (FALSE);
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning event handle %p", __func__, handle);
-
- if(event_handle->manual==FALSE) {
- g_assert (event_handle->set_count > 0);
-
- if (--event_handle->set_count == 0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
- }
-
- return(TRUE);
+ return event_handle_own (handle, MONO_W32HANDLE_EVENT);
}
static void namedevent_signal (gpointer handle)
/* NB, always called with the shared handle lock held */
static gboolean namedevent_own (gpointer handle)
{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named event handle %p", __func__, handle);
+ return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT);
+}
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- if (namedevent_handle->manual == FALSE) {
- g_assert (namedevent_handle->set_count > 0);
-
- if (--namedevent_handle->set_count == 0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
- }
-
- return (TRUE);
+static void event_details (gpointer data)
+{
+ struct _WapiHandle_event *event = (struct _WapiHandle_event *)data;
+ g_print ("manual: %s, set_count: %d",
+ event->manual ? "TRUE" : "FALSE", event->set_count);
}
-static gpointer event_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gboolean manual, gboolean initial)
+
+static void namedevent_details (gpointer data)
+{
+ struct _WapiHandle_namedevent *namedevent = (struct _WapiHandle_namedevent *)data;
+ g_print ("manual: %s, set_count: %d, name: \"%s\"",
+ namedevent->e.manual ? "TRUE" : "FALSE", namedevent->e.set_count, namedevent->sharedns.name);
+}
+
+static const gchar* event_typename (void)
+{
+ return "Event";
+}
+
+static gsize event_typesize (void)
+{
+ return sizeof (struct _WapiHandle_event);
+}
+
+static const gchar* namedevent_typename (void)
+{
+ return "N.Event";
+}
+
+static gsize namedevent_typesize (void)
+{
+ return sizeof (struct _WapiHandle_namedevent);
+}
+
+static gpointer event_handle_create (struct _WapiHandle_event *event_handle, MonoW32HandleType type, gboolean manual, gboolean initial)
{
- struct _WapiHandle_event event_handle = {0};
gpointer handle;
int thr_ret;
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if an event
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating unnamed event", __func__);
-
- event_handle.manual = manual;
- event_handle.set_count = 0;
+ event_handle->manual = manual;
+ event_handle->set_count = (initial && !manual) ? 1 : 0;
- if (initial == TRUE) {
- if (manual == FALSE) {
- event_handle.set_count = 1;
- }
- }
-
- handle = _wapi_handle_new (WAPI_HANDLE_EVENT, &event_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating event handle", __func__);
+ handle = mono_w32handle_new (type, event_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ g_warning ("%s: error creating %s handle",
+ __func__, event_handle_type_to_string (type));
SetLastError (ERROR_GEN_FAILURE);
- return(NULL);
+ return NULL;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (initial == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created new event handle %p", __func__, handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ if (initial)
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- return(handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+
+ return handle;
+}
+
+static gpointer event_create (gboolean manual, gboolean initial)
+{
+ struct _WapiHandle_event event_handle;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, event_handle_type_to_string (MONO_W32HANDLE_EVENT));
+ return event_handle_create (&event_handle, MONO_W32HANDLE_EVENT, manual, initial);
}
-static gpointer namedevent_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gboolean manual, gboolean initial,
- const gunichar2 *name G_GNUC_UNUSED)
+static gpointer namedevent_create (gboolean manual, gboolean initial, const gunichar2 *name G_GNUC_UNUSED)
{
- struct _WapiHandle_namedevent namedevent_handle = {{{0}}, 0};
gpointer handle;
gchar *utf8_name;
int thr_ret;
-
- /* w32 seems to guarantee that opening named objects can't
- * race each other
- */
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, event_handle_type_to_string (MONO_W32HANDLE_NAMEDEVENT));
+
+ /* w32 seems to guarantee that opening named objects can't race each other */
thr_ret = _wapi_namespace_lock ();
g_assert (thr_ret == 0);
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if an event
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named event [%s]", __func__, utf8_name);
-
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDEVENT,
- utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
- /* The name has already been used for a different
- * object.
- */
+
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDEVENT, utf8_name);
+ if (handle == INVALID_HANDLE_VALUE) {
+ /* The name has already been used for a different object. */
+ handle = NULL;
SetLastError (ERROR_INVALID_HANDLE);
- goto cleanup;
} else if (handle) {
- /* Not an error, but this is how the caller is
- * informed that the event wasn't freshly created
- */
+ /* Not an error, but this is how the caller is informed that the event wasn't freshly created */
SetLastError (ERROR_ALREADY_EXISTS);
+
+ /* this is used as creating a new handle */
+ mono_w32handle_ref (handle);
} else {
- /* A new named event, so create both the private and
- * shared parts
- */
-
+ /* A new named event */
+ struct _WapiHandle_namedevent namedevent_handle;
+
strncpy (&namedevent_handle.sharedns.name [0], utf8_name, MAX_PATH);
namedevent_handle.sharedns.name [MAX_PATH] = '\0';
- namedevent_handle.manual = manual;
- namedevent_handle.set_count = 0;
-
- if (initial == TRUE) {
- if (manual == FALSE) {
- namedevent_handle.set_count = 1;
- }
- }
-
- handle = _wapi_handle_new (WAPI_HANDLE_NAMEDEVENT,
- &namedevent_handle);
-
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating event handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Set the initial state, as this is a completely new
- * handle
- */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (initial == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ handle = event_handle_create ((struct _WapiHandle_event*) &namedevent_handle, MONO_W32HANDLE_NAMEDEVENT, manual, initial);
}
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning event handle %p", __func__, handle);
-
-cleanup:
g_free (utf8_name);
- _wapi_namespace_unlock (NULL);
-
- return handle;
+ thr_ret = _wapi_namespace_unlock (NULL);
+ g_assert (thr_ret == 0);
+ return handle;
}
gboolean manual, gboolean initial,
const gunichar2 *name G_GNUC_UNUSED)
{
- mono_once (&event_ops_once, event_ops_init);
-
- if (name == NULL) {
- return(event_create (security, manual, initial));
- } else {
- return(namedevent_create (security, manual, initial, name));
- }
-}
-
-static gboolean event_pulse (gpointer handle)
-{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up event handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Pulsing event handle %p", __func__, handle);
-
- if (event_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- event_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (event_handle->manual == TRUE) {
- /* For a manual-reset event, we're about to try and
- * get the handle lock again, so give other threads a
- * chance
- */
- sched_yield ();
-
- /* Reset the handle signal state */
- /* I'm not sure whether or not we need a barrier here
- * to make sure that all threads waiting on the event
- * have proceeded. Currently we rely on broadcasting
- * a condition.
- */
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on event handle %p",
- __func__, handle);
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
-
- return(TRUE);
-}
-
-static gboolean namedevent_pulse (gpointer handle)
-{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Pulsing named event handle %p", __func__, handle);
-
- if (namedevent_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- namedevent_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (namedevent_handle->manual == TRUE) {
- /* For a manual-reset event, we're about to try and
- * get the handle lock again, so give other processes
- * a chance
- */
- _wapi_handle_spin (200);
-
- /* Reset the handle signal state */
- /* I'm not sure whether or not we need a barrier here
- * to make sure that all threads waiting on the event
- * have proceeded. Currently we rely on waiting for
- * twice the shared handle poll interval.
- */
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on event handle %p",
- __func__, handle);
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if an event
+ * was freshly created
+ */
+ SetLastError (ERROR_SUCCESS);
- return(TRUE);
+ return name ? namedevent_create (manual, initial, name) : event_create (manual, initial);
}
/**
*/
gboolean PulseEvent(gpointer handle)
{
- WapiHandleType type;
-
+ MonoW32HandleType type;
+ struct _WapiHandle_event *event_handle;
+ int thr_ret;
+
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
- type = _wapi_handle_type (handle);
-
- if (event_ops[type].pulse == NULL) {
+
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_EVENT:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(event_ops[type].pulse (handle));
-}
-static gboolean event_reset (gpointer handle)
-{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up event handle %p",
- __func__, handle);
- return(FALSE);
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
}
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Resetting event handle %p", __func__, handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pulsing %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (_wapi_handle_issignalled (handle) == FALSE) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No need to reset event handle %p", __func__,
- handle);
+
+ if (!event_handle->manual) {
+ event_handle->set_count = 1;
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
} else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on event handle %p",
- __func__, handle);
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
-
- event_handle->set_count = 0;
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- return(TRUE);
-}
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
-static gboolean namedevent_reset (gpointer handle)
-{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
+ /* For a manual-reset event, we're about to try and get the handle
+ * lock again, so give other threads a chance */
+ sched_yield ();
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Resetting named event handle %p", __func__, handle);
+ /* Reset the handle signal state */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (_wapi_handle_issignalled (handle) == FALSE) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No need to reset named event handle %p",
- __func__, handle);
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on named event handle %p",
- __func__, handle);
+ /* I'm not sure whether or not we need a barrier here to make sure
+ * that all threads waiting on the event have proceeded. Currently
+ * we rely on broadcasting a condition. */
+
+ thr_ret = mono_w32handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
}
-
- namedevent_handle->set_count = 0;
-
- thr_ret = _wapi_handle_unlock_handle (handle);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
- return(TRUE);
+
+ return TRUE;
}
/**
*/
gboolean ResetEvent(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
+ struct _WapiHandle_event *event_handle;
+ int thr_ret;
+
+ SetLastError (ERROR_SUCCESS);
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- type = _wapi_handle_type (handle);
-
- if (event_ops[type].reset == NULL) {
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_EVENT:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(event_ops[type].reset (handle));
-}
-static gboolean event_set (gpointer handle)
-{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up event handle %p", __func__,
- handle);
- return(FALSE);
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
}
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Setting event handle %p", __func__, handle);
-
- if (event_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- event_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: resetting %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- return(TRUE);
-}
-static gboolean namedevent_set (gpointer handle)
-{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Setting named event handle %p", __func__, handle);
-
- if (namedevent_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ if (!mono_w32handle_issignalled (handle)) {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: no need to reset %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
} else {
- namedevent_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: obtained write lock on %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
}
- thr_ret = _wapi_handle_unlock_handle (handle);
+ event_handle->set_count = 0;
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- return(TRUE);
+ return TRUE;
}
/**
*/
gboolean SetEvent(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
+ struct _WapiHandle_event *event_handle;
+ int thr_ret;
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- type = _wapi_handle_type (handle);
-
- if (event_ops[type].set == NULL) {
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_EVENT:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(event_ops[type].set (handle));
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
+ }
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ if (!event_handle->manual) {
+ event_handle->set_count = 1;
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+ } else {
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+ }
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ return TRUE;
}
gpointer OpenEvent (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name)
gpointer handle;
gchar *utf8_name;
int thr_ret;
-
- mono_once (&event_ops_once, event_ops_init);
/* w32 seems to guarantee that opening named objects can't
* race each other
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named event [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDEVENT,
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDEVENT,
utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
+ if (handle == INVALID_HANDLE_VALUE) {
/* The name has already been used for a different
* object.
*/
+++ /dev/null
-/*
- * handles-private.h: Internal operations on handles
- *
- * Author:
- * Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Novell, Inc.
- */
-
-#ifndef _WAPI_HANDLES_PRIVATE_H_
-#define _WAPI_HANDLES_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/shared.h>
-#include <mono/utils/atomic.h>
-
-#define _WAPI_PRIVATE_MAX_SLOTS (1024 * 16)
-#define _WAPI_PRIVATE_HANDLES(x) (_wapi_private_handles [x / _WAPI_HANDLE_INITIAL_COUNT][x % _WAPI_HANDLE_INITIAL_COUNT])
-#define _WAPI_PRIVATE_HAVE_SLOT(x) ((GPOINTER_TO_UINT (x) / _WAPI_PRIVATE_MAX_SLOTS) < _WAPI_PRIVATE_MAX_SLOTS && \
- _wapi_private_handles [GPOINTER_TO_UINT (x) / _WAPI_HANDLE_INITIAL_COUNT] != NULL)
-#define _WAPI_PRIVATE_VALID_SLOT(x) (((x) / _WAPI_HANDLE_INITIAL_COUNT) < _WAPI_PRIVATE_MAX_SLOTS)
-
-#undef DEBUG
-
-extern struct _WapiHandleUnshared *_wapi_private_handles [];
-
-extern guint32 _wapi_fd_reserve;
-extern gpointer _wapi_global_signal_handle;
-extern mono_mutex_t *_wapi_global_signal_mutex;
-extern mono_cond_t *_wapi_global_signal_cond;
-extern int _wapi_sem_id;
-extern gboolean _wapi_has_shut_down;
-
-extern pid_t _wapi_getpid (void);
-extern gpointer _wapi_handle_new (WapiHandleType type,
- gpointer handle_specific);
-extern gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
- gpointer handle_specific);
-extern gboolean _wapi_lookup_handle (gpointer handle, WapiHandleType type,
- gpointer *handle_specific);
-extern gpointer _wapi_search_handle (WapiHandleType type,
- gboolean (*check)(gpointer, gpointer),
- gpointer user_data,
- gpointer *handle_specific,
- gboolean search_shared);
-extern gpointer _wapi_search_handle_namespace (WapiHandleType type,
- gchar *utf8_name);
-extern void _wapi_handle_ref (gpointer handle);
-extern void _wapi_handle_unref (gpointer handle);
-extern void _wapi_handle_register_capabilities (WapiHandleType type,
- WapiHandleCapability caps);
-extern gboolean _wapi_handle_test_capabilities (gpointer handle,
- WapiHandleCapability caps);
-extern void _wapi_handle_ops_close (gpointer handle, gpointer data);
-extern void _wapi_handle_ops_signal (gpointer handle);
-extern gboolean _wapi_handle_ops_own (gpointer handle);
-extern gboolean _wapi_handle_ops_isowned (gpointer handle);
-extern guint32 _wapi_handle_ops_special_wait (gpointer handle,
- guint32 timeout,
- gboolean alertable);
-extern void _wapi_handle_ops_prewait (gpointer handle);
-
-extern gboolean _wapi_handle_count_signalled_handles (guint32 numhandles,
- gpointer *handles,
- gboolean waitall,
- guint32 *retcount,
- guint32 *lowest);
-extern void _wapi_handle_unlock_handles (guint32 numhandles,
- gpointer *handles);
-extern int _wapi_handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted);
-extern gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
- guint32 new_sharemode,
- guint32 new_access,
- guint32 *old_sharemode,
- guint32 *old_access,
- struct _WapiFileShare **info);
-extern void _wapi_handle_dump (void);
-extern void _wapi_handle_foreach (WapiHandleType type,
- gboolean (*on_each)(gpointer test, gpointer user),
- gpointer user_data);
-void _wapi_free_share_info (_WapiFileShare *share_info);
-
-static inline WapiHandleType _wapi_handle_type (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx) || !_WAPI_PRIVATE_HAVE_SLOT (idx)) {
- return(WAPI_HANDLE_UNUSED); /* An impossible type */
- }
-
- return(_WAPI_PRIVATE_HANDLES(idx).type);
-}
-
-static inline void _wapi_handle_set_signal_state (gpointer handle,
- gboolean state,
- gboolean broadcast)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- struct _WapiHandleUnshared *handle_data;
- int thr_ret;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- handle_data = &_WAPI_PRIVATE_HANDLES(idx);
-
-#ifdef DEBUG
- g_message ("%s: setting state of %p to %s (broadcast %s)", __func__,
- handle, state?"TRUE":"FALSE", broadcast?"TRUE":"FALSE");
-#endif
-
- if (state == TRUE) {
- /* Tell everyone blocking on a single handle */
-
- /* The condition the global signal cond is waiting on is the signalling of
- * _any_ handle. So lock it before setting the signalled state.
- */
- thr_ret = mono_os_mutex_lock (_wapi_global_signal_mutex);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_mutex_lock result %d for global signal mutex", thr_ret);
- g_assert (thr_ret == 0);
-
- /* This function _must_ be called with
- * handle->signal_mutex locked
- */
- handle_data->signalled=state;
-
- if (broadcast == TRUE) {
- thr_ret = mono_os_cond_broadcast (&handle_data->signal_cond);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_cond_broadcast result %d for handle %p", thr_ret, handle);
- g_assert (thr_ret == 0);
- } else {
- thr_ret = mono_os_cond_signal (&handle_data->signal_cond);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_cond_signal result %d for handle %p", thr_ret, handle);
- g_assert (thr_ret == 0);
- }
-
- /* Tell everyone blocking on multiple handles that something
- * was signalled
- */
- thr_ret = mono_os_cond_broadcast (_wapi_global_signal_cond);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_cond_broadcast result %d for handle %p", thr_ret, handle);
- g_assert (thr_ret == 0);
-
- thr_ret = mono_os_mutex_unlock (_wapi_global_signal_mutex);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_mutex_unlock result %d for global signal mutex", thr_ret);
- g_assert (thr_ret == 0);
- } else {
- handle_data->signalled=state;
- }
-}
-
-static inline gboolean _wapi_handle_issignalled (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- return _WAPI_PRIVATE_HANDLES (idx).signalled;
-}
-
-static inline int _wapi_handle_lock_signal_mutex (void)
-{
-#ifdef DEBUG
- g_message ("%s: lock global signal mutex", __func__);
-#endif
-
- return(mono_os_mutex_lock (_wapi_global_signal_mutex));
-}
-
-/* the parameter makes it easier to call from a pthread cleanup handler */
-static inline int _wapi_handle_unlock_signal_mutex (void *unused)
-{
-#ifdef DEBUG
- g_message ("%s: unlock global signal mutex", __func__);
-#endif
-
- return(mono_os_mutex_unlock (_wapi_global_signal_mutex));
-}
-
-static inline int _wapi_handle_lock_handle (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
-
-#ifdef DEBUG
- g_message ("%s: locking handle %p", __func__, handle);
-#endif
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(0);
- }
-
- _wapi_handle_ref (handle);
-
- return(mono_os_mutex_lock (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex));
-}
-
-static inline int _wapi_handle_trylock_handle (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- int ret;
-
-#ifdef DEBUG
- g_message ("%s: locking handle %p", __func__, handle);
-#endif
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(0);
- }
-
- _wapi_handle_ref (handle);
-
- ret = mono_os_mutex_trylock (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
- if (ret != 0) {
- _wapi_handle_unref (handle);
- }
-
- return(ret);
-}
-
-static inline int _wapi_handle_unlock_handle (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- int ret;
-
-#ifdef DEBUG
- g_message ("%s: unlocking handle %p", __func__, handle);
-#endif
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(0);
- }
-
- ret = mono_os_mutex_unlock (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
-
- _wapi_handle_unref (handle);
-
- return(ret);
-}
-
-static inline void _wapi_handle_spin (guint32 ms)
-{
- struct timespec sleepytime;
-
- g_assert (ms < 1000);
-
- sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = ms * 1000000;
-
- nanosleep (&sleepytime, NULL);
-}
-
-static inline int _wapi_namespace_lock (void)
-{
- return(_wapi_shm_sem_lock (_WAPI_SHARED_SEM_NAMESPACE));
-}
-
-/* This signature makes it easier to use in pthread cleanup handlers */
-static inline int _wapi_namespace_unlock (gpointer data G_GNUC_UNUSED)
-{
- return(_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_NAMESPACE));
-}
-
-static inline void _wapi_handle_share_release (struct _WapiFileShare *info)
-{
- int thr_ret;
-
- g_assert (info->handle_refs > 0);
-
- /* Prevent new entries racing with us */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert(thr_ret == 0);
-
- if (InterlockedDecrement ((gint32 *)&info->handle_refs) == 0) {
- _wapi_free_share_info (info);
- }
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-}
-
-#endif /* _WAPI_HANDLES_PRIVATE_H_ */
+++ /dev/null
-/*
- * handles.c: Generic and internal operations on handles
- *
- * Author:
- * Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2011 Novell, Inc.
- * Copyright 2011 Xamarin Inc
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <string.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-# include <sys/mman.h>
-#endif
-#ifdef HAVE_DIRENT_H
-# include <dirent.h>
-#endif
-#include <sys/stat.h>
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/shared.h>
-#include <mono/io-layer/process-private.h>
-#include <mono/io-layer/io-trace.h>
-
-#include <mono/utils/mono-os-mutex.h>
-#include <mono/utils/mono-proclib.h>
-#include <mono/utils/mono-threads.h>
-#include <mono/utils/mono-once.h>
-#include <mono/utils/mono-logger-internals.h>
-#undef DEBUG_REFS
-
-static void (*_wapi_handle_ops_get_close_func (WapiHandleType type))(gpointer, gpointer);
-
-static WapiHandleCapability handle_caps[WAPI_HANDLE_COUNT] = { (WapiHandleCapability)0 };
-static struct _WapiHandleOps *handle_ops[WAPI_HANDLE_COUNT]={
- NULL,
- &_wapi_file_ops,
- &_wapi_console_ops,
- &_wapi_thread_ops,
- &_wapi_sem_ops,
- &_wapi_mutex_ops,
- &_wapi_event_ops,
-#ifndef DISABLE_SOCKETS
- &_wapi_socket_ops,
-#endif
- &_wapi_find_ops,
- &_wapi_process_ops,
- &_wapi_pipe_ops,
- &_wapi_namedmutex_ops,
- &_wapi_namedsem_ops,
- &_wapi_namedevent_ops,
-};
-
-static void _wapi_shared_details (gpointer handle_info);
-
-static void (*handle_details[WAPI_HANDLE_COUNT])(gpointer) = {
- NULL,
- _wapi_file_details,
- _wapi_console_details,
- _wapi_shared_details, /* thread */
- _wapi_sem_details,
- _wapi_mutex_details,
- _wapi_event_details,
- NULL, /* Nothing useful to see in a socket handle */
- NULL, /* Nothing useful to see in a find handle */
- _wapi_shared_details, /* process */
- _wapi_pipe_details,
- _wapi_shared_details, /* namedmutex */
- _wapi_shared_details, /* namedsem */
- _wapi_shared_details, /* namedevent */
-};
-
-const char *_wapi_handle_typename[] = {
- "Unused",
- "File",
- "Console",
- "Thread",
- "Sem",
- "Mutex",
- "Event",
- "Socket",
- "Find",
- "Process",
- "Pipe",
- "N.Mutex",
- "N.Sem",
- "N.Event",
- "Error!!"
-};
-
-/*
- * We can hold _WAPI_PRIVATE_MAX_SLOTS * _WAPI_HANDLE_INITIAL_COUNT handles.
- * If 4M handles are not enough... Oh, well... we will crash.
- */
-#define SLOT_INDEX(x) (x / _WAPI_HANDLE_INITIAL_COUNT)
-#define SLOT_OFFSET(x) (x % _WAPI_HANDLE_INITIAL_COUNT)
-
-struct _WapiHandleUnshared *_wapi_private_handles [_WAPI_PRIVATE_MAX_SLOTS];
-static guint32 _wapi_private_handle_count = 0;
-static guint32 _wapi_private_handle_slot_count = 0;
-
-/*
- * If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
- * it will be NULL. We use this instead of _wapi_fileshare_layout to avoid allocating a
- * 4MB array.
- */
-static GHashTable *file_share_hash;
-static mono_mutex_t file_share_hash_mutex;
-
-#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
-#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
-
-guint32 _wapi_fd_reserve;
-
-/*
- * This is an internal handle which is used for handling waiting for multiple handles.
- * Threads which wait for multiple handles wait on this one handle, and when a handle
- * is signalled, this handle is signalled too.
- */
-gpointer _wapi_global_signal_handle;
-
-/* Point to the mutex/cond inside _wapi_global_signal_handle */
-mono_mutex_t *_wapi_global_signal_mutex;
-mono_cond_t *_wapi_global_signal_cond;
-
-int _wapi_sem_id;
-gboolean _wapi_has_shut_down = FALSE;
-
-/* Use this instead of getpid(), to cope with linuxthreads. It's a
- * function rather than a variable lookup because we need to get at
- * this before share_init() might have been called.
- */
-static pid_t _wapi_pid;
-static mono_once_t pid_init_once = MONO_ONCE_INIT;
-
-static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles);
-
-static void pid_init (void)
-{
- _wapi_pid = getpid ();
-}
-
-pid_t _wapi_getpid (void)
-{
- mono_once (&pid_init_once, pid_init);
-
- return(_wapi_pid);
-}
-
-
-static mono_mutex_t scan_mutex;
-
-static void handle_cleanup (void)
-{
- int i, j, k;
-
- /* Every shared handle we were using ought really to be closed
- * by now, but to make sure just blow them all away. The
- * exiting finalizer thread in particular races us to the
- * program exit and doesn't always win, so it can be left
- * cluttering up the shared file. Anything else left over is
- * really a bug.
- */
- for(i = SLOT_INDEX (0); _wapi_private_handles[i] != NULL; i++) {
- for(j = SLOT_OFFSET (0); j < _WAPI_HANDLE_INITIAL_COUNT; j++) {
- struct _WapiHandleUnshared *handle_data = &_wapi_private_handles[i][j];
- gpointer handle = GINT_TO_POINTER (i*_WAPI_HANDLE_INITIAL_COUNT+j);
-
- for(k = handle_data->ref; k > 0; k--) {
- _wapi_handle_unref_full (handle, TRUE);
- }
- }
- }
-
- _wapi_shm_semaphores_remove ();
-
- if (file_share_hash) {
- g_hash_table_destroy (file_share_hash);
- mono_os_mutex_destroy (&file_share_hash_mutex);
- }
-
- for (i = 0; i < _WAPI_PRIVATE_MAX_SLOTS; ++i)
- g_free (_wapi_private_handles [i]);
-}
-
-int
-wapi_getdtablesize (void)
-{
- return eg_getdtablesize ();
-}
-
-/*
- * wapi_init:
- *
- * Initialize the io-layer.
- */
-void
-wapi_init (void)
-{
- g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
- == WAPI_HANDLE_COUNT);
-
- _wapi_fd_reserve = wapi_getdtablesize ();
-
- /* This is needed by the code in _wapi_handle_new_internal */
- _wapi_fd_reserve = (_wapi_fd_reserve + (_WAPI_HANDLE_INITIAL_COUNT - 1)) & ~(_WAPI_HANDLE_INITIAL_COUNT - 1);
-
- do {
- /*
- * The entries in _wapi_private_handles reserved for fds are allocated lazily to
- * save memory.
- */
- /*
- _wapi_private_handles [idx++] = g_new0 (struct _WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
- */
-
- _wapi_private_handle_count += _WAPI_HANDLE_INITIAL_COUNT;
- _wapi_private_handle_slot_count ++;
- } while(_wapi_fd_reserve > _wapi_private_handle_count);
-
- _wapi_shm_semaphores_init ();
-
- _wapi_io_init ();
- mono_os_mutex_init (&scan_mutex);
-
- _wapi_global_signal_handle = _wapi_handle_new (WAPI_HANDLE_EVENT, NULL);
-
- _wapi_global_signal_cond = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_cond;
- _wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex;
-
- wapi_processes_init ();
-}
-
-void
-wapi_cleanup (void)
-{
- g_assert (_wapi_has_shut_down == FALSE);
-
- _wapi_has_shut_down = TRUE;
-
- _wapi_error_cleanup ();
- _wapi_thread_cleanup ();
- wapi_processes_cleanup ();
- handle_cleanup ();
-}
-
-static size_t _wapi_handle_struct_size (WapiHandleType type)
-{
- size_t type_size;
-
- switch (type) {
- case WAPI_HANDLE_FILE: case WAPI_HANDLE_CONSOLE: case WAPI_HANDLE_PIPE:
- type_size = sizeof (struct _WapiHandle_file);
- break;
- case WAPI_HANDLE_THREAD:
- type_size = sizeof (struct _WapiHandle_thread);
- break;
- case WAPI_HANDLE_SEM:
- type_size = sizeof (struct _WapiHandle_sem);
- break;
- case WAPI_HANDLE_MUTEX:
- type_size = sizeof (struct _WapiHandle_mutex);
- break;
- case WAPI_HANDLE_EVENT:
- type_size = sizeof (struct _WapiHandle_event);
- break;
- case WAPI_HANDLE_SOCKET:
- type_size = sizeof (struct _WapiHandle_socket);
- break;
- case WAPI_HANDLE_FIND:
- type_size = sizeof (struct _WapiHandle_find);
- break;
- case WAPI_HANDLE_PROCESS:
- type_size = sizeof (struct _WapiHandle_process);
- break;
- case WAPI_HANDLE_NAMEDMUTEX:
- type_size = sizeof (struct _WapiHandle_namedmutex);
- break;
- case WAPI_HANDLE_NAMEDSEM:
- type_size = sizeof (struct _WapiHandle_namedsem);
- break;
- case WAPI_HANDLE_NAMEDEVENT:
- type_size = sizeof (struct _WapiHandle_namedevent);
- break;
-
- default:
- g_error ("Unknown WapiHandleType: %d\n", type);
- }
-
- return type_size;
-}
-
-static void _wapi_handle_init (struct _WapiHandleUnshared *handle,
- WapiHandleType type, gpointer handle_specific)
-{
- int thr_ret;
- int type_size;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- handle->type = type;
- handle->signalled = FALSE;
- handle->ref = 1;
-
- thr_ret = mono_os_cond_init (&handle->signal_cond);
- g_assert (thr_ret == 0);
-
- thr_ret = mono_os_mutex_init (&handle->signal_mutex);
- g_assert (thr_ret == 0);
-
- if (handle_specific != NULL) {
- type_size = _wapi_handle_struct_size (type);
- memcpy (&handle->u, handle_specific,
- type_size);
- }
-}
-
-/*
- * _wapi_handle_new_internal:
- * @type: Init handle to this type
- *
- * Search for a free handle and initialize it. Return the handle on
- * success and 0 on failure. This is only called from
- * _wapi_handle_new, and scan_mutex must be held.
- */
-static guint32 _wapi_handle_new_internal (WapiHandleType type,
- gpointer handle_specific)
-{
- guint32 i, k, count;
- static guint32 last = 0;
- gboolean retry = FALSE;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- /* A linear scan should be fast enough. Start from the last
- * allocation, assuming that handles are allocated more often
- * than they're freed. Leave the space reserved for file
- * descriptors
- */
-
- if (last < _wapi_fd_reserve) {
- last = _wapi_fd_reserve;
- } else {
- retry = TRUE;
- }
-
-again:
- count = last;
- for(i = SLOT_INDEX (count); i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (count); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- struct _WapiHandleUnshared *handle = &_wapi_private_handles [i][k];
-
- if(handle->type == WAPI_HANDLE_UNUSED) {
- last = count + 1;
-
- _wapi_handle_init (handle, type, handle_specific);
- return (count);
- }
- count++;
- }
- }
- }
-
- if(retry && last > _wapi_fd_reserve) {
- /* Try again from the beginning */
- last = _wapi_fd_reserve;
- goto again;
- }
-
- /* Will need to expand the array. The caller will sort it out */
-
- return(0);
-}
-
-gpointer
-_wapi_handle_new (WapiHandleType type, gpointer handle_specific)
-{
- guint32 handle_idx = 0;
- gpointer handle;
- int thr_ret;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s", __func__,
- _wapi_handle_typename[type]);
-
- g_assert(!_WAPI_FD_HANDLE(type));
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- while ((handle_idx = _wapi_handle_new_internal (type, handle_specific)) == 0) {
- /* Try and expand the array, and have another go */
- int idx = SLOT_INDEX (_wapi_private_handle_count);
- if (idx >= _WAPI_PRIVATE_MAX_SLOTS) {
- break;
- }
-
- _wapi_private_handles [idx] = g_new0 (struct _WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
-
- _wapi_private_handle_count += _WAPI_HANDLE_INITIAL_COUNT;
- _wapi_private_handle_slot_count ++;
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (handle_idx == 0) {
- /* We ran out of slots */
- handle = _WAPI_HANDLE_INVALID;
- goto done;
- }
-
- /* Make sure we left the space for fd mappings */
- g_assert (handle_idx >= _wapi_fd_reserve);
-
- handle = GUINT_TO_POINTER (handle_idx);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Allocated new handle %p", __func__, handle);
-
-done:
- return(handle);
-}
-
-static void
-init_handles_slot (int idx)
-{
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (_wapi_private_handles [idx] == NULL) {
- _wapi_private_handles [idx] = g_new0 (struct _WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
- g_assert (_wapi_private_handles [idx]);
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-}
-
-gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
- gpointer handle_specific)
-{
- struct _WapiHandleUnshared *handle;
- int thr_ret;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s", __func__,
- _wapi_handle_typename[type]);
-
- g_assert(_WAPI_FD_HANDLE(type));
-
- if (fd >= _wapi_fd_reserve) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d is too big", __func__, fd);
-
- return(GUINT_TO_POINTER (_WAPI_HANDLE_INVALID));
- }
-
- /* Initialize the array entries on demand */
- if (_wapi_private_handles [SLOT_INDEX (fd)] == NULL)
- init_handles_slot (SLOT_INDEX (fd));
-
- handle = &_WAPI_PRIVATE_HANDLES(fd);
-
- if (handle->type != WAPI_HANDLE_UNUSED) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d is already in use!", __func__, fd);
- /* FIXME: clean up this handle? We can't do anything
- * with the fd, cos thats the new one
- */
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Assigning new fd handle %d", __func__, fd);
-
- /* Prevent file share entries racing with us, when the file
- * handle is only half initialised
- */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert(thr_ret == 0);
-
- _wapi_handle_init (handle, type, handle_specific);
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-
- return(GUINT_TO_POINTER(fd));
-}
-
-gboolean
-_wapi_lookup_handle (gpointer handle, WapiHandleType type,
- gpointer *handle_specific)
-{
- struct _WapiHandleUnshared *handle_data;
- guint32 handle_idx = GPOINTER_TO_UINT(handle);
-
- if (!_WAPI_PRIVATE_VALID_SLOT (handle_idx)) {
- return(FALSE);
- }
-
- /* Initialize the array entries on demand */
- if (_wapi_private_handles [SLOT_INDEX (handle_idx)] == NULL)
- init_handles_slot (SLOT_INDEX (handle_idx));
-
- handle_data = &_WAPI_PRIVATE_HANDLES(handle_idx);
-
- if (handle_data->type != type) {
- return(FALSE);
- }
-
- if (handle_specific == NULL) {
- return(FALSE);
- }
-
- *handle_specific = &handle_data->u;
-
- return(TRUE);
-}
-
-void
-_wapi_handle_foreach (WapiHandleType type,
- gboolean (*on_each)(gpointer test, gpointer user),
- gpointer user_data)
-{
- struct _WapiHandleUnshared *handle_data = NULL;
- gpointer ret = NULL;
- guint32 i, k;
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for (i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- handle_data = &_wapi_private_handles [i][k];
-
- if (handle_data->type == type) {
- ret = GUINT_TO_POINTER (i * _WAPI_HANDLE_INITIAL_COUNT + k);
- if (on_each (ret, user_data) == TRUE)
- break;
- }
- }
- }
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-}
-
-/* This might list some shared handles twice if they are already
- * opened by this process, and the check function returns FALSE the
- * first time. Shared handles that are created during the search are
- * unreffed if the check function returns FALSE, so callers must not
- * rely on the handle persisting (unless the check function returns
- * TRUE)
- * The caller owns the returned handle.
- */
-gpointer _wapi_search_handle (WapiHandleType type,
- gboolean (*check)(gpointer test, gpointer user),
- gpointer user_data,
- gpointer *handle_specific,
- gboolean search_shared)
-{
- struct _WapiHandleUnshared *handle_data = NULL;
- gpointer ret = NULL;
- guint32 i, k;
- gboolean found = FALSE;
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for (i = SLOT_INDEX (0); !found && i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- handle_data = &_wapi_private_handles [i][k];
-
- if (handle_data->type == type) {
- ret = GUINT_TO_POINTER (i * _WAPI_HANDLE_INITIAL_COUNT + k);
- if (check (ret, user_data) == TRUE) {
- _wapi_handle_ref (ret);
- found = TRUE;
- break;
- }
- }
- }
- }
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (!found) {
- ret = NULL;
- goto done;
- }
-
- if(handle_specific != NULL) {
- *handle_specific = &handle_data->u;
- }
-
-done:
- return(ret);
-}
-
-/* Returns the offset of the metadata array, or _WAPI_HANDLE_INVALID on error, or NULL for
- * not found
- */
-gpointer _wapi_search_handle_namespace (WapiHandleType type,
- gchar *utf8_name)
-{
- struct _WapiHandleUnshared *handle_data;
- guint32 i, k;
- gpointer ret = NULL;
- int thr_ret;
-
- g_assert(_WAPI_SHARED_NAMESPACE(type));
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s", __func__,
- utf8_name, _wapi_handle_typename[type]);
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
- if (!_wapi_private_handles [i])
- continue;
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- WapiSharedNamespace *sharedns;
-
- handle_data = &_wapi_private_handles [i][k];
-
- /* Check mutex, event, semaphore, timer, job and
- * file-mapping object names. So far only mutex,
- * semaphore and event are implemented.
- */
- if (!_WAPI_SHARED_NAMESPACE (handle_data->type)) {
- continue;
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: found a shared namespace handle at 0x%x (type %s)", __func__, i, _wapi_handle_typename[handle_data->type]);
-
- sharedns=(WapiSharedNamespace *)&handle_data->u;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is [%s]", __func__, sharedns->name);
-
- if (strcmp (sharedns->name, utf8_name) == 0) {
- if (handle_data->type != type) {
- /* Its the wrong type, so fail now */
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x matches name but is wrong type: %s", __func__, i, _wapi_handle_typename[handle_data->type]);
- ret = _WAPI_HANDLE_INVALID;
- goto done;
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x matches name and type", __func__, i);
- ret = handle_data;
- goto done;
- }
- }
- }
- }
-
-done:
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-void _wapi_handle_ref (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- struct _WapiHandleUnshared *handle_data;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Attempting to ref invalid private handle %p", __func__, handle);
- return;
- }
-
- if (_wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Attempting to ref unused handle %p", __func__, handle);
- return;
- }
-
- handle_data = &_WAPI_PRIVATE_HANDLES(idx);
-
- InterlockedIncrement ((gint32 *)&handle_data->ref);
-
-#ifdef DEBUG_REFS
- g_message ("%s: %s handle %p ref now %d", __func__,
- _wapi_handle_typename[_WAPI_PRIVATE_HANDLES (idx).type],
- handle,
- _WAPI_PRIVATE_HANDLES(idx).ref);
-#endif
-}
-
-/* The handle must not be locked on entry to this function */
-static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- gboolean destroy = FALSE, early_exit = FALSE;
- int thr_ret;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- if (_wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
- g_warning ("%s: Attempting to unref unused handle %p",
- __func__, handle);
- return;
- }
-
- /* Possible race condition here if another thread refs the
- * handle between here and setting the type to UNUSED. I
- * could lock a mutex, but I'm not sure that allowing a handle
- * reference to reach 0 isn't an application bug anyway.
- */
- destroy = (InterlockedDecrement ((gint32 *)&_WAPI_PRIVATE_HANDLES(idx).ref) ==0);
-
-#ifdef DEBUG_REFS
- g_message ("%s: %s handle %p ref now %d (destroy %s)", __func__,
- _wapi_handle_typename[_WAPI_PRIVATE_HANDLES (idx).type],
- handle,
- _WAPI_PRIVATE_HANDLES(idx).ref, destroy?"TRUE":"FALSE");
-#endif
-
- if(destroy==TRUE) {
- /* Need to copy the handle info, reset the slot in the
- * array, and _only then_ call the close function to
- * avoid race conditions (eg file descriptors being
- * closed, and another file being opened getting the
- * same fd racing the memset())
- */
- struct _WapiHandleUnshared handle_data;
- WapiHandleType type = _WAPI_PRIVATE_HANDLES(idx).type;
- void (*close_func)(gpointer, gpointer) = _wapi_handle_ops_get_close_func (type);
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Destroying handle %p", __func__, handle);
-
- memcpy (&handle_data, &_WAPI_PRIVATE_HANDLES(idx),
- sizeof (struct _WapiHandleUnshared));
-
- memset (&_WAPI_PRIVATE_HANDLES(idx).u, '\0',
- sizeof(_WAPI_PRIVATE_HANDLES(idx).u));
-
- _WAPI_PRIVATE_HANDLES(idx).type = WAPI_HANDLE_UNUSED;
-
- /* Destroy the mutex and cond var. We hope nobody
- * tried to grab them between the handle unlock and
- * now, but pthreads doesn't have a
- * "unlock_and_destroy" atomic function.
- */
- thr_ret = mono_os_mutex_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
- /*WARNING gross hack to make cleanup not crash when exiting without the whole runtime teardown.*/
- if (thr_ret == EBUSY && ignore_private_busy_handles) {
- early_exit = TRUE;
- } else {
- if (thr_ret != 0)
- g_error ("Error destroying handle %p mutex due to %d\n", handle, thr_ret);
-
- thr_ret = mono_os_cond_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_cond);
- if (thr_ret == EBUSY && ignore_private_busy_handles)
- early_exit = TRUE;
- else if (thr_ret != 0)
- g_error ("Error destroying handle %p cond var due to %d\n", handle, thr_ret);
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (early_exit)
- return;
-
- if (close_func != NULL) {
- close_func (handle, &handle_data.u);
- }
- }
-}
-
-void _wapi_handle_unref (gpointer handle)
-{
- _wapi_handle_unref_full (handle, FALSE);
-}
-
-void _wapi_handle_register_capabilities (WapiHandleType type,
- WapiHandleCapability caps)
-{
- handle_caps[type] = caps;
-}
-
-gboolean _wapi_handle_test_capabilities (gpointer handle,
- WapiHandleCapability caps)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing 0x%x against 0x%x (%d)", __func__,
- handle_caps[type], caps, handle_caps[type] & caps);
-
- return((handle_caps[type] & caps) != 0);
-}
-
-static void (*_wapi_handle_ops_get_close_func (WapiHandleType type))(gpointer, gpointer)
-{
- if (handle_ops[type] != NULL &&
- handle_ops[type]->close != NULL) {
- return (handle_ops[type]->close);
- }
-
- return (NULL);
-}
-
-void _wapi_handle_ops_close (gpointer handle, gpointer data)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->close != NULL) {
- handle_ops[type]->close (handle, data);
- }
-}
-
-void _wapi_handle_ops_signal (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL && handle_ops[type]->signal != NULL) {
- handle_ops[type]->signal (handle);
- }
-}
-
-gboolean _wapi_handle_ops_own (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL && handle_ops[type]->own_handle != NULL) {
- return(handle_ops[type]->own_handle (handle));
- } else {
- return(FALSE);
- }
-}
-
-gboolean _wapi_handle_ops_isowned (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL && handle_ops[type]->is_owned != NULL) {
- return(handle_ops[type]->is_owned (handle));
- } else {
- return(FALSE);
- }
-}
-
-guint32 _wapi_handle_ops_special_wait (gpointer handle, guint32 timeout, gboolean alertable)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(WAIT_FAILED);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->special_wait != NULL) {
- return(handle_ops[type]->special_wait (handle, timeout, alertable));
- } else {
- return(WAIT_FAILED);
- }
-}
-
-void _wapi_handle_ops_prewait (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT (handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- type = _WAPI_PRIVATE_HANDLES (idx).type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->prewait != NULL) {
- handle_ops[type]->prewait (handle);
- }
-}
-
-
-/**
- * CloseHandle:
- * @handle: The handle to release
- *
- * Closes and invalidates @handle, releasing any resources it
- * consumes. When the last handle to a temporary or non-persistent
- * object is closed, that object can be deleted. Closing the same
- * handle twice is an error.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
-gboolean CloseHandle(gpointer handle)
-{
- if (handle == NULL) {
- /* Problem: because we map file descriptors to the
- * same-numbered handle we can't tell the difference
- * between a bogus handle and the handle to stdin.
- * Assume that it's the console handle if that handle
- * exists...
- */
- if (_WAPI_PRIVATE_HANDLES (0).type != WAPI_HANDLE_CONSOLE) {
- SetLastError (ERROR_INVALID_PARAMETER);
- return(FALSE);
- }
- }
- if (handle == _WAPI_HANDLE_INVALID){
- SetLastError (ERROR_INVALID_PARAMETER);
- return(FALSE);
- }
-
- _wapi_handle_unref (handle);
-
- return(TRUE);
-}
-
-/* Lots more to implement here, but this is all we need at the moment */
-gboolean DuplicateHandle (gpointer srcprocess, gpointer src,
- gpointer targetprocess, gpointer *target,
- guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED)
-{
- if (srcprocess != _WAPI_PROCESS_CURRENT ||
- targetprocess != _WAPI_PROCESS_CURRENT) {
- /* Duplicating other process's handles is not supported */
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- if (src == _WAPI_PROCESS_CURRENT) {
- *target = _wapi_process_duplicate ();
- } else if (src == _WAPI_THREAD_CURRENT) {
- g_assert_not_reached ();
- } else {
- _wapi_handle_ref (src);
- *target = src;
- }
-
- return(TRUE);
-}
-
-gboolean _wapi_handle_count_signalled_handles (guint32 numhandles,
- gpointer *handles,
- gboolean waitall,
- guint32 *retcount,
- guint32 *lowest)
-{
- guint32 count, i, iter=0;
- gboolean ret;
- int thr_ret;
- WapiHandleType type;
-
- /* Lock all the handles, with backoff */
-again:
- for(i=0; i<numhandles; i++) {
- gpointer handle = handles[i];
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempting to lock %p", __func__, handle);
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- thr_ret = _wapi_handle_trylock_handle (handle);
-
- if (thr_ret != 0) {
- /* Bummer */
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt failed for %p: %s", __func__,
- handle, strerror (thr_ret));
-
- while (i--) {
- handle = handles[i];
- idx = GPOINTER_TO_UINT(handle);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
-
- /* If iter ever reaches 100 the nanosleep will
- * return EINVAL immediately, but we have a
- * design flaw if that happens.
- */
- iter++;
- if(iter==100) {
- g_warning ("%s: iteration overflow!",
- __func__);
- iter=1;
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Backing off for %d ms", __func__,
- iter*10);
- _wapi_handle_spin (10 * iter);
-
- goto again;
- }
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locked all handles", __func__);
-
- count=0;
- *lowest=numhandles;
-
- for(i=0; i<numhandles; i++) {
- gpointer handle = handles[i];
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Checking handle %p", __func__, handle);
-
- if(((_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_OWN)==TRUE) &&
- (_wapi_handle_ops_isowned (handle) == TRUE)) ||
- (_wapi_handle_issignalled (handle))) {
- count++;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p signalled", __func__,
- handle);
- if(*lowest>i) {
- *lowest=i;
- }
- }
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %d event handles signalled", __func__, count);
-
- if ((waitall == TRUE && count == numhandles) ||
- (waitall == FALSE && count > 0)) {
- ret=TRUE;
- } else {
- ret=FALSE;
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning %d", __func__, ret);
-
- *retcount=count;
-
- return(ret);
-}
-
-void _wapi_handle_unlock_handles (guint32 numhandles, gpointer *handles)
-{
- guint32 i;
- int thr_ret;
-
- for(i=0; i<numhandles; i++) {
- gpointer handle = handles[i];
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, handle);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
-}
-
-static void
-signal_handle_and_unref (gpointer handle)
-{
- mono_cond_t *cond;
- mono_mutex_t *mutex;
- guint32 idx;
-
- g_assert (handle);
-
- /* If we reach here, then interrupt token is set to the flag value, which
- * means that the target thread is either
- * - before the first CAS in timedwait, which means it won't enter the wait.
- * - it is after the first CAS, so it is already waiting, or it will enter
- * the wait, and it will be interrupted by the broadcast. */
- idx = GPOINTER_TO_UINT (handle);
- cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
- mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
-
- mono_os_mutex_lock (mutex);
- mono_os_cond_broadcast (cond);
- mono_os_mutex_unlock (mutex);
-
- _wapi_handle_unref (handle);
-}
-
-int
-_wapi_handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
-{
- guint32 idx;
- int res;
- mono_cond_t *cond;
- mono_mutex_t *mutex;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: waiting for %p (type %s)", __func__, handle,
- _wapi_handle_typename[_wapi_handle_type (handle)]);
-
- if (alerted)
- *alerted = FALSE;
-
- idx = GPOINTER_TO_UINT(handle);
-
- if (alerted) {
- mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
- if (*alerted)
- return 0;
- _wapi_handle_ref (handle);
- }
-
- cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
- mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
-
- if (!poll) {
- res = mono_os_cond_timedwait (cond, mutex, timeout);
- } else {
- /* This is needed when waiting for process handles */
- if (!alerted) {
- /*
- * pthread_cond_(timed)wait() can return 0 even if the condition was not
- * signalled. This happens at least on Darwin. We surface this, i.e., we
- * get spurious wake-ups.
- *
- * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
- */
- res = mono_os_cond_timedwait (cond, mutex, timeout);
- } else {
- if (timeout < 100) {
- /* Real timeout is less than 100ms time */
- res = mono_os_cond_timedwait (cond, mutex, timeout);
- } else {
- res = mono_os_cond_timedwait (cond, mutex, 100);
-
- /* Mask the fake timeout, this will cause
- * another poll if the cond was not really signaled
- */
- if (res == ETIMEDOUT)
- res = 0;
- }
- }
- }
-
- if (alerted) {
- mono_thread_info_uninstall_interrupt (alerted);
- if (!*alerted) {
- /* if it is alerted, then the handle is unref in the interrupt callback */
- _wapi_handle_unref (handle);
- }
- }
-
- return res;
-}
-
-void
-_wapi_free_share_info (_WapiFileShare *share_info)
-{
- file_share_hash_lock ();
- g_hash_table_remove (file_share_hash, share_info);
- file_share_hash_unlock ();
- /* The hashtable dtor frees share_info */
-}
-
-static gint
-wapi_share_info_equal (gconstpointer ka, gconstpointer kb)
-{
- const _WapiFileShare *s1 = (const _WapiFileShare *)ka;
- const _WapiFileShare *s2 = (const _WapiFileShare *)kb;
-
- return (s1->device == s2->device && s1->inode == s2->inode) ? 1 : 0;
-}
-
-static guint
-wapi_share_info_hash (gconstpointer data)
-{
- const _WapiFileShare *s = (const _WapiFileShare *)data;
-
- return s->inode;
-}
-
-gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
- guint32 new_sharemode,
- guint32 new_access,
- guint32 *old_sharemode,
- guint32 *old_access,
- struct _WapiFileShare **share_info)
-{
- struct _WapiFileShare *file_share;
- int thr_ret;
- gboolean exists = FALSE;
-
- /* Prevent new entries racing with us */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert (thr_ret == 0);
-
- _WapiFileShare tmp;
-
- /*
- * Instead of allocating a 4MB array, we use a hash table to keep track of this
- * info. This is needed even if SHM is disabled, to track sharing inside
- * the current process.
- */
- if (!file_share_hash) {
- file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
- mono_os_mutex_init_recursive (&file_share_hash_mutex);
- }
-
- tmp.device = device;
- tmp.inode = inode;
-
- file_share_hash_lock ();
-
- file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
- if (file_share) {
- *old_sharemode = file_share->sharemode;
- *old_access = file_share->access;
- *share_info = file_share;
-
- InterlockedIncrement ((gint32 *)&file_share->handle_refs);
- exists = TRUE;
- } else {
- file_share = g_new0 (_WapiFileShare, 1);
-
- file_share->device = device;
- file_share->inode = inode;
- file_share->opened_by_pid = _wapi_getpid ();
- file_share->sharemode = new_sharemode;
- file_share->access = new_access;
- file_share->handle_refs = 1;
- *share_info = file_share;
-
- g_hash_table_insert (file_share_hash, file_share, file_share);
- }
-
- file_share_hash_unlock ();
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-
- return(exists);
-}
-
-void _wapi_handle_dump (void)
-{
- struct _WapiHandleUnshared *handle_data;
- guint32 i, k;
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- handle_data = &_wapi_private_handles [i][k];
-
- if (handle_data->type == WAPI_HANDLE_UNUSED) {
- continue;
- }
-
- g_print ("%3x [%7s] %s %d ",
- i * _WAPI_HANDLE_INITIAL_COUNT + k,
- _wapi_handle_typename[handle_data->type],
- handle_data->signalled?"Sg":"Un",
- handle_data->ref);
- if (handle_details[handle_data->type])
- handle_details[handle_data->type](&handle_data->u);
- g_print ("\n");
- }
- }
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-}
-
-static void _wapi_shared_details (gpointer handle_info)
-{
- struct _WapiHandle_shared_ref *shared = (struct _WapiHandle_shared_ref *)handle_info;
-
- g_print ("offset: 0x%x", shared->offset);
-}
+++ /dev/null
-/*
- * handles.h: Generic operations on handles
- *
- * Author:
- * Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_HANDLES_H_
-#define _WAPI_HANDLES_H_
-
-#define INVALID_HANDLE_VALUE (gpointer)-1
-
-G_BEGIN_DECLS
-
-extern gboolean CloseHandle (gpointer handle);
-extern gboolean DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target, guint32 access, gboolean inherit, guint32 options);
-
-extern void wapi_init (void);
-extern void wapi_cleanup (void);
-
-int wapi_getdtablesize (void);
-
-G_END_DECLS
-
-#endif /* _WAPI_HANDLES_H_ */
#include <mono/io-layer/io.h>
#include <mono/io-layer/wapi-private.h>
-extern struct _WapiHandleOps _wapi_file_ops;
-extern struct _WapiHandleOps _wapi_console_ops;
-extern struct _WapiHandleOps _wapi_find_ops;
-extern struct _WapiHandleOps _wapi_pipe_ops;
-
extern gboolean _wapi_lock_file_region (int fd, off_t offset, off_t length);
extern gboolean _wapi_unlock_file_region (int fd, off_t offset, off_t length);
-extern void _wapi_file_details (gpointer handle_info);
-extern void _wapi_console_details (gpointer handle_info);
-extern void _wapi_pipe_details (gpointer handle_info);
extern gpointer _wapi_stdhandle_create (int fd, const gchar *name);
/* Currently used for both FILE, CONSOLE and PIPE handle types. This may
#ifdef DISABLE_IO_LAYER_TRACE
#define MONO_TRACE(...)
#else
+#include "mono/utils/mono-logger-internals.h"
#define MONO_TRACE(...) mono_trace (__VA_ARGS__)
#endif
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/timefuncs-private.h>
#include <mono/io-layer/thread-private.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
+
+/*
+ * If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
+ * it will be NULL. We use this instead of _wapi_fileshare_layout to avoid allocating a
+ * 4MB array.
+ */
+static GHashTable *file_share_hash;
+static mono_mutex_t file_share_hash_mutex;
+
+#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
+#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
+
+static void
+_wapi_handle_share_release (_WapiFileShare *share_info)
+{
+ int thr_ret;
+
+ g_assert (share_info->handle_refs > 0);
+
+ /* Prevent new entries racing with us */
+ thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert(thr_ret == 0);
+
+ if (InterlockedDecrement ((gint32 *)&share_info->handle_refs) == 0) {
+ file_share_hash_lock ();
+ g_hash_table_remove (file_share_hash, share_info);
+ file_share_hash_unlock ();
+ }
+
+ thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert (thr_ret == 0);
+}
+
+static gint
+wapi_share_info_equal (gconstpointer ka, gconstpointer kb)
+{
+ const _WapiFileShare *s1 = (const _WapiFileShare *)ka;
+ const _WapiFileShare *s2 = (const _WapiFileShare *)kb;
+
+ return (s1->device == s2->device && s1->inode == s2->inode) ? 1 : 0;
+}
+
+static guint
+wapi_share_info_hash (gconstpointer data)
+{
+ const _WapiFileShare *s = (const _WapiFileShare *)data;
+
+ return s->inode;
+}
+
+static gboolean
+_wapi_handle_get_or_set_share (guint64 device, guint64 inode, guint32 new_sharemode, guint32 new_access,
+ guint32 *old_sharemode, guint32 *old_access, struct _WapiFileShare **share_info)
+{
+ struct _WapiFileShare *file_share;
+ int thr_ret;
+ gboolean exists = FALSE;
+
+ /* Prevent new entries racing with us */
+ thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert (thr_ret == 0);
+
+ _WapiFileShare tmp;
+
+ /*
+ * Instead of allocating a 4MB array, we use a hash table to keep track of this
+ * info. This is needed even if SHM is disabled, to track sharing inside
+ * the current process.
+ */
+ if (!file_share_hash) {
+ file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
+ mono_os_mutex_init_recursive (&file_share_hash_mutex);
+ }
+
+ tmp.device = device;
+ tmp.inode = inode;
+
+ file_share_hash_lock ();
+
+ file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
+ if (file_share) {
+ *old_sharemode = file_share->sharemode;
+ *old_access = file_share->access;
+ *share_info = file_share;
+
+ InterlockedIncrement ((gint32 *)&file_share->handle_refs);
+ exists = TRUE;
+ } else {
+ file_share = g_new0 (_WapiFileShare, 1);
+
+ file_share->device = device;
+ file_share->inode = inode;
+ file_share->opened_by_pid = _wapi_getpid ();
+ file_share->sharemode = new_sharemode;
+ file_share->access = new_access;
+ file_share->handle_refs = 1;
+ *share_info = file_share;
+
+ g_hash_table_insert (file_share_hash, file_share, file_share);
+ }
+
+ file_share_hash_unlock ();
+
+ thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert (thr_ret == 0);
+
+ return(exists);
+}
static void file_close (gpointer handle, gpointer data);
+static void file_details (gpointer data);
+static const gchar* file_typename (void);
+static gsize file_typesize (void);
static WapiFileType file_getfiletype(void);
static gboolean file_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
static guint32 GetDriveTypeFromPath (const gchar *utf8_root_path_name);
/* File handle is only signalled for overlapped IO */
-struct _WapiHandleOps _wapi_file_ops = {
+static MonoW32HandleOps _wapi_file_ops = {
file_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ file_details, /* details */
+ file_typename, /* typename */
+ file_typesize, /* typesize */
};
-void _wapi_file_details (gpointer handle_info)
-{
- struct _WapiHandle_file *file = (struct _WapiHandle_file *)handle_info;
-
- g_print ("[%20s] acc: %c%c%c, shr: %c%c%c, attrs: %5u",
- file->filename,
- file->fileaccess&GENERIC_READ?'R':'.',
- file->fileaccess&GENERIC_WRITE?'W':'.',
- file->fileaccess&GENERIC_EXECUTE?'X':'.',
- file->sharemode&FILE_SHARE_READ?'R':'.',
- file->sharemode&FILE_SHARE_WRITE?'W':'.',
- file->sharemode&FILE_SHARE_DELETE?'D':'.',
- file->attrs);
-}
-
static void console_close (gpointer handle, gpointer data);
+static void console_details (gpointer data);
+static const gchar* console_typename (void);
+static gsize console_typesize (void);
static WapiFileType console_getfiletype(void);
static gboolean console_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
/* Console is mostly the same as file, except it can block waiting for
* input or output
*/
-struct _WapiHandleOps _wapi_console_ops = {
+static MonoW32HandleOps _wapi_console_ops = {
console_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ console_details, /* details */
+ console_typename, /* typename */
+ console_typesize, /* typesize */
};
-void _wapi_console_details (gpointer handle_info)
-{
- _wapi_file_details (handle_info);
-}
+static const gchar* find_typename (void);
+static gsize find_typesize (void);
-/* Find handle has no ops.
- */
-struct _WapiHandleOps _wapi_find_ops = {
+static MonoW32HandleOps _wapi_find_ops = {
NULL, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ NULL, /* details */
+ find_typename, /* typename */
+ find_typesize, /* typesize */
};
static void pipe_close (gpointer handle, gpointer data);
+static void pipe_details (gpointer data);
+static const gchar* pipe_typename (void);
+static gsize pipe_typesize (void);
static WapiFileType pipe_getfiletype (void);
static gboolean pipe_read (gpointer handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped);
/* Pipe handles
*/
-struct _WapiHandleOps _wapi_pipe_ops = {
+static MonoW32HandleOps _wapi_pipe_ops = {
pipe_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ pipe_details, /* details */
+ pipe_typename, /* typename */
+ pipe_typesize, /* typesize */
};
-void _wapi_pipe_details (gpointer handle_info)
-{
- _wapi_file_details (handle_info);
-}
-
static const struct {
/* File, console and pipe handles */
WapiFileType (*getfiletype)(void);
const WapiFileTime *create_time,
const WapiFileTime *last_access,
const WapiFileTime *last_write);
-} io_ops[WAPI_HANDLE_COUNT]={
+} io_ops[MONO_W32HANDLE_COUNT]={
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
/* file */
{file_getfiletype,
NULL, NULL, NULL, NULL, NULL, NULL},
};
-static mono_once_t io_ops_once=MONO_ONCE_INIT;
static gboolean lock_while_writing = FALSE;
-static void io_ops_init (void)
-{
-/* _wapi_handle_register_capabilities (WAPI_HANDLE_FILE, */
-/* WAPI_HANDLE_CAP_WAIT); */
-/* _wapi_handle_register_capabilities (WAPI_HANDLE_CONSOLE, */
-/* WAPI_HANDLE_CAP_WAIT); */
-
- if (g_getenv ("MONO_STRICT_IO_EMULATION") != NULL) {
- lock_while_writing = TRUE;
- }
-}
-
/* Some utility functions.
*/
close (fd);
}
+static void file_details (gpointer data)
+{
+ struct _WapiHandle_file *file = (struct _WapiHandle_file *)data;
+
+ g_print ("[%20s] acc: %c%c%c, shr: %c%c%c, attrs: %5u",
+ file->filename,
+ file->fileaccess&GENERIC_READ?'R':'.',
+ file->fileaccess&GENERIC_WRITE?'W':'.',
+ file->fileaccess&GENERIC_EXECUTE?'X':'.',
+ file->sharemode&FILE_SHARE_READ?'R':'.',
+ file->sharemode&FILE_SHARE_WRITE?'W':'.',
+ file->sharemode&FILE_SHARE_DELETE?'D':'.',
+ file->attrs);
+}
+
+static const gchar* file_typename (void)
+{
+ return "File";
+}
+
+static gsize file_typesize (void)
+{
+ return sizeof (struct _WapiHandle_file);
+}
+
static WapiFileType file_getfiletype(void)
{
return(FILE_TYPE_DISK);
gboolean ok;
int fd, ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
int ret, fd;
off_t current_pos = 0;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
int whence, fd;
guint32 ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
off_t pos;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
int ret;
int fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
guint64 create_ticks, access_ticks, write_ticks;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
guint64 access_ticks, write_ticks;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
}
}
+static void console_details (gpointer data)
+{
+ file_details (data);
+}
+
+static const gchar* console_typename (void)
+{
+ return "Console";
+}
+
+static gsize console_typesize (void)
+{
+ return sizeof (struct _WapiHandle_file);
+}
+
static WapiFileType console_getfiletype(void)
{
return(FILE_TYPE_CHAR);
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&console_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up console handle %p", __func__,
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&console_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up console handle %p", __func__,
return(TRUE);
}
+static const gchar* find_typename (void)
+{
+ return "Find";
+}
+
+static gsize find_typesize (void)
+{
+ return sizeof (struct _WapiHandle_find);
+}
+
static void pipe_close (gpointer handle, gpointer data)
{
struct _WapiHandle_file *pipe_handle = (struct _WapiHandle_file*)data;
close (fd);
}
+static void pipe_details (gpointer data)
+{
+ file_details (data);
+}
+
+static const gchar* pipe_typename (void)
+{
+ return "Pipe";
+}
+
+static gsize pipe_typesize (void)
+{
+ return sizeof (struct _WapiHandle_file);
+}
+
static WapiFileType pipe_getfiletype(void)
{
return(FILE_TYPE_PIPE);
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
(gpointer *)&pipe_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up pipe handle %p", __func__,
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
(gpointer *)&pipe_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up pipe handle %p", __func__,
mode_t perms=0666;
gchar *filename;
int fd, ret;
- WapiHandleType handle_type;
+ MonoW32HandleType handle_type;
struct stat statbuf;
-
- mono_once (&io_ops_once, io_ops_init);
if (attrs & FILE_ATTRIBUTE_TEMPORARY)
perms = 0600;
return(INVALID_HANDLE_VALUE);
}
- if (fd >= _wapi_fd_reserve) {
+ if (fd >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
SetLastError (ERROR_TOO_MANY_OPEN_FILES);
#define S_ISFIFO(m) ((m & S_IFIFO) != 0)
#endif
if (S_ISFIFO (statbuf.st_mode)) {
- handle_type = WAPI_HANDLE_PIPE;
+ handle_type = MONO_W32HANDLE_PIPE;
/* maintain invariant that pipes have no filename */
file_handle.filename = NULL;
g_free (filename);
filename = NULL;
} else if (S_ISCHR (statbuf.st_mode)) {
- handle_type = WAPI_HANDLE_CONSOLE;
+ handle_type = MONO_W32HANDLE_CONSOLE;
} else {
- handle_type = WAPI_HANDLE_FILE;
+ handle_type = MONO_W32HANDLE_FILE;
}
- handle = _wapi_handle_new_fd (handle_type, fd, &file_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new_fd (handle_type, fd, &file_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating file handle", __func__);
g_free (filename);
close (fd);
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 */
}
} else {
/* Add a reference to this handle */
- _wapi_handle_ref (handle);
+ mono_w32handle_ref (handle);
}
done:
gboolean ReadFile(gpointer handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if(io_ops[type].readfile==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
gboolean WriteFile(gpointer handle, gconstpointer buffer, guint32 numbytes,
guint32 *byteswritten, WapiOverlapped *overlapped)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if(io_ops[type].writefile==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
gboolean FlushFileBuffers(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if(io_ops[type].flushfile==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
gboolean SetEndOfFile(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].setendoffile == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
guint32 SetFilePointer(gpointer handle, gint32 movedistance,
gint32 *highmovedistance, WapiSeekMethod method)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].seek == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
WapiFileType GetFileType(gpointer handle)
{
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_HAVE_SLOT (handle)) {
- SetLastError (ERROR_INVALID_HANDLE);
- return(FILE_TYPE_UNKNOWN);
- }
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].getfiletype == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
guint32 GetFileSize(gpointer handle, guint32 *highsize)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].getfilesize == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
gboolean GetFileTime(gpointer handle, WapiFileTime *create_time,
WapiFileTime *last_access, WapiFileTime *last_write)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].getfiletime == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
const WapiFileTime *last_access,
const WapiFileTime *last_write)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].setfiletime == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
find_handle.num = result;
find_handle.count = 0;
- handle = _wapi_handle_new (WAPI_HANDLE_FIND, &find_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new (MONO_W32HANDLE_FIND, &find_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating find handle", __func__);
g_free (dir_part);
g_free (entry_part);
int thr_ret;
gboolean ret = FALSE;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FIND,
(gpointer *)&find_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up find handle %p", __func__,
return(FALSE);
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
retry:
g_free (utf16_basename);
cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
return(ret);
return(FALSE);
}
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FIND,
(gpointer *)&find_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up find handle %p", __func__,
return(FALSE);
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
g_strfreev (find_handle->namelist);
g_free (find_handle->dir_part);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
return(TRUE);
}
int filedes[2];
int ret;
- mono_once (&io_ops_once, io_ops_init);
-
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating pipe", __func__);
ret=pipe (filedes);
return(FALSE);
}
- if (filedes[0] >= _wapi_fd_reserve ||
- filedes[1] >= _wapi_fd_reserve) {
+ if (filedes[0] >= mono_w32handle_fd_reserve ||
+ filedes[1] >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
SetLastError (ERROR_TOO_MANY_OPEN_FILES);
pipe_read_handle.fd = filedes [0];
pipe_read_handle.fileaccess = GENERIC_READ;
- read_handle = _wapi_handle_new_fd (WAPI_HANDLE_PIPE, filedes[0],
+ read_handle = mono_w32handle_new_fd (MONO_W32HANDLE_PIPE, filedes[0],
&pipe_read_handle);
- if (read_handle == _WAPI_HANDLE_INVALID) {
+ if (read_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating pipe read handle", __func__);
close (filedes[0]);
close (filedes[1]);
pipe_write_handle.fd = filedes [1];
pipe_write_handle.fileaccess = GENERIC_WRITE;
- write_handle = _wapi_handle_new_fd (WAPI_HANDLE_PIPE, filedes[1],
+ write_handle = mono_w32handle_new_fd (MONO_W32HANDLE_PIPE, filedes[1],
&pipe_write_handle);
- if (write_handle == _WAPI_HANDLE_INVALID) {
+ if (write_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating pipe write handle", __func__);
- _wapi_handle_unref (read_handle);
+ mono_w32handle_unref (read_handle);
close (filedes[0]);
close (filedes[1]);
}
#endif
-
void
_wapi_io_init (void)
{
mono_os_mutex_init (&stdhandle_mutex);
+
+ mono_w32handle_register_ops (MONO_W32HANDLE_FILE, &_wapi_file_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_CONSOLE, &_wapi_console_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_FIND, &_wapi_find_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_PIPE, &_wapi_pipe_ops);
+
+/* mono_w32handle_register_capabilities (MONO_W32HANDLE_FILE, */
+/* MONO_W32HANDLE_CAP_WAIT); */
+/* mono_w32handle_register_capabilities (MONO_W32HANDLE_CONSOLE, */
+/* MONO_W32HANDLE_CAP_WAIT); */
+
+ if (g_getenv ("MONO_STRICT_IO_EMULATION"))
+ lock_while_writing = TRUE;
+}
+
+void
+_wapi_io_cleanup (void)
+{
+ if (file_share_hash) {
+ g_hash_table_destroy (file_share_hash);
+ mono_os_mutex_destroy (&file_share_hash_mutex);
+ }
}
extern void _wapi_io_init (void);
+extern void _wapi_io_cleanup (void);
G_END_DECLS
#include <errno.h>
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
gboolean
_wapi_lock_file_region (int fd, off_t offset, off_t length)
off_t offset, length;
int fd = GPOINTER_TO_UINT(handle);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
off_t offset, length;
int fd = GPOINTER_TO_UINT(handle);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
#include <pthread.h>
#include <sys/types.h>
-extern struct _WapiHandleOps _wapi_mutex_ops;
-extern struct _WapiHandleOps _wapi_namedmutex_ops;
-
-extern void _wapi_mutex_details (gpointer handle_info);
+#include "wapi-private.h"
struct _WapiHandle_mutex
{
struct _WapiHandle_namedmutex
{
+ struct _WapiHandle_mutex m;
WapiSharedNamespace sharedns;
- pthread_t tid;
- guint32 recursion;
};
+void
+_wapi_mutex_init (void);
+
extern void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid);
#endif /* _WAPI_MUTEX_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static void mutex_signal(gpointer handle);
static gboolean mutex_own (gpointer handle);
static gboolean mutex_is_owned (gpointer handle);
+static void mutex_prewait (gpointer handle);
+static void mutex_details (gpointer data);
+static const gchar* mutex_typename (void);
+static gsize mutex_typesize (void);
static void namedmutex_signal (gpointer handle);
static gboolean namedmutex_own (gpointer handle);
static gboolean namedmutex_is_owned (gpointer handle);
static void namedmutex_prewait (gpointer handle);
+static void namedmutex_details (gpointer data);
+static const gchar* namedmutex_typename (void);
+static gsize namedmutex_typesize (void);
-struct _WapiHandleOps _wapi_mutex_ops = {
+static MonoW32HandleOps _wapi_mutex_ops = {
NULL, /* close */
mutex_signal, /* signal */
mutex_own, /* own */
mutex_is_owned, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ mutex_prewait, /* prewait */
+ mutex_details, /* details */
+ mutex_typename, /* typename */
+ mutex_typesize, /* typesize */
};
-void _wapi_mutex_details (gpointer handle_info)
-{
- struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)handle_info;
-
-#ifdef PTHREAD_POINTER_ID
- g_print ("own: %5p, count: %5u", mut->tid, mut->recursion);
-#else
- g_print ("own: %5ld, count: %5u", mut->tid, mut->recursion);
-#endif
-}
-
-struct _WapiHandleOps _wapi_namedmutex_ops = {
+static MonoW32HandleOps _wapi_namedmutex_ops = {
NULL, /* close */
namedmutex_signal, /* signal */
namedmutex_own, /* own */
namedmutex_is_owned, /* is_owned */
NULL, /* special_wait */
- namedmutex_prewait /* prewait */
+ namedmutex_prewait, /* prewait */
+ namedmutex_details, /* details */
+ namedmutex_typename, /* typename */
+ namedmutex_typesize, /* typesize */
};
-static gboolean mutex_release (gpointer handle);
-static gboolean namedmutex_release (gpointer handle);
-
-static struct
+void
+_wapi_mutex_init (void)
{
- gboolean (*release)(gpointer handle);
-} mutex_ops[WAPI_HANDLE_COUNT] = {
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {mutex_release},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {namedmutex_release},
-};
-
-static mono_once_t mutex_ops_once=MONO_ONCE_INIT;
+ mono_w32handle_register_ops (MONO_W32HANDLE_MUTEX, &_wapi_mutex_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDMUTEX, &_wapi_namedmutex_ops);
-static void mutex_ops_init (void)
-{
- _wapi_handle_register_capabilities (WAPI_HANDLE_MUTEX,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL | WAPI_HANDLE_CAP_OWN));
- _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDMUTEX,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL | WAPI_HANDLE_CAP_OWN));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_MUTEX,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDMUTEX,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
}
-static void mutex_signal(gpointer handle)
+static const char* mutex_handle_type_to_string (MonoW32HandleType type)
{
- ReleaseMutex(handle);
+ switch (type) {
+ case MONO_W32HANDLE_MUTEX: return "mutex";
+ case MONO_W32HANDLE_NAMEDMUTEX: return "named mutex";
+ default:
+ g_assert_not_reached ();
+ }
}
-static gboolean mutex_own (gpointer handle)
+static gboolean
+mutex_handle_own (gpointer handle, MonoW32HandleType type)
{
struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p", __func__, mutex_handle_type_to_string (type), handle);
+ return FALSE;
}
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p, tid %p, recursion %u",
+ __func__, mutex_handle_type_to_string (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);
+
_wapi_thread_own_mutex (handle);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning mutex handle %p", __func__, handle);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
mutex_handle->tid = pthread_self ();
mutex_handle->recursion++;
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p locked %d times by %ld", __func__,
- handle, mutex_handle->recursion, mutex_handle->tid);
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
- return(TRUE);
+ return TRUE;
}
-static gboolean mutex_is_owned (gpointer handle)
+static gboolean
+mutex_handle_is_owned (gpointer handle, MonoW32HandleType type)
{
struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p", __func__, mutex_handle_type_to_string (type), handle);
+ return FALSE;
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership mutex handle %p", __func__, handle);
- if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p owned by %ld", __func__,
- handle, pthread_self ());
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
- return(TRUE);
+ if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p owned by %p",
+ __func__, mutex_handle_type_to_string (type), handle, (gpointer) pthread_self ());
+ return TRUE;
} else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p not owned by %ld, but locked %d times by %ld", __func__,
- handle, pthread_self (), mutex_handle->recursion, mutex_handle->tid);
-
- return(FALSE);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p not owned by %p, but locked %d times by %p",
+ __func__, mutex_handle_type_to_string (type), handle, (gpointer) pthread_self (), mutex_handle->recursion, (gpointer) mutex_handle->tid);
+ return FALSE;
}
}
-static void namedmutex_signal (gpointer handle)
+static void mutex_signal(gpointer handle)
{
ReleaseMutex(handle);
}
-/* NB, always called with the shared handle lock held */
-static gboolean namedmutex_own (gpointer handle)
+static gboolean mutex_own (gpointer handle)
{
- struct _WapiHandle_namedmutex *namedmutex_handle;
- gboolean ok;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named mutex handle %p", __func__, handle);
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&namedmutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- _wapi_thread_own_mutex (handle);
-
- namedmutex_handle->tid = pthread_self ();
- namedmutex_handle->recursion++;
-
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p locked %d times by %ld", __func__,
- handle, namedmutex_handle->recursion, namedmutex_handle->tid);
-
- return(TRUE);
+ return mutex_handle_own (handle, MONO_W32HANDLE_MUTEX);
}
-static gboolean namedmutex_is_owned (gpointer handle)
+static gboolean mutex_is_owned (gpointer handle)
{
- struct _WapiHandle_namedmutex *namedmutex_handle;
- gboolean ok;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&namedmutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
- }
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership mutex handle %p", __func__, handle);
+ return mutex_handle_is_owned (handle, MONO_W32HANDLE_MUTEX);
+}
- if (namedmutex_handle->recursion > 0 && pthread_equal (namedmutex_handle->tid, pthread_self ())) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p owned by %ld", __func__,
- handle, pthread_self ());
+static void namedmutex_signal (gpointer handle)
+{
+ ReleaseMutex(handle);
+}
- return(TRUE);
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p not owned by %ld, but locked %d times by %ld", __func__,
- handle, pthread_self (), namedmutex_handle->recursion, namedmutex_handle->tid);
+/* NB, always called with the shared handle lock held */
+static gboolean namedmutex_own (gpointer handle)
+{
+ return mutex_handle_own (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
- return(FALSE);
- }
+static gboolean namedmutex_is_owned (gpointer handle)
+{
+ return mutex_handle_is_owned (handle, MONO_W32HANDLE_NAMEDMUTEX);
}
-/* The shared state is not locked when prewait methods are called */
-static void namedmutex_prewait (gpointer handle)
+static void mutex_handle_prewait (gpointer handle, MonoW32HandleType type)
{
/* If the mutex is not currently owned, do nothing and let the
* usual wait carry on. If it is owned, check that the owner
* and assume that process exited abnormally and failed to
* clean up.
*/
- struct _WapiHandle_namedmutex *namedmutex_handle;
- gboolean ok;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&namedmutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
+ struct _WapiHandle_mutex *mutex_handle;
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
return;
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Checking ownership of named mutex handle %p", __func__,
- handle);
- if (namedmutex_handle->recursion == 0) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Named mutex handle %p not owned", __func__,
- handle);
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Named mutex handle %p owned by this process", __func__,
- handle);
- }
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pre-waiting %s handle %p, owned? %s",
+ __func__, mutex_handle_type_to_string (type), handle, mutex_handle->recursion != 0 ? "true" : "false");
}
-static void mutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
+/* The shared state is not locked when prewait methods are called */
+static void mutex_prewait (gpointer handle)
{
- struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
- int thr_ret;
+ mutex_handle_prewait (handle, MONO_W32HANDLE_MUTEX);
+}
+
+/* The shared state is not locked when prewait methods are called */
+static void namedmutex_prewait (gpointer handle)
+{
+ mutex_handle_prewait (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
+
+static void mutex_details (gpointer data)
+{
+ struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)data;
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return;
- }
+#ifdef PTHREAD_POINTER_ID
+ g_print ("own: %5p, count: %5u", mut->tid, mut->recursion);
+#else
+ g_print ("own: %5ld, count: %5u", mut->tid, mut->recursion);
+#endif
+}
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
+static void namedmutex_details (gpointer data)
+{
+ struct _WapiHandle_namedmutex *namedmut = (struct _WapiHandle_namedmutex *)data;
- if (pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Mutex handle %p abandoned!", __func__,
- handle);
+#ifdef PTHREAD_POINTER_ID
+ g_print ("own: %5p, count: %5u, name: \"%s\"",
+ namedmut->m.tid, namedmut->m.recursion, namedmut->sharedns.name);
+#else
+ g_print ("own: %5ld, count: %5u, name: \"%s\"",
+ namedmut->m.tid, namedmut->m.recursion, namedmut->sharedns.name);
+#endif
+}
- mutex_handle->recursion = 0;
- mutex_handle->tid = 0;
-
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
+static const gchar* mutex_typename (void)
+{
+ return "Mutex";
+}
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+static gsize mutex_typesize (void)
+{
+ return sizeof (struct _WapiHandle_mutex);
+}
+
+static const gchar* namedmutex_typename (void)
+{
+ return "N.Mutex";
+}
+
+static gsize namedmutex_typesize (void)
+{
+ return sizeof (struct _WapiHandle_namedmutex);
}
-static void namedmutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
+/* When a thread exits, any mutexes it still holds need to be signalled. */
+void _wapi_mutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
{
- struct _WapiHandle_namedmutex *mutex_handle;
- gboolean ok;
+ MonoW32HandleType type;
+ struct _WapiHandle_mutex *mutex_handle;
int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
+
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_MUTEX:
+ case MONO_W32HANDLE_NAMEDMUTEX:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
return;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandon %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Mutex handle %p abandoned!", __func__,
- handle);
+ if (pthread_equal (mutex_handle->tid, tid)) {
mutex_handle->recursion = 0;
mutex_handle->tid = 0;
-
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-}
-/* When a thread exits, any mutexes it still holds need to be
- * signalled. This function must not be called with the shared handle
- * lock held, as namedmutex_abandon () will try to acquire it
- */
-void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid)
-{
- WapiHandleType type = _wapi_handle_type (data);
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
- if (type == WAPI_HANDLE_MUTEX) {
- mutex_abandon (data, pid, tid);
- } else if (type == WAPI_HANDLE_NAMEDMUTEX) {
- namedmutex_abandon (data, pid, tid);
- } else {
- g_assert_not_reached ();
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoned %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
}
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
}
-static gpointer mutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gboolean owned)
+static gpointer mutex_handle_create (struct _WapiHandle_mutex *mutex_handle, MonoW32HandleType type, gboolean owned)
{
- struct _WapiHandle_mutex mutex_handle = {0};
gpointer handle;
int thr_ret;
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating unnamed mutex", __func__);
-
- handle = _wapi_handle_new (WAPI_HANDLE_MUTEX, &mutex_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating mutex handle", __func__);
+
+ mutex_handle->tid = 0;
+ mutex_handle->recursion = 0;
+
+ handle = mono_w32handle_new (type, mutex_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ g_warning ("%s: error creating %s handle",
+ __func__, mutex_handle_type_to_string (type));
SetLastError (ERROR_GEN_FAILURE);
- return(NULL);
+ return NULL;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if(owned==TRUE) {
- mutex_own (handle);
- } else {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning mutex handle %p", __func__, handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ if (owned)
+ mutex_handle_own (handle, type);
+ else
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
- return(handle);
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ return handle;
+}
+
+static gpointer mutex_create (gboolean owned)
+{
+ struct _WapiHandle_mutex mutex_handle;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, mutex_handle_type_to_string (MONO_W32HANDLE_MUTEX));
+ return mutex_handle_create (&mutex_handle, MONO_W32HANDLE_MUTEX, owned);
}
-static gpointer namedmutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned,
- const gunichar2 *name)
+static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
{
- struct _WapiHandle_namedmutex namedmutex_handle = {{{0}}, 0};
gpointer handle;
gchar *utf8_name;
int thr_ret;
- /* w32 seems to guarantee that opening named objects can't
- * race each other
- */
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, mutex_handle_type_to_string (MONO_W32HANDLE_NAMEDMUTEX));
+
+ /* w32 seems to guarantee that opening named objects can't race each other */
thr_ret = _wapi_namespace_lock ();
g_assert (thr_ret == 0);
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named mutex [%s]", __func__, utf8_name);
-
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX,
- utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
- /* The name has already been used for a different
- * object.
- */
+
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDMUTEX, utf8_name);
+ if (handle == INVALID_HANDLE_VALUE) {
+ /* The name has already been used for a different object. */
+ handle = NULL;
SetLastError (ERROR_INVALID_HANDLE);
- goto cleanup;
} else if (handle) {
- /* Not an error, but this is how the caller is
- * informed that the mutex wasn't freshly created
- */
+ /* Not an error, but this is how the caller is informed that the mutex wasn't freshly created */
SetLastError (ERROR_ALREADY_EXISTS);
+
+ /* this is used as creating a new handle */
+ mono_w32handle_ref (handle);
} else {
- /* A new named mutex, so create both the private and
- * shared parts
- */
-
+ /* A new named mutex */
+ struct _WapiHandle_namedmutex namedmutex_handle;
+
strncpy (&namedmutex_handle.sharedns.name [0], utf8_name, MAX_PATH);
namedmutex_handle.sharedns.name [MAX_PATH] = '\0';
- handle = _wapi_handle_new (WAPI_HANDLE_NAMEDMUTEX,
- &namedmutex_handle);
-
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating mutex handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Set the initial state, as this is a completely new
- * handle
- */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (owned == TRUE) {
- namedmutex_own (handle);
- } else {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ handle = mutex_handle_create ((struct _WapiHandle_mutex*) &namedmutex_handle, MONO_W32HANDLE_NAMEDMUTEX, owned);
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning mutex handle %p", __func__, handle);
-cleanup:
g_free (utf8_name);
- _wapi_namespace_unlock (NULL);
-
+ thr_ret = _wapi_namespace_unlock (NULL);
+ g_assert (thr_ret == 0);
+
return handle;
}
*
* Return value: A new handle, or %NULL on error.
*/
-gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned,
- const gunichar2 *name)
+gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned, const gunichar2 *name)
{
- mono_once (&mutex_ops_once, mutex_ops_init);
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex
+ * was freshly created */
+ SetLastError (ERROR_SUCCESS);
- if (name == NULL) {
- return(mutex_create (security, owned));
- } else {
- return(namedmutex_create (security, owned, name));
- }
+ return name ? namedmutex_create (owned, name) : mutex_create (owned);
}
-static gboolean mutex_release (gpointer handle)
+/**
+ * ReleaseMutex:
+ * @handle: The mutex handle.
+ *
+ * Releases ownership if the mutex handle @handle.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise. This function
+ * fails if the calling thread does not own the mutex @handle.
+ */
+gboolean ReleaseMutex(gpointer handle)
{
+ MonoW32HandleType type;
struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
- pthread_t tid = pthread_self ();
+ pthread_t tid;
int thr_ret;
- gboolean ret = FALSE;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Releasing mutex handle %p", __func__, handle);
+ gboolean ret;
- if (!pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: We don't own mutex handle %p (owned by %ld, me %ld)", __func__,
- handle, mutex_handle->tid, tid);
-
- goto cleanup;
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
}
- ret = TRUE;
-
- /* OK, we own this mutex */
- mutex_handle->recursion--;
-
- if(mutex_handle->recursion==0) {
- _wapi_thread_disown_mutex (handle);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking mutex handle %p", __func__, handle);
- mutex_handle->tid=0;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_MUTEX:
+ case MONO_W32HANDLE_NAMEDMUTEX:
+ break;
+ default:
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
}
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-static gboolean namedmutex_release (gpointer handle)
-{
- struct _WapiHandle_namedmutex *mutex_handle;
- gboolean ok;
- pthread_t tid = pthread_self ();
- int thr_ret;
- gboolean ret = FALSE;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&mutex_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
- return(FALSE);
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+ return FALSE;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Releasing mutex handle %p", __func__, handle);
+
+ tid = pthread_self ();
if (!pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: We don't own mutex handle %p (owned by %ld, me %ld)", __func__,
- handle, mutex_handle->tid, tid);
+ ret = FALSE;
- goto cleanup;
- }
- ret = TRUE;
-
- /* OK, we own this mutex */
- mutex_handle->recursion--;
-
- if(mutex_handle->recursion==0) {
- _wapi_thread_disown_mutex (handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: we don't own %s handle %p (owned by %ld, me %ld)",
+ __func__, mutex_handle_type_to_string (type), handle, mutex_handle->tid, tid);
+ } else {
+ ret = TRUE;
+
+ /* OK, we own this mutex */
+ mutex_handle->recursion--;
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking mutex handle %p", __func__, handle);
+ if (mutex_handle->recursion == 0) {
+ _wapi_thread_disown_mutex (handle);
- mutex_handle->tid=0;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ mutex_handle->tid = 0;
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+ }
}
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-/**
- * ReleaseMutex:
- * @handle: The mutex handle.
- *
- * Releases ownership if the mutex handle @handle.
- *
- * Return value: %TRUE on success, %FALSE otherwise. This function
- * fails if the calling thread does not own the mutex @handle.
- */
-gboolean ReleaseMutex(gpointer handle)
-{
- WapiHandleType type;
- if (handle == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- type = _wapi_handle_type (handle);
-
- if (mutex_ops[type].release == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- return(mutex_ops[type].release (handle));
+ return ret;
}
gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name)
gchar *utf8_name;
int thr_ret;
- mono_once (&mutex_ops_once, mutex_ops_init);
-
/* w32 seems to guarantee that opening named objects can't
* race each other
*/
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named mutex [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX,
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDMUTEX,
utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
+ if (handle == INVALID_HANDLE_VALUE) {
/* The name has already been used for a different
* object.
*/
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static guint32
convert_from_flags(int flags)
file_handle.sharemode=0;
file_handle.attrs=0;
- handle = _wapi_handle_new_fd (WAPI_HANDLE_CONSOLE, fd, &file_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new_fd (MONO_W32HANDLE_CONSOLE, fd, &file_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating file handle", __func__);
SetLastError (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
#define WAPI_PID_TO_HANDLE(pid) GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + (pid))
#define WAPI_HANDLE_TO_PID(handle) (GPOINTER_TO_UINT ((handle)) - _WAPI_PROCESS_UNHANDLED)
-void wapi_processes_init (void);
+void _wapi_processes_init (void);
extern gpointer _wapi_process_duplicate (void);
extern void wapi_processes_cleanup (void);
-extern struct _WapiHandleOps _wapi_process_ops;
-
/*
* MonoProcess describes processes we create.
* It contains a semaphore that can be waited on in order to wait
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-proclib.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
/* The process' environment strings */
#if defined(__APPLE__)
static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertable);
static void process_close (gpointer handle, gpointer data);
+static void process_details (gpointer data);
+static const gchar* process_typename (void);
+static gsize process_typesize (void);
static gboolean is_pid_valid (pid_t pid);
#if !(defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER))
open_process_map (int pid, const char *mode);
#endif
-struct _WapiHandleOps _wapi_process_ops = {
+static MonoW32HandleOps _wapi_process_ops = {
process_close, /* close_shared */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
process_wait, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ process_details, /* details */
+ process_typename, /* typename */
+ process_typesize, /* typesize */
};
#if HAVE_SIGACTION
WapiHandle_process *process_data;
gboolean ret;
- ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
+ ret = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS,
(gpointer *)&process_data);
if (!ret)
return NULL;
process_set_defaults (&process_handle);
- handle = _wapi_handle_new (WAPI_HANDLE_PROCESS, &process_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating process handle", __func__);
ret = FALSE;
}
/* Close all file descriptors */
- for (i = wapi_getdtablesize () - 1; i > 2; i--)
+ for (i = mono_w32handle_fd_reserve - 1; i > 2; i--)
close (i);
#ifdef DEBUG_ENABLED
process_handle_data = lookup_process_handle (handle);
if (!process_handle_data) {
g_warning ("%s: error looking up process handle %p", __func__, handle);
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
} else {
process_handle_data->id = pid;
} 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;
}
if (fork_failed)
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
if (startup_pipe [1] != -1) {
/* Write 1 byte, doesn't matter what */
}
void
-wapi_processes_init (void)
+_wapi_processes_init (void)
{
pid_t pid = _wapi_getpid ();
WapiHandle_process process_handle = {0};
- _wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SPECIAL_WAIT));
+ mono_w32handle_register_ops (MONO_W32HANDLE_PROCESS, &_wapi_process_ops);
+
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_PROCESS,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SPECIAL_WAIT));
process_handle.id = pid;
process_set_defaults (&process_handle);
process_set_name (&process_handle);
- current_process = _wapi_handle_new (WAPI_HANDLE_PROCESS,
+ current_process = mono_w32handle_new (MONO_W32HANDLE_PROCESS,
&process_handle);
g_assert (current_process);
gpointer
_wapi_process_duplicate (void)
{
- _wapi_handle_ref (current_process);
+ mono_w32handle_ref (current_process);
return current_process;
}
* unsignalled
*/
if (checking_pid == wanted_pid &&
- !_wapi_handle_issignalled (handle)) {
+ !mono_w32handle_issignalled (handle)) {
/* If the handle is blown away in the window between
- * returning TRUE here and _wapi_search_handle pinging
+ * returning TRUE here and mono_w32handle_search pinging
* the timestamp, the search will continue
*/
return TRUE;
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking for process %d", __func__, pid);
- handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
+ handle = mono_w32handle_search (MONO_W32HANDLE_PROCESS,
process_open_compare,
GUINT_TO_POINTER (pid), NULL, TRUE);
if (handle == 0) {
}
}
- /* _wapi_search_handle () already added a ref */
+ /* mono_w32handle_search () already added a ref */
return handle;
}
*/
process_wait (process, 0, TRUE);
- if (_wapi_handle_issignalled (process))
+ if (mono_w32handle_issignalled (process))
*code = process_handle->exitstatus;
else
*code = STILL_ACTIVE;
/* A process handle is only signalled if the process has
* exited. Otherwise exit_time isn't set
*/
- if (_wapi_handle_issignalled (process))
+ if (mono_w32handle_issignalled (process))
*exit_time = process_handle->exit_time;
#ifdef HAVE_GETRUSAGE
mp->handle = NULL;
mono_os_mutex_unlock (&mono_processes_mutex);
if (unref_handle)
- _wapi_handle_unref (unref_handle);
+ mono_w32handle_unref (unref_handle);
}
}
mono_processes_cleanup ();
}
+static void process_details (gpointer data)
+{
+ WapiHandle_process *process_handle = (WapiHandle_process *) data;
+ g_print ("id: %d, exited: %s, exitstatus: %d",
+ process_handle->id, process_handle->exited ? "true" : "false", process_handle->exitstatus);
+}
+
+static const gchar* process_typename (void)
+{
+ return "Process";
+}
+
+static gsize process_typesize (void)
+{
+ return sizeof (WapiHandle_process);
+}
+
#if HAVE_SIGACTION
MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, siginfo_t *info, void *context))
{
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Setting pid %d signalled, exit status %d",
__func__, handle, timeout, process_handle->id, process_handle->exitstatus);
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
return WAIT_OBJECT_0;
}
#endif
#include <glib.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/access.h>
#include <mono/io-layer/versioninfo.h>
#include <config.h>
#include <glib.h>
-extern struct _WapiHandleOps _wapi_sem_ops;
-extern struct _WapiHandleOps _wapi_namedsem_ops;
-
-extern void _wapi_sem_details (gpointer handle_info);
+#include "wapi-private.h"
/* emulate sem_t, so that we can prod the internal state more easily */
struct _WapiHandle_sem
struct _WapiHandle_namedsem
{
+ struct _WapiHandle_sem s;
WapiSharedNamespace sharedns;
- guint32 val;
- gint32 max;
};
+void
+_wapi_semaphore_init (void);
+
#endif /* _WAPI_SEMAPHORE_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/semaphore-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static void sema_signal(gpointer handle);
static gboolean sema_own (gpointer handle);
+static void sema_details (gpointer data);
+static const gchar* sema_typename (void);
+static gsize sema_typesize (void);
static void namedsema_signal (gpointer handle);
static gboolean namedsema_own (gpointer handle);
+static void namedsema_details (gpointer data);
+static const gchar* namedsema_typename (void);
+static gsize namedsema_typesize (void);
-struct _WapiHandleOps _wapi_sem_ops = {
+static MonoW32HandleOps _wapi_sem_ops = {
NULL, /* close */
sema_signal, /* signal */
sema_own, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ sema_details, /* details */
+ sema_typename, /* typename */
+ sema_typesize, /* typesize */
};
-void _wapi_sem_details (gpointer handle_info)
-{
- struct _WapiHandle_sem *sem = (struct _WapiHandle_sem *)handle_info;
-
- g_print ("val: %5u, max: %5d", sem->val, sem->max);
-}
-
-struct _WapiHandleOps _wapi_namedsem_ops = {
+static MonoW32HandleOps _wapi_namedsem_ops = {
NULL, /* close */
namedsema_signal, /* signal */
namedsema_own, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ namedsema_details, /* details */
+ namedsema_typename, /* typename */
+ namedsema_typesize, /* typesize */
};
-static gboolean sem_release (gpointer handle, gint32 count, gint32 *prev);
-static gboolean namedsem_release (gpointer handle, gint32 count, gint32 *prev);
-
-static struct
+void
+_wapi_semaphore_init (void)
{
- gboolean (*release)(gpointer handle, gint32 count, gint32 *prev);
-} sem_ops[WAPI_HANDLE_COUNT] = {
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {sem_release},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {namedsem_release},
-};
-
-static mono_once_t sem_ops_once=MONO_ONCE_INIT;
+ mono_w32handle_register_ops (MONO_W32HANDLE_SEM, &_wapi_sem_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDSEM, &_wapi_namedsem_ops);
-static void sem_ops_init (void)
-{
- _wapi_handle_register_capabilities (WAPI_HANDLE_SEM,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
- _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDSEM,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_SEM,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDSEM,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
}
-static void sema_signal(gpointer handle)
+static const char* sem_handle_type_to_string (MonoW32HandleType type)
{
- ReleaseSemaphore(handle, 1, NULL);
+ switch (type) {
+ case MONO_W32HANDLE_SEM: return "sem";
+ case MONO_W32HANDLE_NAMEDSEM: return "named sem";
+ default:
+ g_assert_not_reached ();
+ }
}
-static gboolean sema_own (gpointer handle)
+static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type)
{
struct _WapiHandle_sem *sem_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_SEM,
- (gpointer *)&sem_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up sem handle %p", __func__,
- handle);
- return(FALSE);
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
+ return FALSE;
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning sem handle %p", __func__, handle);
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
sem_handle->val--;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p val now %d", __func__, handle, sem_handle->val);
- if(sem_handle->val==0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
+ if (sem_handle->val == 0)
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+
+ return TRUE;
+}
- return(TRUE);
+static void sema_signal(gpointer handle)
+{
+ ReleaseSemaphore(handle, 1, NULL);
+}
+
+static gboolean sema_own (gpointer handle)
+{
+ return sem_handle_own (handle, MONO_W32HANDLE_SEM);
}
static void namedsema_signal (gpointer handle)
/* NB, always called with the shared handle lock held */
static gboolean namedsema_own (gpointer handle)
{
- struct _WapiHandle_namedsem *namedsem_handle;
- gboolean ok;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named sem handle %p", __func__, handle);
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDSEM,
- (gpointer *)&namedsem_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named sem handle %p",
- __func__, handle);
- return (FALSE);
- }
-
- namedsem_handle->val--;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p val now %d", __func__, handle,
- namedsem_handle->val);
+ return sem_handle_own (handle, MONO_W32HANDLE_NAMEDSEM);
+}
- if (namedsem_handle->val == 0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
-
- return (TRUE);
+static void sema_details (gpointer data)
+{
+ struct _WapiHandle_sem *sem = (struct _WapiHandle_sem *)data;
+ g_print ("val: %5u, max: %5d", sem->val, sem->max);
+}
+
+static void namedsema_details (gpointer data)
+{
+ struct _WapiHandle_namedsem *namedsem = (struct _WapiHandle_namedsem *)data;
+ g_print ("val: %5u, max: %5d, name: \"%s\"", namedsem->s.val, namedsem->s.max, namedsem->sharedns.name);
+}
+
+static const gchar* sema_typename (void)
+{
+ return "Semaphore";
+}
+
+static gsize sema_typesize (void)
+{
+ return sizeof (struct _WapiHandle_sem);
+}
+
+static const gchar* namedsema_typename (void)
+{
+ return "N.Semaphore";
+}
+
+static gsize namedsema_typesize (void)
+{
+ return sizeof (struct _WapiHandle_namedsem);
}
-static gpointer sem_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gint32 initial, gint32 max)
+
+static gpointer sem_handle_create (struct _WapiHandle_sem *sem_handle, MonoW32HandleType type, gint32 initial, gint32 max)
{
- struct _WapiHandle_sem sem_handle = {0};
gpointer handle;
int thr_ret;
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a
- * semaphore was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
- sem_handle.val = initial;
- sem_handle.max = max;
- handle = _wapi_handle_new (WAPI_HANDLE_SEM, &sem_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating semaphore handle", __func__);
+ sem_handle->val = initial;
+ sem_handle->max = max;
+
+ handle = mono_w32handle_new (type, sem_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ g_warning ("%s: error creating %s handle",
+ __func__, sem_handle_type_to_string (type));
SetLastError (ERROR_GEN_FAILURE);
- return(NULL);
+ return NULL;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (initial != 0) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Created semaphore handle %p initial %d max %d",
- __func__, handle, initial, max);
+ if (initial != 0)
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- return(handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
+
+ return handle;
+}
+
+static gpointer sem_create (gint32 initial, gint32 max)
+{
+ struct _WapiHandle_sem sem_handle;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d",
+ __func__, sem_handle_type_to_string (MONO_W32HANDLE_SEM), initial, max);
+ return sem_handle_create (&sem_handle, MONO_W32HANDLE_SEM, initial, max);
}
-static gpointer namedsem_create (WapiSecurityAttributes *security G_GNUC_UNUSED, gint32 initial, gint32 max, const gunichar2 *name G_GNUC_UNUSED)
+static gpointer namedsem_create (gint32 initial, gint32 max, const gunichar2 *name)
{
- struct _WapiHandle_namedsem namedsem_handle = {{{0}}, 0};
gpointer handle;
gchar *utf8_name;
int thr_ret;
-
- /* w32 seems to guarantee that opening named objects can't
- * race each other
- */
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d name \"%s\"",
+ __func__, sem_handle_type_to_string (MONO_W32HANDLE_NAMEDSEM), initial, max, name);
+
+ /* w32 seems to guarantee that opening named objects can't race each other */
thr_ret = _wapi_namespace_lock ();
g_assert (thr_ret == 0);
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a
- * semaphore was freshly created
- */
- SetLastError (ERROR_SUCCESS);
utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named sem [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDSEM,
- utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
- /* The name has already been used for a different
- * object.
- */
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named sem name [%s] initial %d max %d", __func__, utf8_name, initial, max);
+
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDSEM, utf8_name);
+ if (handle == INVALID_HANDLE_VALUE) {
+ /* The name has already been used for a different object. */
+ handle = NULL;
SetLastError (ERROR_INVALID_HANDLE);
- goto cleanup;
} else if (handle) {
- /* Not an error, but this is how the caller is
- * informed that the semaphore wasn't freshly created
- */
+ /* Not an error, but this is how the caller is informed that the semaphore wasn't freshly created */
SetLastError (ERROR_ALREADY_EXISTS);
+
+ /* this is used as creating a new handle */
+ mono_w32handle_ref (handle);
} else {
- /* A new named semaphore, so create both the private
- * and shared parts
- */
-
+ /* A new named semaphore */
+ struct _WapiHandle_namedsem namedsem_handle;
+
strncpy (&namedsem_handle.sharedns.name [0], utf8_name, MAX_PATH);
namedsem_handle.sharedns.name [MAX_PATH] = '\0';
-
- namedsem_handle.val = initial;
- namedsem_handle.max = max;
- handle = _wapi_handle_new (WAPI_HANDLE_NAMEDSEM,
- &namedsem_handle);
-
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating named sem handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Set the initial state, as this is a completely new
- * handle
- */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (initial != 0) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ handle = sem_handle_create ((struct _WapiHandle_sem*) &namedsem_handle, MONO_W32HANDLE_NAMEDSEM, initial, max);
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named sem handle %p", __func__, handle);
-cleanup:
g_free (utf8_name);
-
- _wapi_namespace_unlock (NULL);
-
+
+ thr_ret = _wapi_namespace_unlock (NULL);
+ g_assert (thr_ret == 0);
+
return handle;
}
*/
gpointer CreateSemaphore(WapiSecurityAttributes *security G_GNUC_UNUSED, gint32 initial, gint32 max, const gunichar2 *name)
{
- mono_once (&sem_ops_once, sem_ops_init);
-
if (max <= 0) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: max <= 0", __func__);
return(NULL);
}
- if (name == NULL) {
- return (sem_create (security, initial, max));
- } else {
- return (namedsem_create (security, initial, max, name));
- }
-}
-
-static gboolean sem_release (gpointer handle, gint32 count, gint32 *prevcount)
-{
- struct _WapiHandle_sem *sem_handle;
- gboolean ok;
- gboolean ret=FALSE;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SEM,
- (gpointer *)&sem_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up sem handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p val %d count %d", __func__, handle,
- sem_handle->val, count);
-
- /* Do this before checking for count overflow, because overflowing max
- * is a listed technique for finding the current value
- */
- if (prevcount != NULL) {
- *prevcount = sem_handle->val;
- }
-
- /* No idea why max is signed, but thats the spec :-( */
- if (sem_handle->val + count > (guint32)sem_handle->max) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p max value would be exceeded: max %d current %d count %d", __func__, handle, sem_handle->max, sem_handle->val, count);
-
- goto end;
- }
-
- sem_handle->val += count;
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
-
- ret = TRUE;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p val now %d", __func__, handle, sem_handle->val);
-
-end:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-static gboolean namedsem_release (gpointer handle, gint32 count,
- gint32 *prevcount)
-{
- struct _WapiHandle_namedsem *sem_handle;
- gboolean ok;
- gboolean ret=FALSE;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDSEM,
- (gpointer *)&sem_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up sem handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p val %d count %d", __func__, handle,
- sem_handle->val, count);
-
- /* Do this before checking for count overflow, because overflowing max
- * is a listed technique for finding the current value
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if a
+ * semaphore was freshly created
*/
- if (prevcount != NULL) {
- *prevcount = sem_handle->val;
- }
-
- /* No idea why max is signed, but thats the spec :-( */
- if (sem_handle->val + count > (guint32)sem_handle->max) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p max value would be exceeded: max %d current %d count %d", __func__, handle, sem_handle->max, sem_handle->val, count);
-
- goto end;
- }
-
- sem_handle->val += count;
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
-
- ret = TRUE;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p val now %d", __func__, handle,
- sem_handle->val);
-
-end:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ SetLastError (ERROR_SUCCESS);
- return(ret);
+ return name ? namedsem_create (initial, max, name) : sem_create (initial, max);
}
/**
*/
gboolean ReleaseSemaphore(gpointer handle, gint32 count, gint32 *prevcount)
{
- WapiHandleType type;
-
- if (handle == NULL) {
+ MonoW32HandleType type;
+ struct _WapiHandle_sem *sem_handle;
+ int thr_ret;
+ gboolean ret;
+
+ if (!handle) {
SetLastError (ERROR_INVALID_HANDLE);
- return (FALSE);
+ return FALSE;
}
-
- type = _wapi_handle_type (handle);
-
- if (sem_ops[type].release == NULL) {
+
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_SEM:
+ case MONO_W32HANDLE_NAMEDSEM:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return (FALSE);
+ return FALSE;
}
-
- return (sem_ops[type].release (handle, count, prevcount));
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
+ g_warning ("%s: error looking up sem handle %p", __func__, handle);
+ return FALSE;
+ }
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ /* Do this before checking for count overflow, because overflowing
+ * max is a listed technique for finding the current value */
+ if (prevcount)
+ *prevcount = sem_handle->val;
+
+ /* No idea why max is signed, but thats the spec :-( */
+ if (sem_handle->val + count > (guint32)sem_handle->max) {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d, max value would be exceeded",
+ __func__, sem_handle_type_to_string (type), handle, sem_handle->val, count, sem_handle->max, count);
+
+ ret = FALSE;
+ } else {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d",
+ __func__, sem_handle_type_to_string (type), handle, sem_handle->val, count, sem_handle->max, count);
+
+ sem_handle->val += count;
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+
+ ret = TRUE;
+ }
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ return ret;
}
gpointer OpenSemaphore (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED,
gchar *utf8_name;
int thr_ret;
- mono_once (&sem_ops_once, sem_ops_init);
-
/* w32 seems to guarantee that opening named objects can't
* race each other
*/
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named sem [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDSEM,
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDSEM,
utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
+ if (handle == INVALID_HANDLE_VALUE) {
/* The name has already been used for a different
* object.
*/
mono_os_mutex_init (&noshm_sems [i]);
}
-void
-_wapi_shm_semaphores_remove (void)
-{
- /* Nothing */
-}
-
int
_wapi_shm_sem_lock (int sem)
{
#define _WAPI_SHARED_H_
extern void _wapi_shm_semaphores_init (void);
-extern void _wapi_shm_semaphores_remove (void);
extern int _wapi_shm_sem_lock (int sem);
extern int _wapi_shm_sem_trylock (int sem);
extern int _wapi_shm_sem_unlock (int sem);
#include <config.h>
#include <glib.h>
-extern struct _WapiHandleOps _wapi_socket_ops;
+#include "wapi-private.h"
struct _WapiHandle_socket
{
int still_readable;
};
+void
+_wapi_socket_init (void);
+
#endif /* _WAPI_SOCKET_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/socket-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/socket-wrappers.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-poll.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
static guint32 in_cleanup = 0;
static void socket_close (gpointer handle, gpointer data);
+static void socket_details (gpointer data);
+static const gchar* socket_typename (void);
+static gsize socket_typesize (void);
-struct _WapiHandleOps _wapi_socket_ops = {
+static MonoW32HandleOps _wapi_socket_ops = {
socket_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ socket_details, /* details */
+ socket_typename, /* typename */
+ socket_typesize, /* typesize */
};
-static mono_once_t socket_ops_once=MONO_ONCE_INIT;
-
-static void socket_ops_init (void)
+void
+_wapi_socket_init (void)
{
- /* No capabilities to register */
+ mono_w32handle_register_ops (MONO_W32HANDLE_SOCKET, &_wapi_socket_ops);
}
static void socket_close (gpointer handle, gpointer data)
socket_handle->saved_error = 0;
}
+static void socket_details (gpointer data)
+{
+ /* FIXME: do something */
+}
+
+static const gchar* socket_typename (void)
+{
+ return "Socket";
+}
+
+static gsize socket_typesize (void)
+{
+ return sizeof (struct _WapiHandle_socket);
+}
+
static gboolean
-cleanup_close (gpointer handle, gpointer data)
+cleanup_close (gpointer handle, gpointer data, gpointer user_data)
{
- _wapi_handle_ops_close (handle, NULL);
- return TRUE;
+ if (mono_w32handle_get_type (handle) == MONO_W32HANDLE_SOCKET)
+ mono_w32handle_ops_close (handle, data);
+
+ return FALSE;
}
void _wapi_cleanup_networking(void)
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: cleaning up", __func__);
in_cleanup = 1;
- _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
+ mono_w32handle_foreach (cleanup_close, NULL);
in_cleanup = 0;
}
{
gpointer handle = GUINT_TO_POINTER (fd);
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(0);
}
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
return(0);
}
return(INVALID_SOCKET);
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(INVALID_SOCKET);
}
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p",
return(INVALID_SOCKET);
}
- if (new_fd >= _wapi_fd_reserve) {
+ if (new_fd >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
WSASetLastError (WSASYSCALLFAILURE);
new_socket_handle.protocol = socket_handle->protocol;
new_socket_handle.still_readable = 1;
- new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd,
+ new_handle = mono_w32handle_new_fd (MONO_W32HANDLE_SOCKET, new_fd,
&new_socket_handle);
- if(new_handle == _WAPI_HANDLE_INVALID) {
+ if(new_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating socket handle", __func__);
WSASetLastError (ERROR_GEN_FAILURE);
return(INVALID_SOCKET);
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gboolean ok;
gint errnum;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
* But don't do this for EWOULDBLOCK (bug 317315)
*/
if (errnum != WSAEWOULDBLOCK) {
- ok = _wapi_lookup_handle (handle,
- WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle,
+ MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
/* ECONNRESET means the socket was closed by another thread */
errnum = errno_to_WSA (so_error, __func__);
/* Need to save this socket error */
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p", __func__, handle);
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
struct _WapiHandle_socket *socket_handle;
gboolean ok;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
}
if (optname == SO_ERROR) {
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p",
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gboolean ok;
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
* still_readable != 1 then shutdown
* (SHUT_RD|SHUT_RDWR) has been called locally.
*/
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE || socket_handle->still_readable != 1) {
ret = -1;
gboolean ok;
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
if (ret == 0) {
/* see _wapi_recvfrom */
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE || socket_handle->still_readable != 1) {
ret = -1;
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
#endif
struct timeval tv;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
if (how == SHUT_RD ||
how == SHUT_RDWR) {
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p",
return(INVALID_SOCKET);
}
- if (fd >= _wapi_fd_reserve) {
+ if (fd >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big (%d >= %d)",
- __func__, fd, _wapi_fd_reserve);
+ __func__, fd, mono_w32handle_fd_reserve);
WSASetLastError (WSASYSCALLFAILURE);
close (fd);
}
- mono_once (&socket_ops_once, socket_ops_init);
-
- handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new_fd (MONO_W32HANDLE_SOCKET, fd, &socket_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating socket handle", __func__);
WSASetLastError (WSASYSCALLFAILURE);
close (fd);
gpointer handle = GUINT_TO_POINTER (fd);
int newsock, ret;
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p", __func__,
gpointer sock = GUINT_TO_POINTER (socket);
gint ret;
- if (_wapi_handle_type (sock) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (sock) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return FALSE;
}
int ret;
gchar *buffer = NULL;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return SOCKET_ERROR;
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
return;
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return;
}
return(0);
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(0);
}
return;
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return;
}
#include <glib.h>
#include <pthread.h>
+#include "wapi-private.h"
+
/* There doesn't seem to be a defined symbol for this */
#define _WAPI_THREAD_CURRENT (gpointer)0xFFFFFFFE
-extern struct _WapiHandleOps _wapi_thread_ops;
-
struct _WapiHandle_thread
{
pthread_t id;
typedef struct _WapiHandle_thread WapiHandle_thread;
+void
+_wapi_thread_init (void);
+
extern gboolean _wapi_thread_cur_apc_pending (void);
extern void _wapi_thread_own_mutex (gpointer mutex);
extern void _wapi_thread_disown_mutex (gpointer mutex);
#include <glib.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/io.h>
#include <mono/io-layer/status.h>
#include <mono/io-layer/processes.h>
#include <errno.h>
#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
#include <mono/utils/mono-time.h>
+#include <mono/utils/w32handle.h>
static gboolean own_if_signalled(gpointer handle)
{
gboolean ret = FALSE;
- if (_wapi_handle_issignalled (handle)) {
- _wapi_handle_ops_own (handle);
+ if (mono_w32handle_issignalled (handle)) {
+ mono_w32handle_ops_own (handle);
ret = TRUE;
}
{
gboolean ret = FALSE;
- if (_wapi_handle_ops_isowned (handle)) {
- _wapi_handle_ops_own (handle);
+ if (mono_w32handle_ops_isowned (handle)) {
+ mono_w32handle_ops_own (handle);
ret = TRUE;
}
return(WAIT_FAILED);
}
- if (_wapi_handle_test_capabilities (handle,
- WAPI_HANDLE_CAP_WAIT) == FALSE) {
+ if (mono_w32handle_test_capabilities (handle,
+ MONO_W32HANDLE_CAP_WAIT) == FALSE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p can't be waited for", __func__,
handle);
return(WAIT_FAILED);
}
- _wapi_handle_ops_prewait (handle);
+ mono_w32handle_ops_prewait (handle);
- if (_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
+ if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p has special wait", __func__, handle);
- ret = _wapi_handle_ops_special_wait (handle, timeout, alertable);
+ ret = mono_w32handle_ops_specialwait (handle, timeout, alertable);
if (alertable && _wapi_thread_cur_apc_pending ())
ret = WAIT_IO_COMPLETION;
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, handle);
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
- if (_wapi_handle_test_capabilities (handle,
- WAPI_HANDLE_CAP_OWN) == TRUE) {
+ if (mono_w32handle_test_capabilities (handle,
+ MONO_W32HANDLE_CAP_OWN) == TRUE) {
if (own_if_owned (handle) == TRUE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
handle);
do {
/* Check before waiting on the condition, just in case
*/
- _wapi_handle_ops_prewait (handle);
+ mono_w32handle_ops_prewait (handle);
if (own_if_signalled (handle)) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__,
}
if (timeout == INFINITE) {
- waited = _wapi_handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL);
+ waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL);
} else {
now = mono_100ns_ticks ();
if (end < now) {
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) {
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);
return(WAIT_FAILED);
}
- if (_wapi_handle_test_capabilities (signal_handle,
- WAPI_HANDLE_CAP_SIGNAL)==FALSE) {
+ if (mono_w32handle_test_capabilities (signal_handle,
+ MONO_W32HANDLE_CAP_SIGNAL)==FALSE) {
return(WAIT_FAILED);
}
- if (_wapi_handle_test_capabilities (wait,
- WAPI_HANDLE_CAP_WAIT)==FALSE) {
+ if (mono_w32handle_test_capabilities (wait,
+ MONO_W32HANDLE_CAP_WAIT)==FALSE) {
return(WAIT_FAILED);
}
- _wapi_handle_ops_prewait (wait);
+ mono_w32handle_ops_prewait (wait);
- if (_wapi_handle_test_capabilities (wait, WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
+ if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
g_warning ("%s: handle %p has special wait, implement me!!",
__func__, wait);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, wait);
- thr_ret = _wapi_handle_lock_handle (wait);
+ thr_ret = mono_w32handle_lock_handle (wait);
g_assert (thr_ret == 0);
- _wapi_handle_ops_signal (signal_handle);
+ mono_w32handle_ops_signal (signal_handle);
- if (_wapi_handle_test_capabilities (wait, WAPI_HANDLE_CAP_OWN)==TRUE) {
+ if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_OWN)==TRUE) {
if (own_if_owned (wait)) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
wait);
do {
/* Check before waiting on the condition, just in case
*/
- _wapi_handle_ops_prewait (wait);
+ mono_w32handle_ops_prewait (wait);
if (own_if_signalled (wait)) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__, wait);
}
if (timeout == INFINITE) {
- waited = _wapi_handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL);
+ waited = mono_w32handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL);
} else {
now = mono_100ns_ticks ();
if (end < now) {
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) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, wait);
- thr_ret = _wapi_handle_unlock_handle (wait);
+ thr_ret = mono_w32handle_unlock_handle (wait);
g_assert (thr_ret == 0);
return(ret);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handles", __func__);
- done = _wapi_handle_count_signalled_handles (numobjects, handles,
+ done = mono_w32handle_count_signalled_handles (numobjects, handles,
waitall, count, lowest);
if (done == TRUE) {
if (waitall == TRUE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handles", __func__);
- _wapi_handle_unlock_handles (numobjects, handles);
+ mono_w32handle_unlock_handles (numobjects, handles);
return(done);
}
break;
}
- if (_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_WAIT) == FALSE) {
+ if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT) == FALSE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p can't be waited for",
__func__, handles[i]);
}
sorted_handles [i] = handles [i];
- _wapi_handle_ops_prewait (handles[i]);
+ mono_w32handle_ops_prewait (handles[i]);
}
qsort (sorted_handles, numobjects, sizeof (gpointer), g_direct_equal);
poll = FALSE;
for (i = 0; i < numobjects; ++i)
- if (_wapi_handle_type (handles [i]) == WAPI_HANDLE_PROCESS)
+ if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS)
/* Can't wait for a process handle + another handle without polling */
poll = TRUE;
* disappear from under us while we're waiting in the loop
* (not lock, as we don't want exclusive access here)
*/
- _wapi_handle_ref (handles[i]);
+ mono_w32handle_ref (handles[i]);
}
while(1) {
* special-wait handles that aren't already signalled
*/
for (i = 0; i < numobjects; i++) {
- _wapi_handle_ops_prewait (handles[i]);
+ mono_w32handle_ops_prewait (handles[i]);
- if (_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE && _wapi_handle_issignalled (handles[i]) == FALSE) {
- _wapi_handle_ops_special_wait (handles[i], 0, alertable);
+ if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE && mono_w32handle_issignalled (handles[i]) == FALSE) {
+ mono_w32handle_ops_specialwait (handles[i], 0, alertable);
}
}
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking signal mutex", __func__);
- thr_ret = _wapi_handle_lock_signal_mutex ();
+ thr_ret = mono_w32handle_lock_signal_mutex ();
g_assert (thr_ret == 0);
/* Check the signalled state of handles inside the critical section */
if (waitall) {
done = TRUE;
for (i = 0; i < numobjects; i++)
- if (!_wapi_handle_issignalled (handles [i]))
+ if (!mono_w32handle_issignalled (handles [i]))
done = FALSE;
} else {
done = FALSE;
for (i = 0; i < numobjects; i++)
- if (_wapi_handle_issignalled (handles [i]))
+ if (mono_w32handle_issignalled (handles [i]))
done = TRUE;
}
if (!done) {
/* Enter the wait */
if (timeout == INFINITE) {
- ret = _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, INFINITE, poll, &apc_pending);
+ ret = mono_w32handle_timedwait_signal (INFINITE, poll, &apc_pending);
} else {
now = mono_100ns_ticks ();
if (end < now) {
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 {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking signal mutex", __func__);
- thr_ret = _wapi_handle_unlock_signal_mutex (NULL);
+ thr_ret = mono_w32handle_unlock_signal_mutex ();
g_assert (thr_ret == 0);
if (alertable && apc_pending) {
for (i = 0; i < numobjects; i++) {
/* Unref everything we reffed above */
- _wapi_handle_unref (handles[i]);
+ mono_w32handle_unref (handles[i]);
}
return retval;
#include <sys/stat.h>
#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/io.h>
+#include <mono/io-layer/shared.h>
#include <mono/utils/mono-os-mutex.h>
-/* Increment this whenever an incompatible change is made to the
- * shared handle structure.
- */
-#define _WAPI_HANDLE_VERSION 12
-
-typedef enum {
- WAPI_HANDLE_UNUSED=0,
- WAPI_HANDLE_FILE,
- WAPI_HANDLE_CONSOLE,
- WAPI_HANDLE_THREAD,
- WAPI_HANDLE_SEM,
- WAPI_HANDLE_MUTEX,
- WAPI_HANDLE_EVENT,
- WAPI_HANDLE_SOCKET,
- WAPI_HANDLE_FIND,
- WAPI_HANDLE_PROCESS,
- WAPI_HANDLE_PIPE,
- WAPI_HANDLE_NAMEDMUTEX,
- WAPI_HANDLE_NAMEDSEM,
- WAPI_HANDLE_NAMEDEVENT,
- WAPI_HANDLE_COUNT
-} WapiHandleType;
-
-extern const char *_wapi_handle_typename[];
-
-#define _WAPI_FD_HANDLE(type) (type == WAPI_HANDLE_FILE || \
- type == WAPI_HANDLE_CONSOLE || \
- type == WAPI_HANDLE_SOCKET || \
- type == WAPI_HANDLE_PIPE)
-
-#define _WAPI_SHARED_NAMESPACE(type) (type == WAPI_HANDLE_NAMEDMUTEX || \
- type == WAPI_HANDLE_NAMEDSEM || \
- type == WAPI_HANDLE_NAMEDEVENT)
+extern gboolean _wapi_has_shut_down;
typedef struct
{
gchar name[MAX_PATH + 1];
} WapiSharedNamespace;
-typedef enum {
- WAPI_HANDLE_CAP_WAIT=0x01,
- WAPI_HANDLE_CAP_SIGNAL=0x02,
- WAPI_HANDLE_CAP_OWN=0x04,
- WAPI_HANDLE_CAP_SPECIAL_WAIT=0x08
-} WapiHandleCapability;
-
-struct _WapiHandleOps
-{
- void (*close)(gpointer handle, gpointer data);
-
- /* SignalObjectAndWait */
- void (*signal)(gpointer signal);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects,
- * with the handle locked (shared handles aren't locked.)
- * Returns TRUE if ownership was established, false otherwise.
- */
- gboolean (*own_handle)(gpointer handle);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
- * handle in question is "ownable" (ie mutexes), to see if the current
- * thread already owns this handle
- */
- gboolean (*is_owned)(gpointer handle);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects,
- * if the handle in question needs a special wait function
- * instead of using the normal handle signal mechanism.
- * Returns the WaitForSingleObject return code.
- */
- guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean alertable);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects,
- * if the handle in question needs some preprocessing before the
- * signal wait.
- */
- void (*prewait)(gpointer handle);
-};
-
#include <mono/io-layer/event-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/io-layer/socket-private.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/process-private.h>
+#include <mono/utils/w32handle.h>
struct _WapiHandle_shared_ref
{
guint32 offset;
};
-#define _WAPI_HANDLE_INITIAL_COUNT 256
-
-struct _WapiHandleUnshared
-{
- WapiHandleType type;
- guint ref;
- gboolean signalled;
- mono_mutex_t signal_mutex;
- mono_cond_t signal_cond;
-
- union
- {
- struct _WapiHandle_event event;
- struct _WapiHandle_file file;
- struct _WapiHandle_find find;
- struct _WapiHandle_mutex mutex;
- struct _WapiHandle_sem sem;
- struct _WapiHandle_socket sock;
- struct _WapiHandle_thread thread;
- struct _WapiHandle_process process;
- struct _WapiHandle_shared_ref shared;
- struct _WapiHandle_namedmutex namedmutex;
- struct _WapiHandle_namedsem namedsem;
- struct _WapiHandle_namedevent namedevent;
- } u;
-};
-
#define _WAPI_SHARED_SEM_NAMESPACE 0
/*#define _WAPI_SHARED_SEM_COLLECTION 1*/
#define _WAPI_SHARED_SEM_FILESHARE 2
typedef struct _WapiFileShare _WapiFileShare;
-#define _WAPI_HANDLE_INVALID (gpointer)-1
+pid_t
+_wapi_getpid (void);
+
+gpointer
+_wapi_search_handle_namespace (MonoW32HandleType type, gchar *utf8_name);
+
+static inline int _wapi_namespace_lock (void)
+{
+ return(_wapi_shm_sem_lock (_WAPI_SHARED_SEM_NAMESPACE));
+}
+
+/* This signature makes it easier to use in pthread cleanup handlers */
+static inline int _wapi_namespace_unlock (gpointer data G_GNUC_UNUSED)
+{
+ return(_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_NAMESPACE));
+}
#endif /* _WAPI_PRIVATE_H_ */
--- /dev/null
+
+#include "wapi.h"
+
+#include "process-private.h"
+#include "thread-private.h"
+#include "io-trace.h"
+
+#include "mono/utils/mono-lazy-init.h"
+#include "mono/utils/w32handle.h"
+
+gboolean _wapi_has_shut_down = FALSE;
+
+void
+wapi_init (void)
+{
+ _wapi_shm_semaphores_init ();
+ _wapi_io_init ();
+ _wapi_processes_init ();
+ _wapi_thread_init ();
+ _wapi_semaphore_init ();
+ _wapi_mutex_init ();
+ _wapi_event_init ();
+ _wapi_socket_init ();
+}
+
+void
+wapi_cleanup (void)
+{
+ g_assert (_wapi_has_shut_down == FALSE);
+ _wapi_has_shut_down = TRUE;
+
+ _wapi_error_cleanup ();
+ _wapi_thread_cleanup ();
+ wapi_processes_cleanup ();
+ _wapi_io_cleanup ();
+}
+
+/* Use this instead of getpid(), to cope with linuxthreads. It's a
+ * function rather than a variable lookup because we need to get at
+ * this before share_init() might have been called. */
+static mono_lazy_init_t _wapi_pid_init_lazy = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
+static pid_t _wapi_pid;
+
+static void
+_wapi_pid_init (void)
+{
+ _wapi_pid = getpid ();
+}
+
+pid_t
+_wapi_getpid (void)
+{
+ mono_lazy_initialize (&_wapi_pid_init_lazy, _wapi_pid_init);
+ return _wapi_pid;
+}
+
+static gboolean
+_WAPI_SHARED_NAMESPACE (MonoW32HandleType type)
+{
+ switch (type) {
+ case MONO_W32HANDLE_NAMEDMUTEX:
+ case MONO_W32HANDLE_NAMEDSEM:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+typedef struct {
+ gpointer ret;
+ MonoW32HandleType type;
+ gchar *utf8_name;
+} _WapiSearchHandleNamespaceData;
+
+static gboolean mono_w32handle_search_namespace_callback (gpointer handle, gpointer data, gpointer user_data)
+{
+ _WapiSearchHandleNamespaceData *search_data;
+ MonoW32HandleType type;
+ WapiSharedNamespace *sharedns;
+
+ type = mono_w32handle_get_type (handle);
+ if (!_WAPI_SHARED_NAMESPACE (type))
+ return FALSE;
+
+ search_data = (_WapiSearchHandleNamespaceData*) user_data;
+
+ switch (type) {
+ case MONO_W32HANDLE_NAMEDMUTEX: sharedns = &((struct _WapiHandle_namedmutex*) data)->sharedns; break;
+ case MONO_W32HANDLE_NAMEDSEM: sharedns = &((struct _WapiHandle_namedsem*) data)->sharedns; break;
+ case MONO_W32HANDLE_NAMEDEVENT: sharedns = &((struct _WapiHandle_namedevent*) data)->sharedns; break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (strcmp (sharedns->name, search_data->utf8_name) == 0) {
+ if (type != search_data->type) {
+ /* Its the wrong type, so fail now */
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p matches name but is wrong type: %s",
+ __func__, handle, mono_w32handle_ops_typename (type));
+ search_data->ret = INVALID_HANDLE_VALUE;
+ } else {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p matches name and type",
+ __func__, handle);
+ search_data->ret = handle;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Returns the offset of the metadata array, or INVALID_HANDLE_VALUE on error, or NULL for
+ * not found
+ */
+gpointer _wapi_search_handle_namespace (MonoW32HandleType type, gchar *utf8_name)
+{
+ _WapiSearchHandleNamespaceData search_data;
+
+ g_assert(_WAPI_SHARED_NAMESPACE(type));
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s",
+ __func__, utf8_name, mono_w32handle_ops_typename (type));
+
+ search_data.ret = NULL;
+ search_data.type = type;
+ search_data.utf8_name = utf8_name;
+ mono_w32handle_foreach (mono_w32handle_search_namespace_callback, &search_data);
+ return search_data.ret;
+}
+
+/* Lots more to implement here, but this is all we need at the moment */
+gboolean
+DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
+ guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED)
+{
+ if (srcprocess != _WAPI_PROCESS_CURRENT || targetprocess != _WAPI_PROCESS_CURRENT) {
+ /* Duplicating other process's handles is not supported */
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (src == _WAPI_PROCESS_CURRENT) {
+ *target = _wapi_process_duplicate ();
+ } else if (src == _WAPI_THREAD_CURRENT) {
+ g_assert_not_reached ();
+ } else {
+ mono_w32handle_ref (src);
+ *target = src;
+ }
+
+ return TRUE;
+}
+
+/**
+ * CloseHandle:
+ * @handle: The handle to release
+ *
+ * Closes and invalidates @handle, releasing any resources it
+ * consumes. When the last handle to a temporary or non-persistent
+ * object is closed, that object can be deleted. Closing the same
+ * handle twice is an error.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise.
+ */
+gboolean CloseHandle(gpointer handle)
+{
+ if (handle == INVALID_HANDLE_VALUE){
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ if (handle == (gpointer)0 && mono_w32handle_get_type (handle) != MONO_W32HANDLE_CONSOLE) {
+ /* Problem: because we map file descriptors to the
+ * same-numbered handle we can't tell the difference
+ * between a bogus handle and the handle to stdin.
+ * Assume that it's the console handle if that handle
+ * exists...
+ */
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ mono_w32handle_unref (handle);
+ return TRUE;
+}
#include <mono/io-layer/wapi-remap.h>
#include <mono/io-layer/types.h>
#include <mono/io-layer/macros.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/io.h>
#include <mono/io-layer/access.h>
#include <mono/io-layer/context.h>
#include <mono/io-layer/versioninfo.h>
#include <mono/io-layer/wait.h>
+void
+wapi_init (void);
+
+void
+wapi_cleanup (void);
+
+gboolean
+CloseHandle (gpointer handle);
+
+gboolean
+DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
+ guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED);
+
#endif /* _WAPI_WAPI_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
-struct _WapiHandleOps _wapi_thread_ops = {
+static void thread_details (gpointer data);
+static const gchar* thread_typename (void);
+static gsize thread_typesize (void);
+
+static MonoW32HandleOps _wapi_thread_ops = {
NULL, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ thread_details, /* details */
+ thread_typename, /* typename */
+ thread_typesize, /* typesize */
};
-static mono_once_t thread_ops_once = MONO_ONCE_INIT;
+void
+_wapi_thread_init (void)
+{
+ mono_w32handle_register_ops (MONO_W32HANDLE_THREAD, &_wapi_thread_ops);
+
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_THREAD, MONO_W32HANDLE_CAP_WAIT);
+}
+
+static void thread_details (gpointer data)
+{
+ WapiHandle_thread *thread = (WapiHandle_thread*) data;
+ g_print ("id: %p, owned_mutexes: %d, priority: %d",
+ thread->id, thread->owned_mutexes->len, thread->priority);
+}
+
+static const gchar* thread_typename (void)
+{
+ return "Thread";
+}
-static void
-thread_ops_init (void)
+static gsize thread_typesize (void)
{
- _wapi_handle_register_capabilities (WAPI_HANDLE_THREAD,
- WAPI_HANDLE_CAP_WAIT);
+ return sizeof (WapiHandle_thread);
}
void
WapiHandle_thread *thread;
gboolean ok;
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread);
g_assert (ok);
return thread;
pid_t pid = _wapi_getpid ();
pthread_t tid = pthread_self ();
- if (_wapi_handle_issignalled (handle) ||
- _wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
+ if (mono_w32handle_issignalled (handle) ||
+ mono_w32handle_get_type (handle) == MONO_W32HANDLE_UNUSED) {
/* We must have already deliberately finished with
* this thread, so don't do any more now
*/
}
g_ptr_array_free (thread_handle->owned_mutexes, TRUE);
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Recording thread handle %p id %ld status as %d",
__func__, handle, thread_handle->id, exitstatus);
/* The thread is no longer active, so unref it */
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
}
/*
WapiHandle_thread thread_handle = {0}, *thread;
gpointer handle;
- mono_once (&thread_ops_once, thread_ops_init);
-
thread_handle.owned_mutexes = g_ptr_array_new ();
- handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, &thread_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating thread handle", __func__);
SetLastError (ERROR_GEN_FAILURE);
* Hold a reference while the thread is active, because we use
* the handle to store thread exit information
*/
- _wapi_handle_ref (handle);
+ mono_w32handle_ref (handle);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: started thread id %ld", __func__, thread->id);
void
wapi_ref_thread_handle (gpointer handle)
{
- _wapi_handle_ref (handle);
+ mono_w32handle_ref (handle);
}
gpointer
thread = get_current_thread ();
- _wapi_handle_ref (mutex);
+ mono_w32handle_ref (mutex);
g_ptr_array_add (thread->owned_mutexes, mutex);
}
thread = get_current_thread ();
- _wapi_handle_unref (mutex);
+ mono_w32handle_unref (mutex);
g_ptr_array_remove (thread->owned_mutexes, mutex);
}
wapi_init_thread_info_priority (gpointer handle, gint32 priority)
{
struct _WapiHandle_thread *thread_handle = NULL;
- gboolean ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == TRUE)
struct _WapiHandle_thread *thread_handle = NULL;
int policy;
struct sched_param param;
- gboolean ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == FALSE)
posix_priority,
rv;
struct sched_param param;
- gboolean ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == FALSE) {
verify.h
EXTRA_DIST = $(win32_sources) $(unix_sources) $(null_sources) runtime.h \
- threadpool-ms-io-poll.c threadpool-ms-io-epoll.c threadpool-ms-io-kqueue.c
+ threadpool-ms-io-poll.c threadpool-ms-io-epoll.c threadpool-ms-io-kqueue.c sgen-dynarray.h
#include <mono/utils/atomic.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/w32handle.h>
#ifdef HOST_WIN32
#include <direct.h>
#endif
return location;
}
-static gboolean
-ensure_directory_exists (const char *filename)
-{
-#ifdef HOST_WIN32
- gchar *dir_utf8 = g_path_get_dirname (filename);
- gunichar2 *p;
- gunichar2 *dir_utf16 = NULL;
- int retval;
-
- if (!dir_utf8 || !dir_utf8 [0])
- return FALSE;
-
- dir_utf16 = g_utf8_to_utf16 (dir_utf8, strlen (dir_utf8), NULL, NULL, NULL);
- g_free (dir_utf8);
-
- if (!dir_utf16)
- return FALSE;
-
- p = dir_utf16;
-
- /* make life easy and only use one directory seperator */
- while (*p != '\0')
- {
- if (*p == '/')
- *p = '\\';
- p++;
- }
-
- p = dir_utf16;
-
- /* get past C:\ )*/
- while (*p++ != '\\')
- {
- }
-
- while (1) {
- BOOL bRet = FALSE;
- p = wcschr (p, '\\');
- if (p)
- *p = '\0';
- retval = _wmkdir (dir_utf16);
- if (retval != 0 && errno != EEXIST) {
- g_free (dir_utf16);
- return FALSE;
- }
- if (!p)
- break;
- *p++ = '\\';
- }
-
- g_free (dir_utf16);
- return TRUE;
-#else
- char *p;
- gchar *dir = g_path_get_dirname (filename);
- int retval;
- struct stat sbuf;
-
- if (!dir || !dir [0]) {
- g_free (dir);
- return FALSE;
- }
-
- if (stat (dir, &sbuf) == 0 && S_ISDIR (sbuf.st_mode)) {
- g_free (dir);
- return TRUE;
- }
-
- p = dir;
- while (*p == '/')
- p++;
-
- while (1) {
- p = strchr (p, '/');
- if (p)
- *p = '\0';
- retval = mkdir (dir, 0777);
- if (retval != 0 && errno != EEXIST) {
- g_free (dir);
- return FALSE;
- }
- if (!p)
- break;
- *p++ = '/';
- }
-
- g_free (dir);
- return TRUE;
-#endif
-}
-
static gboolean
private_file_needs_copying (const char *src, struct stat *sbuf_src, char *dest)
{
return NULL;
}
- if (ensure_directory_exists (shadow) == FALSE) {
+ if (g_ensure_directory_exists (shadow) == FALSE) {
g_free (shadow);
mono_error_set_execution_engine (oerror, "Failed to create shadow copy (ensure directory exists).");
return NULL;
#define CLI_FLAGS_ILONLY 0x01
#define CLI_FLAGS_32BITREQUIRED 0x02
#define CLI_FLAGS_STRONGNAMESIGNED 0x8
-#define CLI_FLAGS_PREFERRED32BIT 0x10
#define CLI_FLAGS_TRACKDEBUGDATA 0x00010000
+#define CLI_FLAGS_PREFERRED32BIT 0x00020000
guint32 ch_flags;
guint32 ch_entry_point;
};
/* Additional details about a MonoGenericParam */
+/* Keep in sync with managed Mono.RuntimeStructs.GenericParamInfo */
typedef struct {
MonoClass *pklass; /* The corresponding `MonoClass'. */
const char *name;
#include <metadata/threads.h>
#include <metadata/profiler-private.h>
#include <mono/metadata/coree.h>
+#include <mono/utils/w32handle.h>
//#define DEBUG_DOMAIN_UNLOAD 1
#endif
#ifndef HOST_WIN32
+ mono_w32handle_init ();
wapi_init ();
#endif
#ifndef HOST_WIN32
wapi_cleanup ();
+ mono_w32handle_cleanup ();
#endif
}
#include <mono/metadata/marshal.h>
#include <mono/utils/strenc.h>
#include <utils/mono-io-portability.h>
+#include <mono/utils/w32handle.h>
#undef DEBUG
#endif
-void _wapi_handle_dump (void);
+void mono_w32handle_dump (void);
void ves_icall_System_IO_MonoIO_DumpHandles (void)
{
#ifndef HOST_WIN32
- _wapi_handle_dump ();
+ mono_w32handle_dump ();
#endif
}
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
#ifdef ENABLE_CHECKED_BUILD
void mono_handle_verify (MonoRawHandle handle);
-#define HANDLE_INVARIANTS(H) mono_handle_verify((void*)(H).__obj)
+#define HANDLE_INVARIANTS(H) mono_handle_verify((void*)(H))
#else
#define HANDLE_INVARIANTS(H) (0)
#endif
+#define TYPED_HANDLE_PAYLOAD_NAME(TYPE) TYPE ## HandlePayload
#define TYPED_HANDLE_NAME(TYPE) TYPE ## Handle
-#define TYPED_HANDLE_DECL(TYPE) typedef struct { TYPE **__obj; } TYPED_HANDLE_NAME (TYPE) ;
+/*
+ * typedef struct {
+ * MonoObject *__obj;
+ * } MonoObjectHandlePayload;
+ *
+ * typedef MonoObjectHandlePayload* MonoObjectHandle;
+ */
+#define TYPED_HANDLE_DECL(TYPE) typedef struct { TYPE *__obj; } TYPED_HANDLE_PAYLOAD_NAME (TYPE) ; typedef TYPED_HANDLE_PAYLOAD_NAME (TYPE) * TYPED_HANDLE_NAME (TYPE);
-#define MONO_HANDLE_INIT { (void*)mono_null_value_handle.__obj }
+#define MONO_HANDLE_INIT ((void*) mono_null_value_handle)
#define NULL_HANDLE mono_null_value_handle
//XXX add functions to get/set raw, set field, set field to null, set array, set array to null
-#define MONO_HANDLE_RAW(HANDLE) (HANDLE_INVARIANTS (HANDLE), (*(HANDLE).__obj))
-#define MONO_HANDLE_DCL(TYPE, NAME) TYPED_HANDLE_NAME(TYPE) NAME = { mono_handle_new ((MonoObject*)(NAME ## _raw)) }
-#define MONO_HANDLE_NEW(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE)){ mono_handle_new ((MonoObject*)(VALUE)) }
-#define MONO_HANDLE_CAST(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE)){ (TYPE**)((VALUE).__obj) }
+#define MONO_HANDLE_RAW(HANDLE) (HANDLE_INVARIANTS (HANDLE), ((HANDLE)->__obj))
+#define MONO_HANDLE_DCL(TYPE, NAME) TYPED_HANDLE_NAME(TYPE) NAME = (TYPED_HANDLE_NAME(TYPE))(mono_handle_new ((MonoObject*)(NAME ## _raw)))
+#define MONO_HANDLE_NEW(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE))( mono_handle_new ((MonoObject*)(VALUE)) )
+#define MONO_HANDLE_CAST(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE))( VALUE )
/*
WARNING WARNING WARNING
ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_1)
ICALL(ASSEM_1, "FillName", ves_icall_System_Reflection_Assembly_FillName)
+ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId)
ICALL(ASSEM_2, "GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly)
ICALL(ASSEM_3, "GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly)
ICALL(ASSEM_4, "GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly)
ICALL(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)
ICALL(RTH_3, "GetAttributes", ves_icall_RuntimeTypeHandle_GetAttributes)
ICALL(RTH_4, "GetBaseType", ves_icall_RuntimeTypeHandle_GetBaseType)
ICALL(RTH_5, "GetElementType", ves_icall_RuntimeTypeHandle_GetElementType)
+ICALL(RTH_19, "GetGenericParameterInfo", ves_icall_RuntimeTypeHandle_GetGenericParameterInfo)
ICALL(RTH_6, "GetGenericTypeDefinition_impl", ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl)
ICALL(RTH_7, "GetMetadataToken", ves_icall_reflection_get_token)
ICALL(RTH_8, "GetModule", ves_icall_RuntimeTypeHandle_GetModule)
return -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
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)
{
*/
}
if (dll_map->func && strcmp (dll_map->func, func) == 0) {
+ *rdll = dll_map->target;
*rfunc = dll_map->target_func;
break;
}
* @dll: The name of the external library, as it would be found in the DllImport declaration. If prefixed with 'i:' the matching of the library name is done without case sensitivity
* @func: if not null, the mapping will only applied to the named function (the value of EntryPoint)
* @tdll: The name of the library to map the specified @dll if it matches.
- * @tfunc: if func is not NULL, the name of the function that replaces the invocation
+ * @tfunc: The name of the function that replaces the invocation. If NULL, it is replaced with a copy of @func.
*
* LOCKING: Acquires the loader lock.
*
entry->dll = dll? g_strdup (dll): NULL;
entry->target = tdll? g_strdup (tdll): NULL;
entry->func = func? g_strdup (func): NULL;
- entry->target_func = tfunc? g_strdup (tfunc): NULL;
+ entry->target_func = tfunc? g_strdup (tfunc): (func? g_strdup (func): NULL);
global_loader_data_lock ();
entry->next = global_dll_map;
entry->dll = dll? mono_image_strdup (assembly, dll): NULL;
entry->target = tdll? mono_image_strdup (assembly, tdll): NULL;
entry->func = func? mono_image_strdup (assembly, func): NULL;
- entry->target_func = tfunc? mono_image_strdup (assembly, tfunc): NULL;
+ entry->target_func = tfunc? mono_image_strdup (assembly, tfunc): (func? mono_image_strdup (assembly, func): NULL);
mono_image_lock (assembly);
entry->next = assembly->dll_map;
* ARGS should contain the this argument too.
* This wrapper serves the same purpose as the runtime-invoke wrappers, but there
* is only one copy of it, which is useful in full-aot.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod*
mono_marshal_get_runtime_invoke_dynamic (void)
/*
* generates IL code for the icall wrapper (the generated method
* calls the unmanaged code in func)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gconstpointer func, gboolean check_exceptions)
*
* generates IL code for the pinvoke wrapper (the generated method
* calls the unmanaged code in piinfo->addr)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, gboolean aot)
/*
* This does the equivalent of mono_object_castclass_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_castclass_with_cache (void)
/*
* This does the equivalent of mono_object_isinst_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_isinst_with_cache (void)
* an instance of the given type, icluding the case where the object is a proxy.
* The generated function has the following signature:
* MonoObject* __castclass_wrapper_ (MonoObject *obj)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_castclass (MonoClass *klass)
* @klass:
*
* generates IL code for StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_struct_to_ptr (MonoClass *klass)
* @klass:
*
* generates IL code for PtrToStructure (IntPtr src, object structure)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_ptr_to_struct (MonoClass *klass)
* This is used to avoid infinite recursion since it is hard to determine where to
* replace a method with its synchronized wrapper, and where not.
* The runtime should execute METHOD instead of the wrapper.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method)
#endif
/*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- *
* TODO:
* - Separate simple interfaces from variant interfaces or mbr types. This way we can avoid the icall for them.
* - Emit a (new) mono bytecode that produces OP_COND_EXC_NE_UN to raise ArrayTypeMismatch
return res;
}
-/*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- */
MonoMethod*
mono_marshal_get_stelemref (void)
{
* mono_marshal_get_gsharedvt_in_wrapper:
*
* This wrapper handles calls from normal code to gsharedvt code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod*
mono_marshal_get_gsharedvt_in_wrapper (void)
* mono_marshal_get_gsharedvt_out_wrapper:
*
* This wrapper handles calls from gsharedvt code to normal code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod*
mono_marshal_get_gsharedvt_out_wrapper (void)
gpointer aot_module;
+ guint8 aotid[16];
+
/*
* The Assembly this image was loaded from.
*/
if (!read32 (ptr + 8) || !read32 (ptr + 12))
ADD_ERROR (ctx, g_strdup_printf ("Missing medatata section in the CLI header"));
- if ((read32 (ptr + 16) & ~0x0001000B) != 0)
+ if ((read32 (ptr + 16) & ~0x0003000B) != 0)
ADD_ERROR (ctx, g_strdup_printf ("Invalid CLI header flags"));
ptr += 24;
guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
}
+/**
+ * mono_guid_to_string_minimal:
+ *
+ * Converts a 16 byte Microsoft GUID to lower case no '-' representation..
+ */
+char *
+mono_guid_to_string_minimal (const guint8 *guid)
+{
+ return g_strdup_printf ("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ guid[3], guid[2], guid[1], guid[0],
+ guid[5], guid[4],
+ guid[7], guid[6],
+ guid[8], guid[9],
+ guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
+}
static gboolean
get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGenericContainer *container, MonoError *error)
{
struct _MonoArrayType {
MonoClass *eklass;
+ // Number of dimensions of the array
uint8_t rank;
+
+ // Arrays recording known upper and lower index bounds for each dimension
uint8_t numsizes;
uint8_t numlobounds;
int *sizes;
MONO_API char *mono_guid_to_string (const uint8_t *guid);
+MONO_API char *mono_guid_to_string_minimal (const uint8_t *guid);
+
MONO_API uint32_t mono_metadata_declsec_from_index (MonoImage *meta, uint32_t idx);
MONO_API uint32_t mono_metadata_translate_token_index (MonoImage *image, int table, uint32_t idx);
#include <mono/io-layer/io-layer.h>
/* FIXME: fix this code to not depend so much on the internals */
#include <mono/metadata/class-internals.h>
+#include <mono/utils/w32handle.h>
#define LOGDEBUG(...)
/* define LOGDEBUG(...) g_message(__VA_ARGS__) */
void (*register_finalized_object) (GCObject *object);
void (*describe_pointer) (GCObject *object);
void (*enable_accounting) (void);
+
+ // Optional-- used for debugging
void (*set_dump_prefix) (const char *prefix);
/*
void sgen_tarjan_bridge_init (SgenBridgeProcessor *collector);
void sgen_set_bridge_implementation (const char *name);
void sgen_bridge_set_dump_prefix (const char *prefix);
+void sgen_init_bridge_processor();
#endif
sgen_gc_unlock ();
}
-
void
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 (!bridge_processor.reset_data)
- sgen_new_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));
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'.");
}
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));
* unreachable objects. We use it in monodroid to do garbage collection across
* the Mono and Java heaps.
*
- * The client can designate some objects as "bridged", which means that they
- * participate in the bridge processing step once SGen considers them
+ * The client (Monodroid) can designate some objects as "bridged", which means
+ * that they participate in the bridge processing step once SGen considers them
* unreachable, i.e., dead. Bridged objects must be registered for
* finalization.
*
* When SGen is done marking, it puts together a list of all dead bridged
- * objects and then does a strongly connected component analysis over their
- * object graph. That graph will usually contain non-bridged objects, too.
+ * objects. This is passed to the bridge processor, which does an analysis to
+ * simplify the graph: It replaces strongly-connected components with single
+ * nodes, and then removes any nodes corresponding to components which do not
+ * contain bridged objects.
*
- * The output of the SCC analysis is passed to the `cross_references()`
- * callback. It is expected to set the `is_alive` flag on those strongly
- * connected components that it wishes to be kept alive. Only bridged objects
- * will be reported to the callback, i.e., non-bridged objects are removed from
- * the callback graph.
+ * The output of the SCC analysis is passed to the client's `cross_references()`
+ * callback. This consists of 2 arrays, an array of SCCs (MonoGCBridgeSCC),
+ * and an array of "xrefs" (edges between SCCs, MonoGCBridgeXRef). Edges are
+ * encoded as pairs of "API indices", ie indexes in the SCC array. The client
+ * is expected to set the `is_alive` flag on those strongly connected components
+ * that it wishes to be kept alive.
*
* In monodroid each bridged object has a corresponding Java mirror object. In
* the bridge callback it reifies the Mono object graph in the Java heap so that
* point all links to bridged objects that don't have `is_alive` set are nulled.
* Note that weak links to non-bridged objects reachable from bridged objects
* are not nulled. This might be considered a bug.
+ *
+ * There are three different implementations of the bridge processor, each of
+ * which implements 8 callbacks (see SgenBridgeProcessor). The implementations
+ * differ in the algorithm they use to compute the "simplified" SCC graph.
*/
#ifndef _MONO_SGEN_BRIDGE_H_
void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs);
} MonoGCBridgeCallbacks;
+// 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);
--- /dev/null
+/*
+ * Copyright 2016 Xamarin, Inc.
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+ // Growable array implementation used by sgen-new-bridge and sgen-tarjan-bridge.
+
+typedef struct {
+ int size;
+ int capacity; /* if negative, data points to another DynArray's data */
+ char *data;
+} DynArray;
+
+/*Specializations*/
+
+// IntArray supports an optimization (in sgen-new-bridge.c): If capacity is less than 0 it is a "copy" and does not own its buffer.
+typedef struct {
+ DynArray array;
+} DynIntArray;
+
+// PtrArray supports an optimization: If size is equal to 1 it is a "singleton" and data points to the single held item, not to a buffer.
+typedef struct {
+ DynArray array;
+} DynPtrArray;
+
+typedef struct {
+ DynArray array;
+} DynSCCArray;
+
+static void
+dyn_array_init (DynArray *da)
+{
+ da->size = 0;
+ da->capacity = 0;
+ da->data = NULL;
+}
+
+static void
+dyn_array_uninit (DynArray *da, int elem_size)
+{
+ if (da->capacity < 0) {
+ dyn_array_init (da);
+ return;
+ }
+
+ if (da->capacity == 0)
+ return;
+
+ sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
+ da->data = NULL;
+}
+
+static void
+dyn_array_empty (DynArray *da)
+{
+ if (da->capacity < 0)
+ dyn_array_init (da);
+ else
+ da->size = 0;
+}
+
+static char *
+dyn_array_ensure_capacity_internal (DynArray *da, int capacity, int elem_size)
+{
+ if (da->capacity <= 0)
+ da->capacity = 2;
+ while (capacity > da->capacity)
+ da->capacity *= 2;
+
+ return (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+}
+
+static void
+dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
+{
+ int old_capacity = da->capacity;
+ char *new_data;
+
+ g_assert (capacity > 0);
+
+ if (capacity <= old_capacity)
+ return;
+
+ new_data = dyn_array_ensure_capacity_internal (da, capacity, elem_size);
+ memcpy (new_data, da->data, elem_size * da->size);
+ if (old_capacity > 0)
+ sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
+ da->data = new_data;
+}
+
+static gboolean
+dyn_array_is_copy (DynArray *da)
+{
+ return da->capacity < 0;
+}
+
+static void
+dyn_array_ensure_independent (DynArray *da, int elem_size)
+{
+ if (!dyn_array_is_copy (da))
+ return;
+ dyn_array_ensure_capacity (da, da->size, elem_size);
+ g_assert (da->capacity > 0);
+}
+
+static void*
+dyn_array_add (DynArray *da, int elem_size)
+{
+ void *p;
+
+ dyn_array_ensure_capacity (da, da->size + 1, elem_size);
+
+ p = da->data + da->size * elem_size;
+ ++da->size;
+ return p;
+}
+
+static void
+dyn_array_copy (DynArray *dst, DynArray *src, int elem_size)
+{
+ dyn_array_uninit (dst, elem_size);
+
+ if (src->size == 0)
+ return;
+
+ dst->size = src->size;
+ dst->capacity = -1;
+ dst->data = src->data;
+}
+
+/* int */
+static void
+dyn_array_int_init (DynIntArray *da)
+{
+ dyn_array_init (&da->array);
+}
+
+static void
+dyn_array_int_uninit (DynIntArray *da)
+{
+ dyn_array_uninit (&da->array, sizeof (int));
+}
+
+static int
+dyn_array_int_size (DynIntArray *da)
+{
+ return da->array.size;
+}
+
+#ifdef NEW_XREFS
+static void
+dyn_array_int_empty (DynIntArray *da)
+{
+ dyn_array_empty (&da->array);
+}
+#endif
+
+static void
+dyn_array_int_add (DynIntArray *da, int x)
+{
+ int *p = (int *)dyn_array_add (&da->array, sizeof (int));
+ *p = x;
+}
+
+static int
+dyn_array_int_get (DynIntArray *da, int x)
+{
+ return ((int*)da->array.data)[x];
+}
+
+#ifdef NEW_XREFS
+static void
+dyn_array_int_set (DynIntArray *da, int idx, int val)
+{
+ ((int*)da->array.data)[idx] = val;
+}
+#endif
+
+static void
+dyn_array_int_ensure_independent (DynIntArray *da)
+{
+ dyn_array_ensure_independent (&da->array, sizeof (int));
+}
+
+static void
+dyn_array_int_copy (DynIntArray *dst, DynIntArray *src)
+{
+ dyn_array_copy (&dst->array, &src->array, sizeof (int));
+}
+
+static gboolean
+dyn_array_int_is_copy (DynIntArray *da)
+{
+ return dyn_array_is_copy (&da->array);
+}
+
+/* ptr */
+
+static void
+dyn_array_ptr_init (DynPtrArray *da)
+{
+ dyn_array_init (&da->array);
+}
+
+static void
+dyn_array_ptr_uninit (DynPtrArray *da)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1)
+ dyn_array_ptr_init (da);
+ else
+#endif
+ dyn_array_uninit (&da->array, sizeof (void*));
+}
+
+static int
+dyn_array_ptr_size (DynPtrArray *da)
+{
+ return da->array.size;
+}
+
+static void
+dyn_array_ptr_empty (DynPtrArray *da)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1)
+ dyn_array_ptr_init (da);
+ else
+#endif
+ dyn_array_empty (&da->array);
+}
+
+static void*
+dyn_array_ptr_get (DynPtrArray *da, int x)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1) {
+ g_assert (x == 0);
+ return da->array.data;
+ }
+#endif
+ return ((void**)da->array.data)[x];
+}
+
+static void
+dyn_array_ptr_set (DynPtrArray *da, int x, void *ptr)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1) {
+ g_assert (x == 0);
+ da->array.data = ptr;
+ } else
+#endif
+ {
+ ((void**)da->array.data)[x] = ptr;
+ }
+}
+
+static void
+dyn_array_ptr_add (DynPtrArray *da, void *ptr)
+{
+ void **p;
+
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 0) {
+ da->array.capacity = 1;
+ da->array.size = 1;
+ p = (void**)&da->array.data;
+ } else if (da->array.capacity == 1) {
+ void *ptr0 = da->array.data;
+ void **p0;
+ dyn_array_init (&da->array);
+ p0 = (void **)dyn_array_add (&da->array, sizeof (void*));
+ *p0 = ptr0;
+ p = (void **)dyn_array_add (&da->array, sizeof (void*));
+ } else
+#endif
+ {
+ p = (void **)dyn_array_add (&da->array, sizeof (void*));
+ }
+ *p = ptr;
+}
+
+#define dyn_array_ptr_push dyn_array_ptr_add
+
+static void*
+dyn_array_ptr_pop (DynPtrArray *da)
+{
+ int size = da->array.size;
+ void *p;
+ g_assert (size > 0);
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1) {
+ p = dyn_array_ptr_get (da, 0);
+ dyn_array_init (&da->array);
+ } else
+#endif
+ {
+ g_assert (da->array.capacity > 1);
+ dyn_array_ensure_independent (&da->array, sizeof (void*));
+ p = dyn_array_ptr_get (da, size - 1);
+ --da->array.size;
+ }
+ return p;
+}
+
+static void
+dyn_array_ptr_ensure_capacity (DynPtrArray *da, int capacity)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (capacity == 1 && da->array.capacity < 1) {
+ da->array.capacity = 1;
+ } else if (da->array.capacity == 1) // TODO size==1
+ {
+ if (capacity > 1)
+ {
+ void *ptr = dyn_array_ptr_get (da, 0);
+ da->array.data = dyn_array_ensure_capacity_internal(&da->array, capacity, sizeof (void*));
+ dyn_array_ptr_set (da, 0, ptr);
+ }
+ }
+#endif
+ {
+ dyn_array_ensure_capacity (&da->array, capacity, sizeof (void*));
+ }
+}
+
+static void
+dyn_array_ptr_set_all (DynPtrArray *dst, DynPtrArray *src)
+{
+ const int copysize = src->array.size;
+ if (copysize > 0) {
+ dyn_array_ptr_ensure_capacity (dst, copysize);
+
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (copysize == 1) {
+ dyn_array_ptr_set (dst, 0, dyn_array_ptr_get (src, 0));
+ } else
+#endif
+ {
+ memcpy (dst->array.data, src->array.data, copysize * sizeof (void*));
+ }
+ }
+ dst->array.size = src->array.size;
+}
#include "tabledefs.h"
#include "utils/mono-logger-internals.h"
+#define OPTIMIZATION_COPY
+#define OPTIMIZATION_FORWARD
+#define OPTIMIZATION_SINGLETON_DYN_ARRAY
+#include "sgen-dynarray.h"
+
//#define NEW_XREFS
#ifdef NEW_XREFS
//#define TEST_NEW_XREFS
#define XREFS old_xrefs
#endif
-#define OPTIMIZATION_COPY
-#define OPTIMIZATION_FORWARD
-#define OPTIMIZATION_SINGLETON_DYN_ARRAY
-
-typedef struct {
- int size;
- int capacity; /* if negative, data points to another DynArray's data */
- char *data;
-} DynArray;
-
-/*Specializations*/
-
-typedef struct {
- DynArray array;
-} DynIntArray;
-
-typedef struct {
- DynArray array;
-} DynPtrArray;
-
-typedef struct {
- DynArray array;
-} DynSCCArray;
-
-
/*
* Bridge data for a single managed object
*
static SgenBridgeProcessor *bridge_processor;
/* Core functions */
-/* public */
-
-/* private */
-
-static void
-dyn_array_init (DynArray *da)
-{
- da->size = 0;
- da->capacity = 0;
- da->data = NULL;
-}
-
-static void
-dyn_array_uninit (DynArray *da, int elem_size)
-{
- if (da->capacity < 0) {
- dyn_array_init (da);
- return;
- }
-
- if (da->capacity == 0)
- return;
-
- sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
- da->data = NULL;
-}
-
-static void
-dyn_array_empty (DynArray *da)
-{
- if (da->capacity < 0)
- dyn_array_init (da);
- else
- da->size = 0;
-}
-
-static void
-dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
-{
- int old_capacity = da->capacity;
- char *new_data;
-
- g_assert (capacity > 0);
-
- if (capacity <= old_capacity)
- return;
-
- if (old_capacity <= 0)
- da->capacity = 2;
- while (capacity > da->capacity)
- da->capacity *= 2;
-
- new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
- memcpy (new_data, da->data, elem_size * da->size);
- if (old_capacity > 0)
- sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
- da->data = new_data;
-}
-
-static gboolean
-dyn_array_is_copy (DynArray *da)
-{
- return da->capacity < 0;
-}
-
-static void
-dyn_array_ensure_independent (DynArray *da, int elem_size)
-{
- if (!dyn_array_is_copy (da))
- return;
- dyn_array_ensure_capacity (da, da->size, elem_size);
- g_assert (da->capacity > 0);
-}
-
-static void*
-dyn_array_add (DynArray *da, int elem_size)
-{
- void *p;
-
- dyn_array_ensure_capacity (da, da->size + 1, elem_size);
-
- p = da->data + da->size * elem_size;
- ++da->size;
- return p;
-}
-
-static void
-dyn_array_copy (DynArray *dst, DynArray *src, int elem_size)
-{
- dyn_array_uninit (dst, elem_size);
-
- if (src->size == 0)
- return;
-
- dst->size = src->size;
- dst->capacity = -1;
- dst->data = src->data;
-}
-
-/* int */
-static void
-dyn_array_int_init (DynIntArray *da)
-{
- dyn_array_init (&da->array);
-}
-
-static void
-dyn_array_int_uninit (DynIntArray *da)
-{
- dyn_array_uninit (&da->array, sizeof (int));
-}
-
-static int
-dyn_array_int_size (DynIntArray *da)
-{
- return da->array.size;
-}
-
-#ifdef NEW_XREFS
-static void
-dyn_array_int_empty (DynIntArray *da)
-{
- dyn_array_empty (&da->array);
-}
-#endif
-
-static void
-dyn_array_int_add (DynIntArray *da, int x)
-{
- int *p = (int *)dyn_array_add (&da->array, sizeof (int));
- *p = x;
-}
-
-static int
-dyn_array_int_get (DynIntArray *da, int x)
-{
- return ((int*)da->array.data)[x];
-}
-
-#ifdef NEW_XREFS
-static void
-dyn_array_int_set (DynIntArray *da, int idx, int val)
-{
- ((int*)da->array.data)[idx] = val;
-}
-#endif
-
-static void
-dyn_array_int_ensure_independent (DynIntArray *da)
-{
- dyn_array_ensure_independent (&da->array, sizeof (int));
-}
-
-static void
-dyn_array_int_copy (DynIntArray *dst, DynIntArray *src)
-{
- dyn_array_copy (&dst->array, &src->array, sizeof (int));
-}
-
-static gboolean
-dyn_array_int_is_copy (DynIntArray *da)
-{
- return dyn_array_is_copy (&da->array);
-}
-
-/* ptr */
-
-static void
-dyn_array_ptr_init (DynPtrArray *da)
-{
- dyn_array_init (&da->array);
-}
-
-static void
-dyn_array_ptr_uninit (DynPtrArray *da)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1)
- dyn_array_ptr_init (da);
- else
-#endif
- dyn_array_uninit (&da->array, sizeof (void*));
-}
-
-static int
-dyn_array_ptr_size (DynPtrArray *da)
-{
- return da->array.size;
-}
-
-static void
-dyn_array_ptr_empty (DynPtrArray *da)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1)
- dyn_array_ptr_init (da);
- else
-#endif
- dyn_array_empty (&da->array);
-}
-
-static void*
-dyn_array_ptr_get (DynPtrArray *da, int x)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1) {
- g_assert (x == 0);
- return da->array.data;
- }
-#endif
- return ((void**)da->array.data)[x];
-}
-
-static void
-dyn_array_ptr_add (DynPtrArray *da, void *ptr)
-{
- void **p;
-
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 0) {
- da->array.capacity = 1;
- da->array.size = 1;
- p = (void**)&da->array.data;
- } else if (da->array.capacity == 1) {
- void *ptr0 = da->array.data;
- void **p0;
- dyn_array_init (&da->array);
- p0 = (void **)dyn_array_add (&da->array, sizeof (void*));
- *p0 = ptr0;
- p = (void **)dyn_array_add (&da->array, sizeof (void*));
- } else
-#endif
- {
- p = (void **)dyn_array_add (&da->array, sizeof (void*));
- }
- *p = ptr;
-}
-
-#define dyn_array_ptr_push dyn_array_ptr_add
-
-static void*
-dyn_array_ptr_pop (DynPtrArray *da)
-{
- int size = da->array.size;
- void *p;
- g_assert (size > 0);
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1) {
- p = dyn_array_ptr_get (da, 0);
- dyn_array_init (&da->array);
- } else
-#endif
- {
- g_assert (da->array.capacity > 1);
- dyn_array_ensure_independent (&da->array, sizeof (void*));
- p = dyn_array_ptr_get (da, size - 1);
- --da->array.size;
- }
- return p;
-}
/*SCC */
#include "tabledefs.h"
#include "utils/mono-logger-internals.h"
-typedef struct {
- int size;
- int capacity;
- char *data;
-} DynArray;
-
-/*Specializations*/
-
-typedef struct {
- DynArray array;
-} DynPtrArray;
-
-/* private */
-
-static void
-dyn_array_uninit (DynArray *da, int elem_size)
-{
- if (da->capacity <= 0)
- return;
+#include "sgen-dynarray.h"
- sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
- da->data = NULL;
-}
-
-static void
-dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
-{
- int old_capacity = da->capacity;
- char *new_data;
-
- if (capacity <= old_capacity)
- return;
-
- if (da->capacity == 0)
- da->capacity = 2;
- while (capacity > da->capacity)
- da->capacity *= 2;
-
- new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
- if (da->data) {
- memcpy (new_data, da->data, elem_size * da->size);
- sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
- }
- da->data = new_data;
-}
-
-static void*
-dyn_array_add (DynArray *da, int elem_size)
-{
- void *p;
-
- dyn_array_ensure_capacity (da, da->size + 1, elem_size);
-
- p = da->data + da->size * elem_size;
- ++da->size;
- return p;
-}
-
-/* ptr */
-
-static void
-dyn_array_ptr_uninit (DynPtrArray *da)
-{
- dyn_array_uninit (&da->array, sizeof (void*));
-}
-
-static int
-dyn_array_ptr_size (DynPtrArray *da)
-{
- return da->array.size;
-}
-
-static void
-dyn_array_ptr_set_size (DynPtrArray *da, int size)
-{
- da->array.size = size;
-}
-
-static void*
-dyn_array_ptr_get (DynPtrArray *da, int x)
-{
- return ((void**)da->array.data)[x];
-}
-
-static void
-dyn_array_ptr_add (DynPtrArray *da, void *ptr)
-{
- void **p = (void **)dyn_array_add (&da->array, sizeof (void*));
- *p = ptr;
-}
-
-#define dyn_array_ptr_push dyn_array_ptr_add
-
-static void*
-dyn_array_ptr_pop (DynPtrArray *da)
-{
- void *p;
- int size = da->array.size;
- g_assert (size > 0);
- p = dyn_array_ptr_get (da, size - 1);
- --da->array.size;
- return p;
-}
-
-static void
-dyn_array_ptr_ensure_capacity (DynPtrArray *da, int capacity)
-{
- dyn_array_ensure_capacity (&da->array, capacity, sizeof (void*));
-}
-
-
-static void
-dyn_array_ptr_set_all (DynPtrArray *dst, DynPtrArray *src)
-{
- if (src->array.size > 0) {
- dyn_array_ptr_ensure_capacity (dst, src->array.size);
- memcpy (dst->array.data, src->array.data, src->array.size * sizeof (void*));
- }
- dst->array.size = src->array.size;
-}
+/*
+ * See comments in sgen-bridge.h
+ *
+ * This bridge implementation is based on the tarjan algorithm for strongly
+ * connected components. It has two elements:
+ *
+ * - Standard tarjan SCC algorithm to convert graph to SCC forest
+ *
+ * - "Colors": We reduce the SCC forest to bridged-SCCs-only by using a
+ * "color" algorithm devised by Kumpera. Consider the set of bridged SCCs
+ * which is reachable from a given object. We call each such unique set a
+ * "color". We compute the set of colors and which colors contain links to
+ * which colors. The color graph then becomes the reduced SCC graph.
+ */
static void
enable_accounting (void)
// hash_table = (SgenHashTable)SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
}
+// Is this class bridged or not, and should its dependencies be scanned or not?
+// The result of this callback will be cached for use by is_opaque_object later.
static MonoGCBridgeObjectKind
class_kind (MonoClass *klass)
{
return GC_BRIDGE_TRANSPARENT_CLASS;
}
-//enable unsage logging
+//enable usage logging
// #define DUMP_GRAPH 1
+// ScanData state
enum {
INITIAL,
SCANNED,
We can split this data structure in two, those with bridges and those without
*/
typedef struct {
+ // Colors (ColorDatas) linked to by objects with this color
DynPtrArray other_colors;
+ // Bridge objects (GCObjects) held by objects with this color
DynPtrArray bridges;
int api_index : 31;
unsigned visited : 1;
} ColorData;
-
-typedef struct {
- GCObject *obj; //XXX this can be eliminated.
+// Represents one managed object. Equivalent of new/old bridge "HashEntry"
+typedef struct _ScanData {
+ // FIXME this can be eliminated; if we have a ScanData we generally looked it up from its GCObject
+ GCObject *obj;
+ // We use the sgen lock_word in GCObject to store a pointer to the ScanData. Cache the original here to restore later:
mword lock_word;
ColorData *color;
+ // Tarjan algorithm index (order visited)
int index;
+ // Tarjan index of lowest-index object known reachable from here
int low_index : 27;
+ // See "ScanData state" enum above
unsigned state : 2;
unsigned is_bridge : 1;
+ // Similar to lock_word, we use these bits in the GCObject as scratch space then restore them when done
unsigned obj_state : 2;
} ScanData;
+// Stacks of ScanData objects used for tarjan algorithm.
+// The Tarjan algorithm is normally defined recursively; here scan_stack simulates the call stack of a recursive algorithm,
+// and loop_stack is the stack structure used by the algorithm itself.
+static DynPtrArray scan_stack, loop_stack;
-static DynPtrArray scan_stack, loop_stack, registered_bridges;
+// GCObjects on which register_finalized_object has been called
+static DynPtrArray registered_bridges;
+
+// ColorData objects
static DynPtrArray color_merge_array;
static int ignored_objects;
//ColorData buckets
#define NUM_COLOR_ENTRIES ((BUCKET_SIZE - SIZEOF_VOID_P * 2) / sizeof (ColorData))
+// Same as ObjectBucket except NUM_COLOR_ENTRIES and NUM_SCAN_ENTRIES differ
typedef struct _ColorBucket ColorBucket;
struct _ColorBucket {
ColorBucket *next;
res->obj = obj;
res->color = NULL;
res->index = res->low_index = -1;
+ res->state = INITIAL;
+ res->is_bridge = FALSE;
res->obj_state = o [0] & SGEN_VTABLE_BITS_MASK;
res->lock_word = o [1];
return FALSE;
}
+// Called during DFS; visits one child. If it is a candidate to be scanned, pushes it to the stacks.
static void
push_object (GCObject *obj)
{
if (dst) push_object (dst); \
} while (0)
+// dfs () function's queue-children-of-object operation.
static void
push_all (ScanData *data)
{
mword desc = sgen_obj_get_descriptor_safe (obj);
#if DUMP_GRAPH
- printf ("**scanning %p %s\n", obj, safe_name_bridge (obj));
+ printf ("+scanning %s (%p) index %d color %p\n", safe_name_bridge (data->obj), data->obj, data->index, data->color);
#endif
#include "sgen/sgen-scan-object.h"
{
ScanData *other;
ColorData *cd;
- obj = bridge_object_forward (obj);
+ obj = bridge_object_forward (obj);
other = find_data (obj);
#if DUMP_GRAPH
#if DUMP_GRAPH
printf ("|SCC rooted in %s (%p) has bridge %d\n", safe_name_bridge (data->obj), data->obj, found_bridge);
printf ("\tpoints-to-colors: ");
- for (i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i)
+ for (int i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i)
printf ("%p ", dyn_array_ptr_get (&color_merge_array, i));
printf ("\n");
printf ("loop stack: ");
- for (i = 0; i < dyn_array_ptr_size (&loop_stack); ++i) {
+ for (int i = 0; i < dyn_array_ptr_size (&loop_stack); ++i) {
ScanData *other = dyn_array_ptr_get (&loop_stack, i);
printf ("(%d/%d)", other->index, other->low_index);
}
g_assert (cd->visited);
cd->visited = FALSE;
}
- dyn_array_ptr_set_size (&color_merge_array, 0);
+ dyn_array_ptr_empty (&color_merge_array);
found_bridge = FALSE;
}
g_assert (dyn_array_ptr_size (&scan_stack) == 1);
g_assert (dyn_array_ptr_size (&loop_stack) == 0);
- dyn_array_ptr_set_size (&color_merge_array, 0);
+ dyn_array_ptr_empty (&color_merge_array);
while (dyn_array_ptr_size (&scan_stack) > 0) {
ScanData *data = (ScanData *)dyn_array_ptr_pop (&scan_stack);
static void
reset_data (void)
{
- dyn_array_ptr_set_size (®istered_bridges, 0);
+ dyn_array_ptr_empty (®istered_bridges);
}
static void
cleanup (void)
{
- dyn_array_ptr_set_size (&scan_stack, 0);
- dyn_array_ptr_set_size (&loop_stack, 0);
- dyn_array_ptr_set_size (®istered_bridges, 0);
+ dyn_array_ptr_empty (&scan_stack);
+ dyn_array_ptr_empty (&loop_stack);
+ dyn_array_ptr_empty (®istered_bridges);
free_object_buckets ();
free_color_buckets ();
reset_cache ();
#if defined (DUMP_GRAPH)
printf ("----summary----\n");
printf ("bridges:\n");
- for (i = 0; i < bridge_count; ++i) {
+ for (int i = 0; i < bridge_count; ++i) {
ScanData *sd = find_data (dyn_array_ptr_get (®istered_bridges, i));
printf ("\t%s (%p) index %d color %p\n", safe_name_bridge (sd->obj), sd->obj, sd->index, sd->color);
}
if (!bridges)
continue;
- dyn_array_ptr_set_size (&color_merge_array, 0);
+ dyn_array_ptr_empty (&color_merge_array);
gather_xrefs (cd);
reset_xrefs (cd);
dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
#if defined (DUMP_GRAPH)
printf ("---xrefs:\n");
- for (i = 0; i < xref_count; ++i)
+ for (int i = 0; i < xref_count; ++i)
printf ("\t%d -> %d\n", api_xrefs [i].src_scc_index, api_xrefs [i].dst_scc_index);
#endif
#include <mono/utils/mono-threads.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/networking.h>
+#include <mono/utils/w32handle.h>
#include <time.h>
#ifdef HAVE_SYS_TIME_H
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*/
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-rand.h>
#include <mono/utils/json.h>
#include <mono/utils/mono-threads-coop.h>
gboolean soft_debug;
gboolean log_generics;
gboolean log_instances;
- gboolean gen_seq_points_file;
- char *gen_seq_points_file_path;
+ gboolean gen_msym_dir;
+ char *gen_msym_dir_path;
gboolean direct_pinvoke;
gboolean direct_icalls;
gboolean no_direct_calls;
if (acfg->aot_opts.mtriple && strstr (acfg->aot_opts.mtriple, "darwin")) {
g_string_append (acfg->llc_args, "-mattr=+v6");
} else {
-#ifdef ARM_FPU_VFP
+#if defined(ARM_FPU_VFP_HARD)
+ g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16 -float-abi=hard");
+ g_string_append (acfg->as_args, " -mfpu=vfp3");
+#elif defined(ARM_FPU_VFP)
g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16");
g_string_append (acfg->as_args, " -mfpu=vfp3");
#else
} 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")) {
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");
g_ptr_array_free (table, TRUE);
}
+static void
+generate_aotid (guint8* aotid)
+{
+ gpointer *rand_handle;
+ MonoError error;
+
+ mono_rand_open ();
+ rand_handle = mono_rand_init (NULL, 0);
+
+ mono_rand_try_get_bytes (rand_handle, aotid, 16, &error);
+ mono_error_assert_ok (&error);
+
+ mono_rand_close (rand_handle);
+}
+
static void
emit_exception_info (MonoAotCompile *acfg)
{
// By design aot-runtime decode_exception_debug_info is not able to load sequence point debug data from a file.
// As it is not possible to load debug data from a file its is also not possible to store it in a file.
- gboolean method_seq_points_to_file = acfg->aot_opts.gen_seq_points_file &&
+ gboolean method_seq_points_to_file = acfg->aot_opts.gen_msym_dir &&
cfg->gen_seq_points && !cfg->gen_sdb_seq_points;
gboolean method_seq_points_to_binary = cfg->gen_seq_points && !method_seq_points_to_file;
}
if (seq_points_to_file) {
- char *seq_points_aot_file = acfg->aot_opts.gen_seq_points_file_path ? acfg->aot_opts.gen_seq_points_file_path
- : g_strdup_printf("%s%s", acfg->image->name, SEQ_POINT_AOT_EXT);
- mono_seq_point_data_write (&sp_data, seq_points_aot_file);
+ char *aotid = mono_guid_to_string_minimal (acfg->image->aotid);
+ char *dir = g_build_filename (acfg->aot_opts.gen_msym_dir_path, aotid, NULL);
+ char *image_basename = g_path_get_basename (acfg->image->name);
+ char *aot_file = g_strdup_printf("%s%s", image_basename, SEQ_POINT_AOT_EXT);
+ char *aot_file_path = g_build_filename (dir, aot_file, NULL);
+
+ if (g_ensure_directory_exists (aot_file_path) == FALSE) {
+ fprintf (stderr, "AOT : failed to create msym directory: %s\n", aot_file_path);
+ exit (1);
+ }
+
+ mono_seq_point_data_write (&sp_data, aot_file_path);
mono_seq_point_data_free (&sp_data);
- g_free (seq_points_aot_file);
+
+ g_free (aotid);
+ g_free (dir);
+ g_free (image_basename);
+ g_free (aot_file);
+ g_free (aot_file_path);
}
acfg->stats.offsets_size += emit_offset_table (acfg, "ex_info_offsets", MONO_AOT_TABLE_EX_INFO_OFFSETS, acfg->nmethods, 10, offsets);
info->nshared_got_entries = acfg->nshared_got_entries;
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
info->tramp_page_code_offsets [i] = acfg->tramp_page_code_offsets [i];
+
+ memcpy(&info->aotid, acfg->image->aotid, 16);
}
static void
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
emit_int32 (acfg, info->tramp_page_code_offsets [i]);
+ emit_bytes (acfg, info->aotid, 16);
+
if (acfg->aot_opts.static_link) {
emit_global_inner (acfg, acfg->static_linking_symbol, FALSE);
emit_alignment (acfg, sizeof (gpointer));
* 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);
aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name);
+ generate_aotid ((guint8*) &acfg->image->aotid);
+
+ char *aotid = mono_guid_to_string (acfg->image->aotid);
+ aot_printf (acfg, "AOTID %s\n", aotid);
+ g_free (aotid);
+
#ifndef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
if (mono_aot_mode_is_full (&acfg->aot_opts)) {
aot_printerrf (acfg, "--aot=full is not supported on this platform.\n");
msg = g_strdup_printf ("not compiled with --aot=llvmonly");
usable = FALSE;
}
-#ifdef TARGET_ARM
- /* mono_arch_find_imt_method () requires this */
- if ((info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
- msg = g_strdup_printf ("compiled against LLVM");
- usable = FALSE;
- }
- if (!(info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && mono_use_llvm) {
- msg = g_strdup_printf ("not compiled against LLVM");
- usable = FALSE;
- }
-#endif
if (mini_get_debug_options ()->mdb_optimizations && !(info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) {
msg = g_strdup_printf ("not compiled for debugging");
usable = FALSE;
find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&info);
}
+ // Copy aotid to MonoImage
+ memcpy(&assembly->image->aotid, info->aotid, 16);
+
if (version_symbol) {
/* Old file format */
version = atoi (version_symbol);
}
[Category ("!FULLAOT")]
+ [Category ("!BITCODE")]
public static int test_0_regress_668095_synchronized_gshared () {
return DoSomething (new DefaultRetriever ());
}
need_unbox_tramp = TRUE;
}
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
// FIXME: This can throw exceptions
addr = compiled_method = mono_compile_method_checked (m, error);
mono_error_assert_ok (error);
if (vt->klass->valuetype)
need_unbox_tramp = TRUE;
- // FIXME: This can throw exceptions
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
addr = compiled_method = mono_compile_method_checked (m, &error);
- mono_error_assert_ok (&error);
+ mono_error_raise_exception (&error);
g_assert (addr);
addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, need_unbox_tramp, &arg);
* but we don't have a a structure which could own its memory.
*/
if (G_UNLIKELY (!ftndesc)) {
- gpointer addr = mono_compile_method_checked (del->method, &error);
+ MonoMethod *m = del->method;
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
+ gpointer addr = mono_compile_method_checked (m, &error);
if (mono_error_set_pending_exception (&error))
return;
- if (del->method->klass->valuetype && mono_method_signature (del->method)->hasthis)
- addr = mono_aot_get_unbox_trampoline (del->method);
+ if (m->klass->valuetype && mono_method_signature (m)->hasthis)
+ addr = mono_aot_get_unbox_trampoline (m);
gpointer arg = mini_get_delegate_arg (del->method, addr);
method = mono_object_get_virtual_method (target, method);
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ method = mono_marshal_get_synchronized_wrapper (method);
+
del->method = method;
del->method_ptr = mono_compile_method_checked (method, &error);
if (mono_error_set_pending_exception (&error))
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
+#include <cstdlib>
+
extern "C" {
#include <mono/utils/mono-dl.h>
}
#endif
+static AllocCodeMemoryCb *alloc_code_mem_cb;
+
+class MonoJitMemoryManager : public RTDyldMemoryManager
+{
+public:
+ ~MonoJitMemoryManager() override;
+
+ uint8_t *allocateDataSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName,
+ bool IsReadOnly) override;
+
+ uint8_t *allocateCodeSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) override;
+
+ bool finalizeMemory(std::string *ErrMsg = nullptr) override;
+};
+
+MonoJitMemoryManager::~MonoJitMemoryManager()
+{
+}
+
+uint8_t *
+MonoJitMemoryManager::allocateDataSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName,
+ bool IsReadOnly) {
+ uint8_t *res = (uint8_t*)malloc (Size);
+ assert (res);
+ memset (res, 0, Size);
+ return res;
+}
+
+uint8_t *
+MonoJitMemoryManager::allocateCodeSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName)
+{
+ return alloc_code_mem_cb (NULL, Size);
+}
+
+bool
+MonoJitMemoryManager::finalizeMemory(std::string *ErrMsg)
+{
+ return false;
+}
+
class MonoLLVMJIT {
public:
/* We use our own trampoline infrastructure instead of the Orc one */
} );
return CompileLayer.addModuleSet(singletonSet(M),
- make_unique<SectionMemoryManager>(),
+ make_unique<MonoJitMemoryManager>(),
std::move(Resolver));
}
MonoEERef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
{
+ alloc_code_mem_cb = alloc_cb;
+
InitializeNativeTarget ();
InitializeNativeTargetAsmPrinter();
inline_costs += 10 * num_calls++;
+ /*
+ * Synchronized wrappers.
+ * Its hard to determine where to replace a method with its synchronized
+ * wrapper without causing an infinite recursion. The current solution is
+ * to add the synchronized wrapper in the trampolines, and to
+ * change the called method to a dummy wrapper, and resolve that wrapper
+ * to the real method in mono_jit_compile_method ().
+ */
+ if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
+ MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
+ if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
+ cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
+ }
+
/*
* Making generic calls out of gsharedvt methods.
* This needs to be used for all generic calls, not just ones with a gsharedvt signature, to avoid
}
}
- /*
- * Synchronized wrappers.
- * Its hard to determine where to replace a method with its synchronized
- * wrapper without causing an infinite recursion. The current solution is
- * to add the synchronized wrapper in the trampolines, and to
- * change the called method to a dummy wrapper, and resolve that wrapper
- * to the real method in mono_jit_compile_method ().
- */
- if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
- MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
- if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
- cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
- }
-
/*
* Virtual calls in llvm-only mode.
*/
MONO_EMIT_NULL_CHECK (cfg, sp [0]->dreg);
+ if (ins_flag & MONO_INST_VOLATILE) {
+ /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
+ emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL);
+ }
+
if (mini_is_gsharedvt_klass (klass)) {
MonoInst *offset_ins;
}
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;
guint32 argsize = 8;
ArgumentClass arg_class;
MonoMarshalType *info = NULL;
- MonoMarshalField *fields = NULL;
+ StructFieldInfo *fields = NULL;
MonoClass *klass;
gboolean pass_on_stack = FALSE;
* 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;
}
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;
/* use the right size when copying args/return vars. */
guint32 quadsize [2] = {8, 8};
ArgumentClass args [2];
- MonoMarshalType *info = NULL;
- MonoMarshalField *fields = NULL;
+ StructFieldInfo *fields = NULL;
MonoClass *klass;
gboolean pass_on_stack = FALSE;
+ int struct_size;
klass = mono_class_from_mono_type (type);
size = mini_type_stack_size_full (&klass->byval_arg, NULL, sig->pinvoke);
/* If this struct can't be split up naturally into 8-byte */
/* chunks (registers), pass it on the stack. */
- if (sig->pinvoke && !pass_on_stack) {
- guint32 align;
- guint32 field_size;
-
- info = mono_marshal_load_type_info (klass);
+ if (sig->pinvoke) {
+ MonoMarshalType *info = mono_marshal_load_type_info (klass);
g_assert (info);
+ struct_size = info->native_size;
+ } else {
+ struct_size = mono_class_value_size (klass, NULL);
+ }
+ /*
+ * Collect field information recursively to be able to
+ * handle nested structures.
+ */
+ nfields = count_fields_nested (klass, sig->pinvoke);
+ fields = g_new0 (StructFieldInfo, nfields);
+ collect_field_info_nested (klass, fields, 0, 0, sig->pinvoke, klass->unicode);
- /*
- * Collect field information recursively to be able to
- * handle nested structures.
- */
- nfields = count_fields_nested (klass);
- fields = g_new0 (MonoMarshalField, nfields);
- collect_field_info_nested (klass, fields, 0, 0);
-
- for (i = 0; i < nfields; ++i) {
- field_size = mono_marshal_type_size (fields [i].field->type,
- fields [i].mspec,
- &align, TRUE, klass->unicode);
- if ((fields [i].offset < 8) && (fields [i].offset + field_size) > 8) {
- pass_on_stack = TRUE;
- break;
- }
+ for (i = 0; i < nfields; ++i) {
+ if ((fields [i].offset < 8) && (fields [i].offset + fields [i].size) > 8) {
+ pass_on_stack = TRUE;
+ break;
}
}
* The X87 and SSEUP stuff is left out since there are no such types in
* the CLR.
*/
- g_assert (info);
-
- if (!fields) {
+ if (!nfields) {
ainfo->storage = ArgValuetypeInReg;
ainfo->pair_storage [0] = ainfo->pair_storage [1] = ArgNone;
return;
}
- if (info->native_size > 16) {
+ if (struct_size > 16) {
ainfo->offset = *stack_size;
- *stack_size += ALIGN_TO (info->native_size, 8);
+ *stack_size += ALIGN_TO (struct_size, 8);
ainfo->storage = is_return ? ArgValuetypeAddrInIReg : ArgOnStack;
if (!is_return)
- ainfo->arg_size = ALIGN_TO (info->native_size, 8);
+ ainfo->arg_size = ALIGN_TO (struct_size, 8);
g_free (fields);
return;
args [0] = ARG_CLASS_NO_CLASS;
args [1] = ARG_CLASS_NO_CLASS;
for (quad = 0; quad < nquads; ++quad) {
- int size;
- guint32 align;
ArgumentClass class1;
if (nfields == 0)
else
class1 = ARG_CLASS_NO_CLASS;
for (i = 0; i < nfields; ++i) {
- size = mono_marshal_type_size (fields [i].field->type,
- fields [i].mspec,
- &align, TRUE, klass->unicode);
- if ((fields [i].offset < 8) && (fields [i].offset + size) > 8) {
+ if ((fields [i].offset < 8) && (fields [i].offset + fields [i].size) > 8) {
/* Unaligned field */
NOT_IMPLEMENTED;
}
/* How far into this quad this data extends.*/
/* (8 is size of quad) */
- quadsize [quad] = fields [i].offset + size - (quad * 8);
+ quadsize [quad] = fields [i].offset + fields [i].size - (quad * 8);
- class1 = merge_argument_class_from_type (fields [i].field->type, class1);
+ class1 = merge_argument_class_from_type (fields [i].type, class1);
}
- g_assert (class1 != ARG_CLASS_NO_CLASS);
+ /* Empty structs have a nonzero size, causing this assert to be hit */
+ if (sig->pinvoke)
+ g_assert (class1 != ARG_CLASS_NO_CLASS);
args [quad] = class1;
}
}
break;
case ARG_CLASS_MEMORY:
break;
+ case ARG_CLASS_NO_CLASS:
+ break;
default:
g_assert_not_reached ();
}
ainfo->offset = *stack_size;
if (sig->pinvoke)
- arg_size = ALIGN_TO (info->native_size, 8);
+ arg_size = ALIGN_TO (struct_size, 8);
else
arg_size = nquads * sizeof(mgreg_t);
*stack_size += arg_size;
/* fall through */
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_TYPEDBYREF:
- add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
+ add_valuetype (sig, ainfo, ptype, FALSE, &gr, &fr, &stack_size);
break;
case MONO_TYPE_U8:
}
cfg->arch.saved_iregs = cfg->used_int_regs;
- if (cfg->method->save_lmf)
- /* Save all callee-saved registers normally, and restore them when unwinding through an LMF */
- cfg->arch.saved_iregs |= (1 << AMD64_RBX) | (1 << AMD64_R12) | (1 << AMD64_R13) | (1 << AMD64_R14) | (1 << AMD64_R15);
+ if (cfg->method->save_lmf) {
+ /* Save all callee-saved registers normally (except RBP, if not already used), and restore them when unwinding through an LMF */
+ guint32 iregs_to_save = AMD64_CALLEE_SAVED_REGS & ~(1<<AMD64_RBP);
+ cfg->arch.saved_iregs |= iregs_to_save;
+ }
if (cfg->arch.omit_fp)
cfg->arch.reg_save_area_offset = offset;
case ArgInFloatSSEReg:
case ArgInDoubleSSEReg:
case ArgValuetypeAddrInIReg:
+ case ArgValuetypeInReg:
break;
- case ArgValuetypeInReg: {
- ArgInfo *ainfo = &cinfo->ret;
-
- if (ainfo->pair_storage [0] != ArgNone && ainfo->pair_storage [0] != ArgInIReg)
- return FALSE;
- if (ainfo->pair_storage [1] != ArgNone && ainfo->pair_storage [1] != ArgInIReg)
- return FALSE;
- break;
- }
default:
return FALSE;
}
case ArgInIReg:
case ArgInFloatSSEReg:
case ArgInDoubleSSEReg:
- break;
case ArgValuetypeInReg:
- if (ainfo->pair_storage [0] != ArgNone && ainfo->pair_storage [0] != ArgInIReg)
- return FALSE;
- if (ainfo->pair_storage [1] != ArgNone && ainfo->pair_storage [1] != ArgInIReg)
- return FALSE;
break;
case ArgOnStack:
if (!(ainfo->offset + (ainfo->arg_size / 8) <= DYN_CALL_STACK_ARGS))
case MONO_TYPE_VALUETYPE: {
switch (ainfo->storage) {
case ArgValuetypeInReg:
- if (ainfo->pair_storage [0] != ArgNone) {
- slot = param_reg_to_index [ainfo->pair_regs [0]];
- g_assert (ainfo->pair_storage [0] == ArgInIReg);
- p->regs [slot] = ((mgreg_t*)(arg))[0];
- }
- if (ainfo->pair_storage [1] != ArgNone) {
- slot = param_reg_to_index [ainfo->pair_regs [1]];
- g_assert (ainfo->pair_storage [1] == ArgInIReg);
- p->regs [slot] = ((mgreg_t*)(arg))[1];
+ for (i = 0; i < 2; ++i) {
+ switch (ainfo->pair_storage [i]) {
+ case ArgNone:
+ break;
+ case ArgInIReg:
+ slot = param_reg_to_index [ainfo->pair_regs [i]];
+ p->regs [slot] = ((mgreg_t*)(arg))[i];
+ break;
+ case ArgInDoubleSSEReg:
+ p->has_fp = 1;
+ p->fregs [ainfo->pair_regs [i]] = ((double*)(arg))[i];
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
}
break;
case ArgOnStack:
guint8 *ret = dargs->ret;
mgreg_t res = dargs->res;
MonoType *sig_ret = mini_get_underlying_type (sig->ret);
+ int i;
switch (sig_ret->type) {
case MONO_TYPE_VOID:
g_assert (ainfo->storage == ArgValuetypeInReg);
- if (ainfo->pair_storage [0] != ArgNone) {
- g_assert (ainfo->pair_storage [0] == ArgInIReg);
- ((mgreg_t*)ret)[0] = res;
+ for (i = 0; i < 2; ++i) {
+ switch (ainfo->pair_storage [0]) {
+ case ArgInIReg:
+ ((mgreg_t*)ret)[i] = res;
+ break;
+ case ArgInDoubleSSEReg:
+ ((double*)ret)[i] = dargs->fregs [i];
+ break;
+ case ArgNone:
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
}
-
- g_assert (ainfo->pair_storage [1] == ArgNone);
}
break;
default:
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: {
MonoMethod *inflated_method;
MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ WrapperInfo *winfo = NULL;
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
MonoJumpInfoGSharedVtCall *res;
mono_class_init (inflated_class);
- g_assert (!method->wrapper_type);
+ if (method->wrapper_type) {
+ winfo = mono_marshal_get_wrapper_info (method);
+
+ g_assert (winfo);
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ method = winfo->d.synchronized_inner.method;
+ }
if (inflated_class->byval_arg.type == MONO_TYPE_ARRAY ||
inflated_class->byval_arg.type == MONO_TYPE_SZARRAY) {
}
mono_class_init (inflated_method->klass);
g_assert (inflated_method->klass == inflated_class);
+
+ if (winfo) {
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ inflated_method = mono_marshal_get_synchronized_inner_wrapper (inflated_method);
+ }
+
res->method = inflated_method;
return res;
g_assert (method->is_inflated);
+ if (mono_llvm_only && (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
+ method = mono_marshal_get_synchronized_wrapper (method);
+
if (!virtual_) {
addr = mono_compile_method_checked (method, error);
return_val_if_nok (error, NULL);
LLVMValueRef
mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
- const char *Name, gboolean is_volatile, BarrierKind barrier)
+ const char *Name, gboolean is_volatile)
{
LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
+ return wrap(ins);
+}
+
+LLVMValueRef
+mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
+ const char *Name, gboolean is_volatile, int alignment, BarrierKind barrier)
+{
+ LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
+
+ ins->setAlignment (alignment);
switch (barrier) {
case LLVM_BARRIER_NONE:
break;
LLVMValueRef
mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
- const char *Name, gboolean is_volatile, BarrierKind barrier);
+ const char *Name, gboolean is_volatile);
LLVMValueRef
+mono_llvm_build_atomic_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
+ const char *Name, gboolean is_volatile, int alignment, BarrierKind barrier);
+
+LLVMValueRef
mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
const char *Name, gboolean is_volatile, int alignment);
}
static LLVMValueRef
-emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
+emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
{
const char *intrins_name;
LLVMValueRef args [16], res;
#if LLVM_API_VERSION > 100
if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
/* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
- LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
+ LLVMValueRef cmp;
+
+ cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
*builder_ref = ctx->builder;
use_intrinsics = FALSE;
* LLVM will generate invalid code when encountering a load from a
* NULL address.
*/
- res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
+ if (barrier != LLVM_BARRIER_NONE)
+ res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
+ else
+ res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
- /* Mark it with a custom metadata */
- /*
- if (is_faulting)
- set_metadata_flag (res, "mono.faulting.load");
- */
+ /* Mark it with a custom metadata */
+ /*
+ if (is_faulting)
+ set_metadata_flag (res, "mono.faulting.load");
+ */
- return res;
+ return res;
}
}
static LLVMValueRef
emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
{
- return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
+ return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
}
static void
-emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
+emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
{
const char *intrins_name;
LLVMValueRef args [16];
#if LLVM_API_VERSION > 100
if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
/* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
- LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
+ LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
*builder_ref = ctx->builder;
use_intrinsics = FALSE;
}
static void
-emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
+emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
{
- emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
+ emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
}
/*
if (!ctx->imt_rgctx_loc)
ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
- args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
+ args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
#else
args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
#endif
if (!ctx->imt_rgctx_loc)
ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
- args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
+ args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
#else
args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
#endif
if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM) || (ins->opcode == OP_LOADI4_MEM) || (ins->opcode == OP_LOADU4_MEM) || (ins->opcode == OP_LOADU1_MEM) || (ins->opcode == OP_LOADU2_MEM)) {
addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
+ base = addr;
} else {
/* _MEMBASE */
base = lhs;
addr = convert (ctx, addr, LLVMPointerType (t, 0));
- values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
+ values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
/*
case OP_STORER8_MEMBASE_REG:
case OP_STORE_MEMBASE_REG: {
int size = 8;
- LLVMValueRef index, addr;
+ LLVMValueRef index, addr, base;
LLVMTypeRef t;
gboolean sext = FALSE, zext = FALSE;
gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
+ base = values [ins->inst_destbasereg];
if (ins->inst_offset % size != 0) {
/* Unaligned store */
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
- addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
+ addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
} else {
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
- addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
+ addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
}
- emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
+ emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
break;
}
case OP_STOREI8_MEMBASE_IMM:
case OP_STORE_MEMBASE_IMM: {
int size = 8;
- LLVMValueRef index, addr;
+ LLVMValueRef index, addr, base;
LLVMTypeRef t;
gboolean sext = FALSE, zext = FALSE;
gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
+ base = values [ins->inst_destbasereg];
if (ins->inst_offset % size != 0) {
/* Unaligned store */
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
- addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
+ addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
} else {
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
- addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
+ addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
}
- emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
+ emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
break;
}
case OP_CHECK_THIS:
- emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
+ emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
break;
case OP_OUTARG_VTRETADDR:
break;
case OP_ATOMIC_LOAD_U8:
case OP_ATOMIC_LOAD_R4:
case OP_ATOMIC_LOAD_R8: {
- set_failure (ctx, "atomic mono.load intrinsic");
- break;
-#if 0
+#if LLVM_API_VERSION > 100
int size;
gboolean sext, zext;
LLVMTypeRef t;
addr = convert (ctx, addr, LLVMPointerType (t, 0));
- values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
+ values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
if (sext)
values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
else if (zext)
values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
break;
+#else
+ set_failure (ctx, "atomic mono.load intrinsic");
+ break;
#endif
}
case OP_ATOMIC_STORE_I1:
LLVMTypeRef t;
gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
- LLVMValueRef index, addr, value;
+ LLVMValueRef index, addr, value, base;
+#if LLVM_API_VERSION < 100
if (!cfg->llvm_only) {
set_failure (ctx, "atomic mono.store intrinsic");
break;
}
+#endif
if (!values [ins->inst_destbasereg]) {
set_failure (ctx, "inst_destbasereg");
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
+ base = values [ins->inst_destbasereg];
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
- addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
+ addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
value = convert (ctx, values [ins->sreg1], t);
- emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
+ emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
break;
}
case OP_RELAXED_NOP: {
* mono_threads_state_poll ();
* FIXME: Use a preserveall wrapper
*/
- val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
+ val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
poll_bb = gen_bb (ctx, "POLL_BB");
cont_bb = gen_bb (ctx, "CONT_BB");
names = g_new (char *, sig->param_count);
mono_method_get_param_names (cfg->method, (const char **) names);
+ /* Set parameter names/attributes */
for (i = 0; i < sig->param_count; ++i) {
LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
char *name;
g_free (name);
}
+ if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
+ continue;
+
values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
if (names [i] && names [i][0] != '\0')
return res;
}
+static LLVMValueRef
+llvm_array_from_bytes (guint8 *values, int nvalues)
+{
+ int i;
+ LLVMValueRef res, *vals;
+
+ vals = g_new0 (LLVMValueRef, nvalues);
+ for (i = 0; i < nvalues; ++i)
+ vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
+ res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
+ g_free (vals);
+ return res;
+}
/*
* mono_llvm_emit_aot_file_info:
*
info = &module->aot_info;
/* Create an LLVM type to represent MonoAotFileInfo */
- nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
+ nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
eltypes = g_new (LLVMTypeRef, nfields);
tindex = 0;
eltypes [tindex ++] = LLVMInt32Type ();
eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
for (i = 0; i < 4; ++i)
eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
+ eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
g_assert (tindex == nfields);
file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
+
+ fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
g_assert (tindex == nfields);
LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
LLVMValueRef lmethod;
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ continue;
+
lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
if (lmethod) {
for (l = callers; l; l = l->next) {
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.
else if (!strcmp (option, "gen-seq-points"))
debug_options.gen_sdb_seq_points = TRUE;
else if (!strcmp (option, "gen-compact-seq-points"))
- debug_options.gen_seq_points_compact_data = TRUE;
+ fprintf (stderr, "Mono Warning: option gen-compact-seq-points is deprecated.\n");
+ else if (!strcmp (option, "no-compact-seq-points"))
+ debug_options.no_seq_points_compact_data = TRUE;
else if (!strcmp (option, "single-imm-size"))
debug_options.single_imm_size = TRUE;
else if (!strcmp (option, "init-stacks"))
if (!mini_parse_debug_option (arg)) {
fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg);
- fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'gen-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n");
+ fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'no-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n");
exit (1);
}
}
*/
no_patch = TRUE;
}
-
+#if LLVM_API_VERSION > 100
+ /* LLVM code doesn't make direct calls */
+ if (ji && ji->from_llvm)
+ no_patch = TRUE;
+#endif
if (!no_patch && mono_method_same_domain (ji, target_ji))
mono_arch_patch_callsite ((guint8 *)ji->code_start, code, (guint8 *)addr);
}
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);
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;
#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))
guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
/* The offset where the trampolines begin on a trampoline page */
guint32 tramp_page_code_offsets [MONO_AOT_TRAMP_NUM];
+ /* GUID of aot compilation */
+ guint8 aotid[16];
} MonoAotFileInfo;
/* Number of symbols in the MonoAotFileInfo structure */
* Next sequence points and flags are required by the debugger agent.
*/
gboolean gen_sdb_seq_points;
- gboolean gen_seq_points_compact_data;
+ gboolean no_seq_points_compact_data;
/*
* Setting single_imm_size should guarantee that each time managed code is compiled
* the same instructions and registers are used, regardless of the size of used values.
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
}
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;
}
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,
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*
using System;
+using System.Linq;
class C
{
{
string fullTrace = ex.StackTrace;
string[] frames = fullTrace.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+
+ // Ignore metadata
+ frames = frames.Where (l => !l.StartsWith ("[")).ToArray ();
+
return frames.Length;
}
t.Join ();
for (int i = 0; i < 5; ++i) {
+ Console.WriteLine("-GC {0}/5-", i);
GC.Collect ();
GC.WaitForPendingFinalizers ();
}
parse.c \
parse.h \
checked-build.c \
- checked-build.h
+ checked-build.h \
+ w32handle.c \
+ w32handle.h
arch_sources =
MONO_TRACE_THREADPOOL = (1<<7),
MONO_TRACE_IO_THREADPOOL = (1<<8),
MONO_TRACE_IO_LAYER = (1<<9),
+ MONO_TRACE_W32HANDLE = (1<<10),
MONO_TRACE_ALL = MONO_TRACE_ASSEMBLY |
MONO_TRACE_TYPE |
MONO_TRACE_DLLIMPORT |
MONO_TRACE_SECURITY |
MONO_TRACE_THREADPOOL |
MONO_TRACE_IO_THREADPOOL |
- MONO_TRACE_IO_LAYER
+ MONO_TRACE_IO_LAYER |
+ MONO_TRACE_W32HANDLE
} MonoTraceMask;
extern GLogLevelFlags mono_internal_current_level;
if(level_stack == NULL)
mono_trace_init();
- if ((dest != NULL) && (strcmp("syslog", dest) != 0)) {
+ if ((dest == NULL) || (strcmp("syslog", dest) != 0)) {
logger.opener = mono_log_open_logfile;
logger.writer = mono_log_write_logfile;
logger.closer = mono_log_close_logfile;
const char *tok;
guint32 flags = 0;
- const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "io-layer", "all", NULL};
+ const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "io-layer", "w32handle", "all", NULL};
const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_SECURITY,
- MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_IO_LAYER, MONO_TRACE_ALL };
+ MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_IO_LAYER,
+ MONO_TRACE_W32HANDLE, MONO_TRACE_ALL };
if(!value)
return;
g_free (ptr);
}
+
+/**
+ * mono_set_allocator_vtable
+ *
+ * Make the runtime use the functions in @vtable for allocating memory.
+ * The provided functions must have the same semantics of their libc's equivalents.
+ *
+ * @return TRUE is the vtable was installed. FALSE if the version is incompatible.
+ */
+mono_bool
+mono_set_allocator_vtable (MonoAllocatorVTable* vtable)
+{
+ if (vtable->version != MONO_ALLOCATOR_VTABLE_VERSION)
+ return FALSE;
+ GMemVTable g_mem_vtable = { vtable->malloc, vtable->realloc, vtable->free, vtable->calloc};
+ g_mem_set_vtable (&g_mem_vtable);
+ return TRUE;
+}
#endif /* end of compiler-specific stuff */
+#include <stdlib.h>
+
#if defined(MONO_DLL_EXPORT)
#define MONO_API MONO_API_EXPORT
#elif defined(MONO_DLL_IMPORT)
MONO_API void mono_free (void *);
+#define MONO_ALLOCATOR_VTABLE_VERSION 1
+
+typedef struct {
+ int version;
+ void *(*malloc) (size_t size);
+ void *(*realloc) (void *mem, size_t count);
+ void (*free) (void *mem);
+ void *(*calloc) (size_t count, size_t size);
+} MonoAllocatorVTable;
+
+MONO_API mono_bool
+mono_set_allocator_vtable (MonoAllocatorVTable* vtable);
+
+
#define MONO_CONST_RETURN const
/*
--- /dev/null
+/*
+ * w32handle.c: Generic and internal operations on handles
+ *
+ * Author:
+ * Dick Porter (dick@ximian.com)
+ * Ludovic Henry (luhenry@microsoft.com)
+ *
+ * (C) 2002-2011 Novell, Inc.
+ * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+
+#if !defined(HOST_WIN32)
+
+#include <glib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#endif
+#include <sys/stat.h>
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+#include "w32handle.h"
+
+#include "atomic.h"
+#include "mono-logger-internals.h"
+#include "mono-os-mutex.h"
+#include "mono-proclib.h"
+#include "mono-threads.h"
+
+#undef DEBUG_REFS
+
+#define SLOT_MAX (1024 * 16)
+
+/* must be a power of 2 */
+#define HANDLE_PER_SLOT (256)
+
+typedef struct {
+ MonoW32HandleType type;
+ guint ref;
+ gboolean signalled;
+ mono_mutex_t signal_mutex;
+ mono_cond_t signal_cond;
+ gpointer specific;
+} MonoW32HandleBase;
+
+static MonoW32HandleCapability handle_caps [MONO_W32HANDLE_COUNT];
+static MonoW32HandleOps *handle_ops [MONO_W32HANDLE_COUNT];
+
+/*
+ * We can hold SLOT_MAX * HANDLE_PER_SLOT handles.
+ * If 4M handles are not enough... Oh, well... we will crash.
+ */
+#define SLOT_INDEX(x) (x / HANDLE_PER_SLOT)
+#define SLOT_OFFSET(x) (x % HANDLE_PER_SLOT)
+
+static MonoW32HandleBase *private_handles [SLOT_MAX];
+static guint32 private_handles_count = 0;
+static guint32 private_handles_slots_count = 0;
+
+guint32 mono_w32handle_fd_reserve;
+
+/*
+ * This is an internal handle which is used for handling waiting for multiple handles.
+ * Threads which wait for multiple handles wait on this one handle, and when a handle
+ * is signalled, this handle is signalled too.
+ */
+static mono_mutex_t global_signal_mutex;
+static mono_cond_t global_signal_cond;
+
+static mono_mutex_t scan_mutex;
+
+static gboolean shutting_down = FALSE;
+
+static gboolean
+type_is_fd (MonoW32HandleType type)
+{
+ switch (type) {
+ case MONO_W32HANDLE_FILE:
+ case MONO_W32HANDLE_CONSOLE:
+ case MONO_W32HANDLE_SOCKET:
+ case MONO_W32HANDLE_PIPE:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean
+mono_w32handle_lookup_data (gpointer handle, MonoW32HandleBase **handle_data)
+{
+ gsize index, offset;
+
+ g_assert (handle_data);
+
+ index = SLOT_INDEX ((gsize) handle);
+ if (index >= SLOT_MAX)
+ return FALSE;
+ if (!private_handles [index])
+ return FALSE;
+
+ offset = SLOT_OFFSET ((gsize) handle);
+ if (private_handles [index][offset].type == MONO_W32HANDLE_UNUSED)
+ return FALSE;
+
+ *handle_data = &private_handles [index][offset];
+ return TRUE;
+}
+
+MonoW32HandleType
+mono_w32handle_get_type (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data))
+ return MONO_W32HANDLE_UNUSED; /* An impossible type */
+
+ return handle_data->type;
+}
+
+void
+mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast)
+{
+ MonoW32HandleBase *handle_data;
+ 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; i<numhandles; i++) {
+ gpointer handle = handles[i];
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempting to lock %p", __func__, handle);
+
+ thr_ret = mono_w32handle_trylock_handle (handle);
+
+ if (thr_ret != 0) {
+ /* Bummer */
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempt failed for %p: %s", __func__,
+ handle, strerror (thr_ret));
+
+ while (i--) {
+ handle = handles[i];
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+ }
+
+ /* If iter ever reaches 100 the nanosleep will
+ * return EINVAL immediately, but we have a
+ * design flaw if that happens.
+ */
+ iter++;
+ if(iter==100) {
+ g_warning ("%s: iteration overflow!",
+ __func__);
+ iter=1;
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Backing off for %d ms", __func__,
+ iter*10);
+ spin (10 * iter);
+
+ goto again;
+ }
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Locked all handles", __func__);
+
+ count=0;
+ *lowest=numhandles;
+
+ for(i=0; i<numhandles; i++) {
+ gpointer handle = handles[i];
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Checking handle %p", __func__, handle);
+
+ if(((mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)==TRUE) &&
+ (mono_w32handle_ops_isowned (handle) == TRUE)) ||
+ (mono_w32handle_issignalled (handle))) {
+ count++;
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Handle %p signalled", __func__,
+ handle);
+ if(*lowest>i) {
+ *lowest=i;
+ }
+ }
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: %d event handles signalled", __func__, count);
+
+ if ((waitall == TRUE && count == numhandles) ||
+ (waitall == FALSE && count > 0)) {
+ ret=TRUE;
+ } else {
+ ret=FALSE;
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Returning %d", __func__, ret);
+
+ *retcount=count;
+
+ return(ret);
+}
+
+void mono_w32handle_unlock_handles (guint32 numhandles, gpointer *handles)
+{
+ guint32 i;
+ int thr_ret;
+
+ for(i=0; i<numhandles; i++) {
+ gpointer handle = handles[i];
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: unlocking handle %p", __func__, handle);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+ }
+}
+
+static int
+mono_w32handle_timedwait_signal_naked (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout, gboolean poll, gboolean *alerted)
+{
+ int res;
+
+ if (!poll) {
+ res = mono_os_cond_timedwait (cond, mutex, timeout);
+ } else {
+ /* This is needed when waiting for process handles */
+ if (!alerted) {
+ /*
+ * pthread_cond_(timed)wait() can return 0 even if the condition was not
+ * signalled. This happens at least on Darwin. We surface this, i.e., we
+ * get spurious wake-ups.
+ *
+ * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
+ */
+ res = mono_os_cond_timedwait (cond, mutex, timeout);
+ } else {
+ if (timeout < 100) {
+ /* Real timeout is less than 100ms time */
+ res = mono_os_cond_timedwait (cond, mutex, timeout);
+ } else {
+ res = mono_os_cond_timedwait (cond, mutex, 100);
+
+ /* Mask the fake timeout, this will cause
+ * another poll if the cond was not really signaled
+ */
+ if (res == ETIMEDOUT)
+ res = 0;
+ }
+ }
+ }
+
+ return res;
+}
+
+static void
+signal_global (gpointer unused)
+{
+ /* If we reach here, then interrupt token is set to the flag value, which
+ * means that the target thread is either
+ * - before the first CAS in timedwait, which means it won't enter the wait.
+ * - it is after the first CAS, so it is already waiting, or it will enter
+ * the wait, and it will be interrupted by the broadcast. */
+ mono_os_mutex_lock (&global_signal_mutex);
+ mono_os_cond_broadcast (&global_signal_cond);
+ mono_os_mutex_unlock (&global_signal_mutex);
+}
+
+int
+mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted)
+{
+ int res;
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for global", __func__);
+
+ if (alerted)
+ *alerted = FALSE;
+
+ if (alerted) {
+ mono_thread_info_install_interrupt (signal_global, NULL, alerted);
+ if (*alerted)
+ return 0;
+ }
+
+ res = mono_w32handle_timedwait_signal_naked (&global_signal_cond, &global_signal_mutex, timeout, poll, alerted);
+
+ if (alerted)
+ mono_thread_info_uninstall_interrupt (alerted);
+
+ return res;
+}
+
+static void
+signal_handle_and_unref (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ mono_cond_t *cond;
+ mono_mutex_t *mutex;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data))
+ g_error ("cannot signal unknown handle %p", handle);
+
+ /* If we reach here, then interrupt token is set to the flag value, which
+ * means that the target thread is either
+ * - before the first CAS in timedwait, which means it won't enter the wait.
+ * - it is after the first CAS, so it is already waiting, or it will enter
+ * the wait, and it will be interrupted by the broadcast. */
+ cond = &handle_data->signal_cond;
+ mutex = &handle_data->signal_mutex;
+
+ mono_os_mutex_lock (mutex);
+ mono_os_cond_broadcast (cond);
+ mono_os_mutex_unlock (mutex);
+
+ mono_w32handle_unref (handle);
+}
+
+int
+mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
+{
+ MonoW32HandleBase *handle_data;
+ int res;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data))
+ g_error ("cannot wait on unknown handle %p", handle);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for %p (type %s)", __func__, handle,
+ mono_w32handle_ops_typename (mono_w32handle_get_type (handle)));
+
+ if (alerted)
+ *alerted = FALSE;
+
+ if (alerted) {
+ mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
+ if (*alerted)
+ return 0;
+ mono_w32handle_ref (handle);
+ }
+
+ res = mono_w32handle_timedwait_signal_naked (&handle_data->signal_cond, &handle_data->signal_mutex, timeout, poll, alerted);
+
+ if (alerted) {
+ mono_thread_info_uninstall_interrupt (alerted);
+ if (!*alerted) {
+ /* if it is alerted, then the handle is unref in the interrupt callback */
+ mono_w32handle_unref (handle);
+ }
+ }
+
+ return res;
+}
+
+void mono_w32handle_dump (void)
+{
+ MonoW32HandleBase *handle_data;
+ guint32 i, k;
+ 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) */
--- /dev/null
+
+#ifndef _MONO_UTILS_W32HANDLE_H_
+#define _MONO_UTILS_W32HANDLE_H_
+
+#include <config.h>
+
+#if !defined(HOST_WIN32)
+
+#include <glib.h>
+
+#define INVALID_HANDLE_VALUE (gpointer)-1
+
+typedef enum {
+ MONO_W32HANDLE_UNUSED = 0,
+ MONO_W32HANDLE_FILE,
+ MONO_W32HANDLE_CONSOLE,
+ MONO_W32HANDLE_THREAD,
+ MONO_W32HANDLE_SEM,
+ MONO_W32HANDLE_MUTEX,
+ MONO_W32HANDLE_EVENT,
+ MONO_W32HANDLE_SOCKET,
+ MONO_W32HANDLE_FIND,
+ MONO_W32HANDLE_PROCESS,
+ MONO_W32HANDLE_PIPE,
+ MONO_W32HANDLE_NAMEDMUTEX,
+ MONO_W32HANDLE_NAMEDSEM,
+ MONO_W32HANDLE_NAMEDEVENT,
+ MONO_W32HANDLE_COUNT
+} MonoW32HandleType;
+
+typedef struct
+{
+ void (*close)(gpointer handle, gpointer data);
+
+ /* SignalObjectAndWait */
+ void (*signal)(gpointer signal);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects,
+ * with the handle locked (shared handles aren't locked.)
+ * Returns TRUE if ownership was established, false otherwise.
+ */
+ gboolean (*own_handle)(gpointer handle);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
+ * handle in question is "ownable" (ie mutexes), to see if the current
+ * thread already owns this handle
+ */
+ gboolean (*is_owned)(gpointer handle);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects,
+ * if the handle in question needs a special wait function
+ * instead of using the normal handle signal mechanism.
+ * Returns the WaitForSingleObject return code.
+ */
+ guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean alertable);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects,
+ * if the handle in question needs some preprocessing before the
+ * signal wait.
+ */
+ void (*prewait)(gpointer handle);
+
+ /* Called when dumping the handles */
+ void (*details)(gpointer data);
+
+ /* Called to get the name of the handle type */
+ const gchar* (*typename) (void);
+
+ /* Called to get the size of the handle type */
+ gsize (*typesize) (void);
+} MonoW32HandleOps;
+
+typedef enum {
+ MONO_W32HANDLE_CAP_WAIT = 0x01,
+ MONO_W32HANDLE_CAP_SIGNAL = 0x02,
+ MONO_W32HANDLE_CAP_OWN = 0x04,
+ MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
+} MonoW32HandleCapability;
+
+extern guint32 mono_w32handle_fd_reserve;
+
+void
+mono_w32handle_init (void);
+
+void
+mono_w32handle_cleanup (void);
+
+void
+mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops);
+
+gpointer
+mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific);
+
+gpointer
+mono_w32handle_new_fd (MonoW32HandleType type, int fd, gpointer handle_specific);
+
+MonoW32HandleType
+mono_w32handle_get_type (gpointer handle);
+
+gboolean
+mono_w32handle_lookup (gpointer handle, MonoW32HandleType type, gpointer *handle_specific);
+
+gpointer
+mono_w32handle_search (MonoW32HandleType type, gboolean (*check)(gpointer, gpointer), gpointer user_data, gpointer *handle_specific, gboolean search_shared);
+
+void
+mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data);
+
+void
+mono_w32handle_dump (void);
+
+void
+mono_w32handle_ref (gpointer handle);
+
+void
+mono_w32handle_unref (gpointer handle);
+
+void
+mono_w32handle_register_capabilities (MonoW32HandleType type, MonoW32HandleCapability caps);
+
+gboolean
+mono_w32handle_test_capabilities (gpointer handle, MonoW32HandleCapability caps);
+
+void
+mono_w32handle_ops_close (gpointer handle, gpointer data);
+
+void
+mono_w32handle_ops_signal (gpointer handle);
+
+gboolean
+mono_w32handle_ops_own (gpointer handle);
+
+gboolean
+mono_w32handle_ops_isowned (gpointer handle);
+
+guint32
+mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean alertable);
+
+void
+mono_w32handle_ops_prewait (gpointer handle);
+
+void
+mono_w32handle_ops_details (MonoW32HandleType type, gpointer data);
+
+const gchar*
+mono_w32handle_ops_typename (MonoW32HandleType type);
+
+gsize
+mono_w32handle_ops_typesize (MonoW32HandleType type);
+
+gboolean
+mono_w32handle_count_signalled_handles (guint32 numhandles, gpointer *handles, gboolean waitall, guint32 *retcount, guint32 *lowest);
+
+void
+mono_w32handle_unlock_handles (guint32 numhandles, gpointer *handles);
+
+int
+mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted);
+
+int
+mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted);
+
+void
+mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
+
+gboolean
+mono_w32handle_issignalled (gpointer handle);
+
+int
+mono_w32handle_lock_handle (gpointer handle);
+
+int
+mono_w32handle_trylock_handle (gpointer handle);
+
+int
+mono_w32handle_unlock_handle (gpointer handle);
+
+int
+mono_w32handle_lock_signal_mutex (void);
+
+int
+mono_w32handle_unlock_signal_mutex (void);
+
+#endif /* !defined(HOST_WIN32) */
+
+#endif /* _MONO_UTILS_W32HANDLE_H_ */
open (OUT, ">$outfile") || die "Cannot open '$outfile': $!\n";
print OUT "; file generated by create-windef.pl\n";
-#print OUT "LIBRARY $dllname\nEXPORTS\n";
+print OUT "EXPORTS\n";
print OUT join ("\n", @symbols);
print OUT "\n";
-<?xml version="1.0" encoding="utf-8"?>\r
+<?xml version="1.0" encoding="utf-8"?>\r
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
<ItemGroup Label="ProjectConfigurations">\r
<ProjectConfiguration Include="Debug|Win32">\r
<ClCompile Include="..\eglib\src\gtimer-win32.c" />\r
<ClCompile Include="..\eglib\src\gunicode.c" />\r
<ClCompile Include="..\eglib\src\gutf8.c" />\r
- <ClCompile Include="..\eglib\src\vasprintf.c" />\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\eglib\src\glib.h" />\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<ImportGroup Label="ExtensionTargets">\r
</ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
mono_get_uintptr_class
mono_get_void_class
mono_guid_to_string
+mono_guid_to_string_minimal
mono_image_add_to_name_cache
mono_image_addref
mono_image_close
mono_lock_free_queue_node_init
mono_lock_free_queue_node_unpoison
mono_locks_dump
+mono_log_close_logfile
+mono_log_close_syslog
+mono_log_open_logfile
+mono_log_open_syslog
+mono_log_write_logfile
+mono_log_write_syslog
mono_lookup_icall_symbol
mono_lookup_internal_call
mono_lookup_pinvoke_call
mono_security_core_clr_set_options
mono_security_enable_core_clr
mono_security_set_core_clr_platform_callback
+mono_set_allocator_vtable
mono_set_assemblies_path
mono_set_break_policy
mono_set_config_dir
mono_threads_attach_tools_thread
mono_threads_detach_coop
mono_threads_enter_gc_safe_region
+mono_threads_enter_gc_safe_region_unbalanced
mono_threads_enter_gc_unsafe_region
+mono_threads_enter_gc_unsafe_region_unbalanced
mono_threads_exit_gc_safe_region
+mono_threads_exit_gc_safe_region_unbalanced
mono_threads_exit_gc_unsafe_region
+mono_threads_exit_gc_unsafe_region_unbalanced
mono_threads_get_default_stacksize
mono_threads_request_thread_dump
mono_threads_set_default_stacksize
mono_trace_set_level_string
mono_trace_set_log_handler
+mono_trace_set_logdest_string
+mono_trace_set_logheader_string
mono_trace_set_mask_string
mono_trace_set_print_handler
mono_trace_set_printerr_handler
mono_get_uintptr_class
mono_get_void_class
mono_guid_to_string
+mono_guid_to_string_minimal
mono_image_add_to_name_cache
mono_image_addref
mono_image_close
mono_lock_free_queue_node_init
mono_lock_free_queue_node_unpoison
mono_locks_dump
+mono_log_close_logfile
+mono_log_close_syslog
+mono_log_open_logfile
+mono_log_open_syslog
+mono_log_write_logfile
+mono_log_write_syslog
mono_lookup_icall_symbol
mono_lookup_internal_call
mono_lookup_pinvoke_call
mono_security_core_clr_set_options
mono_security_enable_core_clr
mono_security_set_core_clr_platform_callback
+mono_set_allocator_vtable
mono_set_assemblies_path
mono_set_break_policy
mono_set_config_dir
mono_threads_attach_tools_thread
mono_threads_detach_coop
mono_threads_enter_gc_safe_region
+mono_threads_enter_gc_safe_region_unbalanced
mono_threads_enter_gc_unsafe_region
+mono_threads_enter_gc_unsafe_region_unbalanced
mono_threads_exit_gc_safe_region
+mono_threads_exit_gc_safe_region_unbalanced
mono_threads_exit_gc_unsafe_region
+mono_threads_exit_gc_unsafe_region_unbalanced
mono_threads_get_default_stacksize
mono_threads_request_thread_dump
mono_threads_set_default_stacksize
mono_trace_set_level_string
mono_trace_set_log_handler
+mono_trace_set_logdest_string
+mono_trace_set_logheader_string
mono_trace_set_mask_string
mono_trace_set_print_handler
mono_trace_set_printerr_handler
#include <mono/jit/jit.h>
#include <mono/metadata/environment.h>
+#include <mono/utils/mono-publib.h>
#include <stdlib.h>
/*
mono_jit_exec (domain, assembly, argc, argv);
}
+static int malloc_count = 0;
+
+static void* custom_malloc(size_t bytes)
+{
+ ++malloc_count;
+ return malloc(bytes);
+}
int
main(int argc, char* argv[]) {
}
file = argv [1];
+ MonoAllocatorVTable mem_vtable = {custom_malloc};
+ mono_set_allocator_vtable (&mem_vtable);
+
/*
* Load the default Mono configuration file, this is needed
* if you are planning on using the dllmaps defined on the
retval = mono_environment_exitcode_get ();
mono_jit_cleanup (domain);
+
+ fprintf (stdout, "custom malloc calls = %d\n", malloc_count);
+
return retval;
}