#include <mono/metadata/object.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/threads-types.h>
-#include <mono/metadata/threadpool.h>
#include <mono/metadata/threadpool-ms.h>
#include <mono/metadata/threadpool-ms-io.h>
#include <mono/metadata/monitor.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/locales.h>
#include <mono/metadata/filewatcher.h>
-#include <mono/metadata/char-conversions.h>
#include <mono/metadata/security.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/cil-coff.h>
#include <mono/metadata/file-mmap.h>
#include <mono/metadata/seq-points-data.h>
#include <mono/io-layer/io-layer.h>
-#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-proclib.h>
#include <shlobj.h>
#endif
#include "decimal-ms.h"
+#include "number-ms.h"
extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
mono_raise_exception (mono_class_get_exception_for_failure (klass));
}
-/*
- * We expect a pointer to a char, not a string
- */
-ICALL_EXPORT gboolean
-mono_double_ParseImpl (char *ptr, double *result)
-{
- gchar *endptr = NULL;
- *result = 0.0;
-
- if (*ptr){
- /* mono_strtod () is not thread-safe */
- mono_mutex_lock (&mono_strtod_mutex);
- *result = mono_strtod (ptr, &endptr);
- mono_mutex_unlock (&mono_strtod_mutex);
- }
-
- if (!*ptr || (endptr && *endptr))
- return FALSE;
-
- return TRUE;
-}
-
ICALL_EXPORT MonoObject *
ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
{
mono_image_register_token (mb->dynamic_image, token, obj);
}
+ICALL_EXPORT MonoObject*
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+{
+ gpointer obj;
+
+ mono_loader_lock ();
+ obj = mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
+ mono_loader_unlock ();
+
+ return obj;
+}
+
static gboolean
get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
{
mono_metadata_free_type (inflated);
}
+static guint
+get_interfaces_hash (gconstpointer v1)
+{
+ MonoClass *k = (MonoClass*)v1;
+
+ return k->type_token;
+}
+
ICALL_EXPORT MonoArray*
ves_icall_Type_GetInterfaces (MonoReflectionType* type)
{
FillIfaceArrayData data = { 0 };
int len;
- GHashTable *iface_hash = g_hash_table_new (NULL, NULL);
+ GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
if (class->generic_class && class->generic_class->context.class_inst->is_open) {
data.context = mono_class_get_context (class);
return class->rank;
}
+static MonoArray*
+create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count)
+{
+ MonoArray *res;
+ res = mono_array_new (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count);
+ return res;
+}
+
ICALL_EXPORT MonoArray*
-ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
+ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
{
MonoArray *res;
MonoClass *klass, *pklass;
MonoDomain *domain = mono_object_domain (type);
- MonoVTable *array_vtable = mono_class_vtable_full (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1), TRUE);
int i;
klass = mono_class_from_mono_type (type->type);
if (klass->generic_container) {
MonoGenericContainer *container = klass->generic_container;
- res = mono_array_new_specific (array_vtable, container->type_argc);
+ res = create_type_array (domain, runtimeTypeArray, container->type_argc);
for (i = 0; i < container->type_argc; ++i) {
pklass = mono_class_from_generic_parameter (mono_generic_container_get_param (container, i), klass->image, FALSE);
mono_array_setref (res, i, mono_type_get_object (domain, &pklass->byval_arg));
}
} else if (klass->generic_class) {
MonoGenericInst *inst = klass->generic_class->context.class_inst;
- res = mono_array_new_specific (array_vtable, inst->type_argc);
+ res = create_type_array (domain, runtimeTypeArray, inst->type_argc);
for (i = 0; i < inst->type_argc; ++i)
mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
} else {
- res = mono_array_new_specific (array_vtable, 0);
+ res = NULL;
}
return res;
}
return NULL;
}
-
-
ICALL_EXPORT MonoReflectionMethod *
ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *ref_type)
{
return mono_method_get_object (mono_object_domain (ref_type), method, method->klass);
}
-ICALL_EXPORT MonoReflectionDllImportAttribute*
-ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
+ICALL_EXPORT MonoBoolean
+ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
+{
+ mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
+ return FALSE;
+}
+
+ICALL_EXPORT MonoBoolean
+ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
+{
+ mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
+ return FALSE;
+}
+
+ICALL_EXPORT void
+ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
{
- static MonoClass *DllImportAttributeClass = NULL;
MonoDomain *domain = mono_domain_get ();
- MonoReflectionDllImportAttribute *attr;
- MonoImage *image = method->klass->image;
- MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
+ MonoImage *image = method->method->klass->image;
+ MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
MonoTableInfo *tables = image->tables;
MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
guint32 scope_token;
const char *import = NULL;
const char *scope = NULL;
- guint32 flags;
-
- if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
- return NULL;
- if (!DllImportAttributeClass) {
- DllImportAttributeClass =
- mono_class_from_name (mono_defaults.corlib,
- "System.Runtime.InteropServices", "DllImportAttribute");
- g_assert (DllImportAttributeClass);
- }
-
- if (image_is_dynamic (method->klass->image)) {
+ if (image_is_dynamic (image)) {
MonoReflectionMethodAux *method_aux =
- g_hash_table_lookup (
- ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
if (method_aux) {
import = method_aux->dllentry;
scope = method_aux->dll;
if (!import || !scope) {
mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
- return NULL;
+ return;
}
}
else {
scope = mono_metadata_string_heap (image, scope_token);
}
}
- flags = piinfo->piflags;
- attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
-
- MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
- MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
- attr->call_conv = (flags & 0x700) >> 8;
- attr->charset = ((flags & 0x6) >> 1) + 1;
- if (attr->charset == 1)
- attr->charset = 2;
- attr->exact_spelling = (flags & 0x1) != 0;
- attr->set_last_error = (flags & 0x40) != 0;
- attr->best_fit_mapping = (flags & 0x30) == 0x10;
- attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
- attr->preserve_sig = FALSE;
-
- return attr;
+ *flags = piinfo->piflags;
+ *entry_point = mono_string_new (domain, import);
+ *dll_name = mono_string_new (domain, scope);
}
ICALL_EXPORT MonoReflectionMethod *
if (m->klass->rank == pcount) {
/* Only lengths provided. */
- lower_bounds = NULL;
+ return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, NULL);
} else {
g_assert (pcount == (m->klass->rank * 2));
- /* lower bounds are first. */
- lower_bounds = (intptr_t*)lengths;
- lengths += m->klass->rank;
- }
+ /* The arguments are lower-bound-length pairs */
+ lower_bounds = g_alloca (sizeof (intptr_t) * pcount);
+
+ for (i = 0; i < pcount / 2; ++i) {
+ lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
+ lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
+ }
- return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
+ return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
+ }
}
return mono_runtime_invoke_array (m, obj, params, NULL);
}
if (type->type == MONO_TYPE_CLASS) {
MonoClass *klass = mono_type_get_class (type);
- if (mono_security_enabled () && !klass->exception_type)
- /* Some security problems are detected during generic vtable construction */
- mono_class_setup_vtable (klass);
-
/* need to report exceptions ? */
if (throwOnError && klass->exception_type) {
/* report SecurityException (or others) that occured when loading the assembly */
mono_loader_clear_error ();
mono_set_pending_exception (exc);
return NULL;
- } else if (mono_security_enabled () && klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
- return NULL;
}
}
if (!exportedOnly || mono_module_type_is_visible (tdef, image, i + 1)) {
MonoError error;
klass = mono_class_get_checked (image, (i + 1) | MONO_TOKEN_TYPE_DEF, &error);
- g_assert (!mono_loader_get_last_error ()); /* Plug any leaks */
+ mono_loader_assert_no_error (); /* Plug any leaks */
if (klass) {
mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
return delegate;
}
-ICALL_EXPORT void
-ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
-{
- /* Reset the invoke impl to the default one */
- this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
-}
-
-/*
- * Magic number to convert a time which is relative to
- * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
- */
-#define EPOCH_ADJUST ((guint64)62135596800LL)
-
-/*
- * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
- */
-#define FILETIME_ADJUST ((guint64)504911232000000000LL)
-
-#ifdef HOST_WIN32
-/* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
-static void
-convert_to_absolute_date(SYSTEMTIME *date)
-{
-#define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
- static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- /* from the calendar FAQ */
- int a = (14 - date->wMonth) / 12;
- int y = date->wYear - a;
- int m = date->wMonth + 12 * a - 2;
- int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
-
- /* d is now the day of the week for the first of the month (0 == Sunday) */
-
- int day_of_week = date->wDayOfWeek;
-
- /* set day_in_month to the first day in the month which falls on day_of_week */
- int day_in_month = 1 + (day_of_week - d);
- if (day_in_month <= 0)
- day_in_month += 7;
-
- /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
- date->wDay = day_in_month + (date->wDay - 1) * 7;
- if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
- date->wDay -= 7;
-}
-#endif
-
-#ifndef HOST_WIN32
-/*
- * Return's the offset from GMT of a local time.
- *
- * tm is a local time
- * t is the same local time as seconds.
- */
-static int
-gmt_offset(struct tm *tm, time_t t)
-{
-#if defined (HAVE_TM_GMTOFF)
- return tm->tm_gmtoff;
-#else
- struct tm g;
- time_t t2;
- g = *gmtime(&t);
- g.tm_isdst = tm->tm_isdst;
- t2 = mktime(&g);
- return (int)difftime(t, t2);
-#endif
-}
-#endif
-/*
- * This is heavily based on zdump.c from glibc 2.2.
- *
- * * data[0]: start of daylight saving time (in DateTime ticks).
- * * data[1]: end of daylight saving time (in DateTime ticks).
- * * data[2]: utcoffset (in TimeSpan ticks).
- * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
- * * name[0]: name of this timezone when not daylight saving.
- * * name[1]: name of this timezone when daylight saving.
- *
- * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
- * the class library allows years between 1 and 9999.
- *
- * Returns true on success and zero on failure.
- */
-ICALL_EXPORT guint32
-ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
+ICALL_EXPORT MonoMulticastDelegate *
+ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
{
-#ifndef HOST_WIN32
- MonoDomain *domain = mono_domain_get ();
- struct tm start, tt;
- time_t t;
-
- long int gmtoff, gmtoff_after, gmtoff_st, gmtoff_ds;
- int day, transitioned;
- char tzone [64];
-
- gmtoff_st = gmtoff_ds = transitioned = 0;
-
- MONO_CHECK_ARG_NULL (data, 0);
- MONO_CHECK_ARG_NULL (names, 0);
-
- mono_gc_wbarrier_generic_store (data, (MonoObject*) mono_array_new (domain, mono_defaults.int64_class, 4));
- mono_gc_wbarrier_generic_store (names, (MonoObject*) mono_array_new (domain, mono_defaults.string_class, 2));
-
- /*
- * no info is better than crashing: we'll need our own tz data
- * to make this work properly, anyway. The range is probably
- * reduced to 1970 .. 2037 because that is what mktime is
- * guaranteed to support (we get into an infinite loop
- * otherwise).
- */
-
- memset (&start, 0, sizeof (start));
-
- start.tm_mday = 1;
- start.tm_year = year-1900;
-
- t = mktime (&start);
-
- if ((year < 1970) || (year > 2037) || (t == -1)) {
- t = time (NULL);
- tt = *localtime (&t);
- strftime (tzone, sizeof (tzone), "%Z", &tt);
- mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
- mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
- return 1;
- }
-
- gmtoff = gmt_offset (&start, t);
-
- /* For each day of the year, calculate the tm_gmtoff. */
- for (day = 0; day < 365 && transitioned < 2; day++) {
-
- t += 3600*24;
- tt = *localtime (&t);
+ MonoMulticastDelegate *ret;
- gmtoff_after = gmt_offset(&tt, t);
+ g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
- /* Daylight saving starts or ends here. */
- if (gmtoff_after != gmtoff) {
- struct tm tt1;
- time_t t1;
+ ret = (MonoMulticastDelegate*) mono_object_new (mono_object_domain (delegate), mono_object_class (delegate));
+ ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
- /* Try to find the exact hour when daylight saving starts/ends. */
- t1 = t;
- do {
- t1 -= 3600;
- tt1 = *localtime (&t1);
- } while (gmt_offset (&tt1, t1) != gmtoff);
-
- /* Try to find the exact minute when daylight saving starts/ends. */
- do {
- t1 += 60;
- tt1 = *localtime (&t1);
- } while (gmt_offset (&tt1, t1) == gmtoff);
- t1+=gmtoff;
- strftime (tzone, sizeof (tzone), "%Z", &tt);
-
- /* Write data, if we're already in daylight saving, we're done. */
- if (tt.tm_isdst) {
- mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
- mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
- if (gmtoff_ds == 0) {
- gmtoff_st = gmtoff;
- gmtoff_ds = gmtoff_after;
- }
- transitioned++;
- } else {
- mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
- mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
- if (gmtoff_ds == 0) {
- gmtoff_st = gmtoff_after;
- gmtoff_ds = gmtoff;
- }
- transitioned++;
- }
-
- /* This is only set once when we enter daylight saving. */
- if (tt1.tm_isdst) {
- mono_array_set ((*data), gint64, 2, (gint64)gmtoff_st * 10000000L);
- mono_array_set ((*data), gint64, 3, (gint64)(gmtoff_ds - gmtoff_st) * 10000000L);
- }
- gmtoff = gmt_offset (&tt, t);
- }
- }
-
- if (transitioned < 2) {
- strftime (tzone, sizeof (tzone), "%Z", &tt);
- mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
- mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
- mono_array_set ((*data), gint64, 0, 0);
- mono_array_set ((*data), gint64, 1, 0);
- mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
- mono_array_set ((*data), gint64, 3, 0);
- }
-
- return 1;
-#else
- MonoDomain *domain = mono_domain_get ();
- TIME_ZONE_INFORMATION tz_info;
- FILETIME ft;
- int i;
- int err, tz_id;
-
- tz_id = GetTimeZoneInformation (&tz_info);
- if (tz_id == TIME_ZONE_ID_INVALID)
- return 0;
-
- MONO_CHECK_ARG_NULL (data, 0);
- MONO_CHECK_ARG_NULL (names, 0);
-
- mono_gc_wbarrier_generic_store (data, mono_array_new (domain, mono_defaults.int64_class, 4));
- mono_gc_wbarrier_generic_store (names, mono_array_new (domain, mono_defaults.string_class, 2));
-
- for (i = 0; i < 32; ++i)
- if (!tz_info.DaylightName [i])
- break;
- mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
- for (i = 0; i < 32; ++i)
- if (!tz_info.StandardName [i])
- break;
- mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
-
- if ((year <= 1601) || (year > 30827)) {
- /*
- * According to MSDN, the MS time functions can't handle dates outside
- * this interval.
- */
- return 1;
- }
-
- /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
- if (tz_id != TIME_ZONE_ID_UNKNOWN) {
- tz_info.StandardDate.wYear = year;
- convert_to_absolute_date(&tz_info.StandardDate);
- err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
- //g_assert(err);
- if (err == 0)
- return 0;
-
- mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
- tz_info.DaylightDate.wYear = year;
- convert_to_absolute_date(&tz_info.DaylightDate);
- err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
- //g_assert(err);
- if (err == 0)
- return 0;
-
- mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
- }
- mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
- mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
-
- return 1;
-#endif
+ return ret;
}
/* System.Buffer */
#endif
}
+ICALL_EXPORT gint32
+ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
+{
+ return 9;
+}
+
ICALL_EXPORT void
ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
MonoReflectionMethod *method,
MonoDomain *domain;
MonoString *file;
gchar *config_file_name, *config_file_path;
- gsize len;
+ gsize len, config_file_path_length, config_ext_length;
gchar *module;
domain = mono_domain_get ();
file = domain->setup->configuration_file;
- if (!file)
+ if (!file || file->length == 0)
return NULL;
// Retrieve config file and remove the extension
config_file_path = mono_portability_find_file (config_file_name, TRUE);
if (!config_file_path)
config_file_path = config_file_name;
- len = strlen (config_file_path) - strlen (".config");
+
+ config_file_path_length = strlen (config_file_path);
+ config_ext_length = strlen (".config");
+ if (config_file_path_length <= config_ext_length)
+ return NULL;
+
+ len = config_file_path_length - config_ext_length;
module = g_malloc0 (len + 1);
memcpy (module, config_file_path, len);
// Get the config file from the module name
MonoTypedRef res;
MonoReflectionField *f;
MonoClass *klass;
- MonoType *ftype;
- guint8 *p;
+ MonoType *ftype = NULL;
+ guint8 *p = NULL;
int i;
memset (&res, 0, sizeof (res));
*decHexDigits = Formatter_DecHexDigits;
}
-/* These parameters are "readonly" in corlib/System/Globalization/TextInfo.cs */
-ICALL_EXPORT void
-ves_icall_System_Globalization_TextInfo_GetDataTablePointersLite (
- guint16 const **to_lower_data_low,
- guint16 const **to_lower_data_high,
- guint16 const **to_upper_data_low,
- guint16 const **to_upper_data_high)
-{
- *to_lower_data_low = ToLowerDataLow;
- *to_lower_data_high = ToLowerDataHigh;
- *to_upper_data_low = ToUpperDataLow;
- *to_upper_data_high = ToUpperDataHigh;
-}
-
/*
* We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
* and avoid useless allocations.
guint32 il_offset;
char *path_str = mono_string_to_utf8 (path);
- if (!seq_point_data_get_il_offset (path_str, method_token, method_index, native_offset, &il_offset))
+ if (!mono_seq_point_data_get_il_offset (path_str, method_token, method_index, native_offset, &il_offset))
il_offset = -1;
g_free (path_str);