mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error);
-#define ldstr_lock() EnterCriticalSection (&ldstr_section)
-#define ldstr_unlock() LeaveCriticalSection (&ldstr_section)
-static CRITICAL_SECTION ldstr_section;
+#define ldstr_lock() mono_mutex_lock (&ldstr_section)
+#define ldstr_unlock() mono_mutex_unlock (&ldstr_section)
+static mono_mutex_t ldstr_section;
static gboolean profile_allocs = TRUE;
guint32 initializing_tid;
guint32 waiting_count;
gboolean done;
- CRITICAL_SECTION initialization_section;
+ mono_mutex_t initialization_section;
} TypeInitializationLock;
/* for locking access to type_initialization_hash and blocked_thread_hash */
-#define mono_type_initialization_lock() EnterCriticalSection (&type_initialization_section)
-#define mono_type_initialization_unlock() LeaveCriticalSection (&type_initialization_section)
-static CRITICAL_SECTION type_initialization_section;
+#define mono_type_initialization_lock() mono_mutex_lock (&type_initialization_section)
+#define mono_type_initialization_unlock() mono_mutex_unlock (&type_initialization_section)
+static mono_mutex_t type_initialization_section;
/* from vtable to lock */
static GHashTable *type_initialization_hash;
void
mono_type_initialization_init (void)
{
- InitializeCriticalSection (&type_initialization_section);
+ mono_mutex_init_recursive (&type_initialization_section);
type_initialization_hash = g_hash_table_new (NULL, NULL);
blocked_thread_hash = g_hash_table_new (NULL, NULL);
- InitializeCriticalSection (&ldstr_section);
+ mono_mutex_init_recursive (&ldstr_section);
}
void
/* This is causing race conditions with
* mono_release_type_locks
*/
- DeleteCriticalSection (&type_initialization_section);
+ mono_mutex_destroy (&type_initialization_section);
g_hash_table_destroy (type_initialization_hash);
type_initialization_hash = NULL;
#endif
- DeleteCriticalSection (&ldstr_section);
+ mono_mutex_destroy (&ldstr_section);
g_hash_table_destroy (blocked_thread_hash);
blocked_thread_hash = NULL;
}
}
lock = g_malloc (sizeof(TypeInitializationLock));
- InitializeCriticalSection (&lock->initialization_section);
+ mono_mutex_init_recursive (&lock->initialization_section);
lock->initializing_tid = tid;
lock->waiting_count = 1;
lock->done = FALSE;
/* grab the vtable lock while this thread still owns type_initialization_section */
- EnterCriticalSection (&lock->initialization_section);
+ mono_mutex_lock (&lock->initialization_section);
g_hash_table_insert (type_initialization_hash, vtable, lock);
do_initialization = 1;
} else {
if (last_domain)
mono_domain_set (last_domain, TRUE);
lock->done = TRUE;
- LeaveCriticalSection (&lock->initialization_section);
+ mono_mutex_unlock (&lock->initialization_section);
} else {
/* this just blocks until the initializing thread is done */
- EnterCriticalSection (&lock->initialization_section);
- LeaveCriticalSection (&lock->initialization_section);
+ mono_mutex_lock (&lock->initialization_section);
+ mono_mutex_unlock (&lock->initialization_section);
}
mono_type_initialization_lock ();
g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
--lock->waiting_count;
if (lock->waiting_count == 0) {
- DeleteCriticalSection (&lock->initialization_section);
+ mono_mutex_destroy (&lock->initialization_section);
g_hash_table_remove (type_initialization_hash, vtable);
g_free (lock);
}
* and get_type_init_exception_for_class () needs to be aware of this.
*/
vtable->init_failed = 1;
- LeaveCriticalSection (&lock->initialization_section);
+ mono_mutex_unlock (&lock->initialization_section);
--lock->waiting_count;
if (lock->waiting_count == 0) {
- DeleteCriticalSection (&lock->initialization_section);
+ mono_mutex_destroy (&lock->initialization_section);
g_free (lock);
return TRUE;
}
if (mono_class_has_variant_generic_params (iface))
has_variant_iface = TRUE;
+ mono_class_setup_methods (iface);
vt_slot = interface_offset;
for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
MonoMethod *method;
int method_slot_in_interface;
for (method_slot_in_interface = 0; method_slot_in_interface < iface->method.count; method_slot_in_interface++) {
MonoMethod *method = mono_class_get_method_by_index (iface, method_slot_in_interface);
+
+ if (method->is_generic)
+ has_generic_virtual = TRUE;
add_imt_builder_entry (imt_builder, method, &imt_collisions_bitmap, interface_offset + method_slot_in_interface, slot_num);
}
interface_offset += iface->method.count;
bitmap = default_bitmap;
} else if (mono_type_is_struct (field->type)) {
fclass = mono_class_from_mono_type (field->type);
- bitmap = compute_class_bitmap (fclass, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, FALSE);
+ bitmap = compute_class_bitmap (fclass, default_bitmap, sizeof (default_bitmap) * 8, - (int)(sizeof (MonoObject) / sizeof (gpointer)), &max_set, FALSE);
numbits = max_set + 1;
} else {
default_bitmap [0] = 0;
MonoClass *class = mono_class_from_mono_type (type);
int size = mono_class_value_size (class, NULL);
if (value == NULL)
- mono_gc_bzero (dest, size);
+ mono_gc_bzero_atomic (dest, size);
else
mono_gc_wbarrier_value_copy (dest, value, 1, class);
}
void
mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
{
- return mono_field_static_get_value_for_thread (mono_thread_internal_current (), vt, field, value);
+ mono_field_static_get_value_for_thread (mono_thread_internal_current (), vt, field, value);
}
/**
if (param_class->has_references)
mono_gc_wbarrier_value_copy (buf + klass->fields [0].offset - sizeof (MonoObject), mono_object_unbox (value), 1, param_class);
else
- mono_gc_memmove (buf + klass->fields [0].offset - sizeof (MonoObject), mono_object_unbox (value), mono_class_value_size (param_class, NULL));
+ mono_gc_memmove_atomic (buf + klass->fields [0].offset - sizeof (MonoObject), mono_object_unbox (value), mono_class_value_size (param_class, NULL));
} else {
- mono_gc_bzero (buf + klass->fields [0].offset - sizeof (MonoObject), mono_class_value_size (param_class, NULL));
+ mono_gc_bzero_atomic (buf + klass->fields [0].offset - sizeof (MonoObject), mono_class_value_size (param_class, NULL));
}
}
if (param_class->has_references)
mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
else
- mono_gc_memmove (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), mono_class_value_size (param_class, NULL));
+ mono_gc_memmove_atomic (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), mono_class_value_size (param_class, NULL));
return o;
}
else
}
static char **main_args = NULL;
-static int num_main_args;
+static int num_main_args = 0;
/**
* mono_runtime_get_main_args:
int i;
MonoDomain *domain = mono_domain_get ();
- if (!main_args)
- return NULL;
-
res = (MonoArray*)mono_array_new (domain, mono_defaults.string_class, num_main_args);
for (i = 0; i < num_main_args; ++i)
for (i = 0; i < num_main_args; ++i)
g_free (main_args [i]);
g_free (main_args);
+ num_main_args = 0;
+ main_args = NULL;
+}
+
+/**
+ * mono_runtime_set_main_args:
+ * @argc: number of arguments from the command line
+ * @argv: array of strings from the command line
+ *
+ * Set the command line arguments from an embedding application that doesn't otherwise call
+ * mono_runtime_run_main ().
+ */
+int
+mono_runtime_set_main_args (int argc, char* argv[])
+{
+ int i;
+
+ free_main_args ();
+ main_args = g_new0 (char*, argc);
+ num_main_args = argc;
+
+ for (i = 0; i < argc; ++i) {
+ gchar *utf8_arg;
+
+ utf8_arg = mono_utf8_from_external (argv[i]);
+ if (utf8_arg == NULL) {
+ g_print ("\nCannot determine the text encoding for argument %d (%s).\n", i, argv [i]);
+ g_print ("Please add the correct encoding to MONO_EXTERNAL_ENCODINGS and try again.\n");
+ exit (-1);
+ }
+
+ main_args [i] = utf8_arg;
+ }
+
+ return 0;
}
/**
}
mono_thread_init_apartment_state ();
- mono_debugger_event (MONO_DEBUGGER_EVENT_REACHED_MAIN, 0, 0);
-
/* FIXME: check signature of method */
if (mono_method_signature (method)->ret->type == MONO_TYPE_I4) {
MonoObject *res;
}
}
- mono_debugger_event (MONO_DEBUGGER_EVENT_MAIN_EXITED, (guint64) (gsize) rval, 0);
-
return rval;
}
} else {
int size = obj->vtable->klass->instance_size;
/* do not copy the sync state */
- mono_gc_memmove ((char*)o + sizeof (MonoObject), (char*)obj + sizeof (MonoObject), size - sizeof (MonoObject));
+ mono_gc_memmove_atomic ((char*)o + sizeof (MonoObject), (char*)obj + sizeof (MonoObject), size - sizeof (MonoObject));
}
if (G_UNLIKELY (profile_allocs))
mono_profiler_allocation (o, obj->vtable->klass);
#ifdef HAVE_SGEN_GC
if (klass->element_class->valuetype) {
if (klass->element_class->has_references)
- mono_value_copy_array (dest, 0, mono_array_addr_with_size (src, 0, 0), mono_array_length (src));
+ mono_value_copy_array (dest, 0, mono_array_addr_with_size_fast (src, 0, 0), mono_array_length (src));
else
- mono_gc_memmove (&dest->vector, &src->vector, size);
+ mono_gc_memmove_atomic (&dest->vector, &src->vector, size);
} else {
mono_array_memcpy_refs (dest, 0, src, 0, mono_array_length (src));
}
#else
- mono_gc_memmove (&dest->vector, &src->vector, size);
+ mono_gc_memmove_atomic (&dest->vector, &src->vector, size);
#endif
}
#ifdef HAVE_SGEN_GC
if (klass->element_class->valuetype) {
if (klass->element_class->has_references)
- mono_value_copy_array (o, 0, mono_array_addr_with_size (array, 0, 0), mono_array_length (array));
+ mono_value_copy_array (o, 0, mono_array_addr_with_size_fast (array, 0, 0), mono_array_length (array));
else
- mono_gc_memmove (&o->vector, &array->vector, size);
+ mono_gc_memmove_atomic (&o->vector, &array->vector, size);
} else {
mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
}
#else
- mono_gc_memmove (&o->vector, &array->vector, size);
+ mono_gc_memmove_atomic (&o->vector, &array->vector, size);
#endif
return o;
}
#ifdef HAVE_SGEN_GC
if (klass->element_class->valuetype) {
if (klass->element_class->has_references)
- mono_value_copy_array (o, 0, mono_array_addr_with_size (array, 0, 0), mono_array_length (array));
+ mono_value_copy_array (o, 0, mono_array_addr_with_size_fast (array, 0, 0), mono_array_length (array));
else
- mono_gc_memmove (&o->vector, &array->vector, size);
+ mono_gc_memmove_atomic (&o->vector, &array->vector, size);
} else {
mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
}
#else
- mono_gc_memmove (&o->vector, &array->vector, size);
+ mono_gc_memmove_atomic (&o->vector, &array->vector, size);
#endif
return o;
MonoArray*
mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
{
- uintptr_t byte_len, len, bounds_size;
+ uintptr_t byte_len = 0, len, bounds_size;
MonoObject *o;
MonoArray *array;
MonoArrayBounds *bounds;
return s;
}
+/**
+ * mono_string_new_utf32:
+ * @text: a pointer to an utf32 string
+ * @len: the length of the string
+ *
+ * Returns: A newly created string object which contains @text.
+ */
+MonoString *
+mono_string_new_utf32 (MonoDomain *domain, const mono_unichar4 *text, gint32 len)
+{
+ MonoString *s;
+ mono_unichar2 *utf16_output = NULL;
+ gint32 utf16_len = 0;
+ GError *error = NULL;
+ glong items_written;
+
+ utf16_output = g_ucs4_to_utf16 (text, len, NULL, &items_written, &error);
+
+ if (error)
+ g_error_free (error);
+
+ while (utf16_output [utf16_len]) utf16_len++;
+
+ s = mono_string_new_size (domain, utf16_len);
+ g_assert (s != NULL);
+
+ memcpy (mono_string_chars (s), utf16_output, utf16_len * 2);
+
+ g_free (utf16_output);
+
+ return s;
+}
+
/**
* mono_string_new_size:
* @text: a pointer to an utf16 string
{
MonoString *s;
MonoVTable *vtable;
- size_t size = (sizeof (MonoString) + ((len + 1) * 2));
+ size_t size;
- /* overflow ? can't fit it, can't allocate it! */
- if (len > size)
+ /* check for overflow */
+ if (len < 0 || len > ((SIZE_MAX - sizeof (MonoString) - 2) / 2))
mono_gc_out_of_memory (-1);
+ size = (sizeof (MonoString) + ((len + 1) * 2));
+ g_assert (size > 0);
+
vtable = mono_class_vtable (domain, mono_defaults.string_class);
g_assert (vtable);
mono_gc_wbarrier_value_copy ((char *)res + sizeof (MonoObject), value, 1, class);
#else
#if NO_UNALIGNED_ACCESS
- mono_gc_memmove ((char *)res + sizeof (MonoObject), value, size);
+ mono_gc_memmove_atomic ((char *)res + sizeof (MonoObject), value, size);
#else
switch (size) {
case 1:
*(guint64 *)((guint8 *) res + sizeof (MonoObject)) = *(guint64 *) value;
break;
default:
- mono_gc_memmove ((char *)res + sizeof (MonoObject), value, size);
+ mono_gc_memmove_atomic ((char *)res + sizeof (MonoObject), value, size);
}
#endif
#endif
mono_value_copy_array (MonoArray *dest, int dest_idx, gpointer src, int count)
{
int size = mono_array_element_size (dest->obj.vtable->klass);
- char *d = mono_array_addr_with_size (dest, size, dest_idx);
+ char *d = mono_array_addr_with_size_fast (dest, size, dest_idx);
g_assert (size == mono_class_value_size (mono_object_class (dest)->element_class, NULL));
mono_gc_wbarrier_value_copy (d, src, count, mono_object_class (dest)->element_class);
}
return (gunichar2 *)(as);
}
+/**
+ * mono_string_to_utf32:
+ * @s: a MonoString
+ *
+ * Return an null-terminated array of the UTF-32 (UCS-4) chars
+ * contained in @s. The result must be freed with g_free().
+ */
+mono_unichar4*
+mono_string_to_utf32 (MonoString *s)
+{
+ mono_unichar4 *utf32_output = NULL;
+ GError *error = NULL;
+ glong items_written;
+
+ if (s == NULL)
+ return NULL;
+
+ utf32_output = g_utf16_to_ucs4 (s->chars, s->length, NULL, &items_written, &error);
+
+ if (error)
+ g_error_free (error);
+
+ return utf32_output;
+}
+
/**
* mono_string_from_utf16:
* @data: the UTF16 string (LPWSTR) to convert
if (class->has_references)
mono_gc_wbarrier_value_copy (*((gpointer *)params [i]), arg + sizeof (MonoObject), 1, class);
else
- mono_gc_memmove (*((gpointer *)params [i]), arg + sizeof (MonoObject), size);
+ mono_gc_memmove_atomic (*((gpointer *)params [i]), arg + sizeof (MonoObject), size);
} else {
size = mono_class_value_size (mono_class_from_mono_type (pt), NULL);
- mono_gc_bzero (*((gpointer *)params [i]), size);
+ mono_gc_bzero_atomic (*((gpointer *)params [i]), size);
}
}