static void mono_class_setup_vtable_full (MonoClass *class, GList *in_setup);
static void mono_generic_class_setup_parent (MonoClass *klass, MonoClass *gklass);
-
-void (*mono_debugger_class_init_func) (MonoClass *klass) = NULL;
-
-
/*
We use gclass recording to allow recursive system f types to be referenced by a parent.
* is_generic_method_definition().
*/
- return mono_method_inflated_lookup (iresult, TRUE);
+ return (MonoMethod*)mono_method_inflated_lookup (iresult, TRUE);
fail:
g_free (iresult);
explicit_size = mono_metadata_packing_from_typedef (class->image, class->type_token, &packing_size, &real_size);
if (explicit_size) {
- if ((packing_size & 0xfffffff0) != 0) {
- char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", class->name, packing_size);
+ if ((packing_size & 0xffffff00) != 0) {
+ char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", class->name, packing_size);
mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, err_msg);
return;
}
MonoMethodSignature *sig;
int count_generic = 0, first_generic = 0;
int method_num = 0;
+ gboolean jagged_ctor = FALSE;
count = 3 + (class->rank > 1? 2: 1);
mono_class_setup_interfaces (class, &error);
g_assert (mono_error_ok (&error)); /*FIXME can this fail for array types?*/
+ if (class->rank == 1 && class->element_class->rank) {
+ jagged_ctor = TRUE;
+ class->method.count ++;
+ }
+
if (class->interface_count) {
count_generic = generic_array_methods (class);
first_generic = count;
amethod = create_array_method (class, ".ctor", sig);
methods [method_num++] = amethod;
}
+
+ if (jagged_ctor) {
+ /* Jagged arrays have an extra ctor in .net which creates an array of arrays */
+ sig = mono_metadata_signature_alloc (class->image, class->rank + 1);
+ sig->ret = &mono_defaults.void_class->byval_arg;
+ sig->pinvoke = TRUE;
+ sig->hasthis = TRUE;
+ for (i = 0; i < class->rank + 1; ++i)
+ sig->params [i] = &mono_defaults.int32_class->byval_arg;
+ amethod = create_array_method (class, ".ctor", sig);
+ methods [method_num++] = amethod;
+ }
+
/* element Get (idx11, [idx2, ...]) */
sig = mono_metadata_signature_alloc (class->image, class->rank);
sig->ret = &class->element_class->byval_arg;
mono_loader_unlock ();
- if (mono_debugger_class_init_func)
- mono_debugger_class_init_func (class);
-
return class->exception_type == MONO_EXCEPTION_NONE;
}
#define FAST_CACHE_SIZE 16
+/*
+ * LOCKING: Takes the image lock depending on @take_lock.
+ */
static MonoClass *
-get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
+get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_lock)
{
int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
MonoImage *image = param->image;
else
return image->var_cache_fast ? image->var_cache_fast [n] : NULL;
} else {
+ MonoClass *klass = NULL;
ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
- return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
+ if (ht) {
+ if (take_lock)
+ mono_image_lock (image);
+ klass = g_hash_table_lookup (ht, GINT_TO_POINTER (n));
+ if (take_lock)
+ mono_image_unlock (image);
+ }
+ return klass;
}
}
/*
- * LOCKING: Acquires the loader lock.
+ * LOCKING: Image lock (param->image) must be held
*/
static void
set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
{
int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
MonoImage *image = param->image;
- GHashTable *ht;
g_assert (image);
if (n < FAST_CACHE_SIZE) {
if (is_mvar) {
- /* No locking needed */
+ /* Requires locking to avoid droping an already published class */
if (!image->mvar_cache_fast)
image->mvar_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
image->mvar_cache_fast [n] = klass;
image->var_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
image->var_cache_fast [n] = klass;
}
- return;
- }
- ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
- if (!ht) {
- mono_image_lock (image);
- ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+ } else {
+ GHashTable *ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
if (!ht) {
- ht = g_hash_table_new (NULL, NULL);
- mono_memory_barrier ();
- if (is_mvar)
- image->mvar_cache_slow = ht;
- else
- image->var_cache_slow = ht;
+ ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+ if (!ht) {
+ ht = g_hash_table_new (NULL, NULL);
+ mono_memory_barrier ();
+ if (is_mvar)
+ image->mvar_cache_slow = ht;
+ else
+ image->var_cache_slow = ht;
+ }
}
- mono_image_unlock (image);
+ g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
}
-
- g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
}
/*
- * LOCKING: Acquires the loader lock.
+ * LOCKING: Acquires the image lock (@image).
*/
MonoClass *
mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gboolean is_mvar)
{
MonoGenericContainer *container = mono_generic_param_owner (param);
- MonoGenericParamInfo *pinfo;
- MonoClass *klass;
-
- mono_loader_lock ();
+ MonoGenericParamInfo *pinfo = NULL;
+ MonoClass *klass, *klass2;
if (container) {
pinfo = mono_generic_param_info (param);
- if (pinfo->pklass) {
- mono_loader_unlock ();
- return pinfo->pklass;
- }
+ klass = pinfo->pklass;
} else {
- pinfo = NULL;
image = NULL;
-
- klass = get_anon_gparam_class (param, is_mvar);
- if (klass) {
- mono_loader_unlock ();
- return klass;
- }
+ klass = get_anon_gparam_class (param, is_mvar, TRUE);
}
+ if (klass)
+ return klass;
if (!image && container) {
if (is_mvar) {
mono_memory_barrier ();
+ if (!image) //FIXME is this only needed by monodis? Can't we fix monodis instead of having this hack?
+ image = mono_defaults.corlib;
+
+ mono_image_lock (image);
if (container)
- pinfo->pklass = klass;
+ klass2 = pinfo->pklass;
else
- set_anon_gparam_class (param, is_mvar, klass);
+ klass2 = get_anon_gparam_class (param, is_mvar, FALSE);
- mono_loader_unlock ();
+ if (klass2) {
+ klass = klass2;
+ } else {
+ if (container)
+ pinfo->pklass = klass;
+ else
+ set_anon_gparam_class (param, is_mvar, klass);
+ }
+ mono_image_unlock (image);
/* FIXME: Should this go inside 'make_generic_param_klass'? */
- mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+ if (klass2)
+ mono_profiler_class_loaded (klass2, MONO_PROFILE_FAILED);
+ else
+ mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
return klass;
}
el_class = mono_class_from_mono_type (type);
image = el_class->image;
- mono_loader_lock ();
-
- if (!image->ptr_cache)
- image->ptr_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
-
- if ((result = g_hash_table_lookup (image->ptr_cache, el_class))) {
- mono_loader_unlock ();
- return result;
+ mono_image_lock (image);
+ if (image->ptr_cache) {
+ if ((result = g_hash_table_lookup (image->ptr_cache, el_class))) {
+ mono_image_unlock (image);
+ return result;
+ }
}
+ mono_image_unlock (image);
+
result = mono_image_alloc0 (image, sizeof (MonoClass));
classes_size += sizeof (MonoClass);
mono_class_setup_supertypes (result);
+ mono_image_lock (image);
+ if (image->ptr_cache) {
+ MonoClass *result2;
+ if ((result2 = g_hash_table_lookup (image->ptr_cache, el_class))) {
+ mono_image_unlock (image);
+ mono_profiler_class_loaded (result, MONO_PROFILE_FAILED);
+ return result2;
+ }
+ } else {
+ image->ptr_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
+ }
g_hash_table_insert (image->ptr_cache, el_class, result);
-
- mono_loader_unlock ();
+ mono_image_unlock (image);
mono_profiler_class_loaded (result, MONO_PROFILE_OK);
sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
mono_metadata_decode_blob_size (sig, &sig);
if (*sig == 0x6) { /* it's a field */
+ MonoError error;
MonoClass *klass;
MonoClassField *field;
- field = mono_field_from_token (image, token, &klass, context);
+ field = mono_field_from_token_checked (image, token, &klass, context, &error);
if (handle_class)
*handle_class = mono_defaults.fieldhandle_class;
+ if (!field) {
+ mono_loader_set_error_from_mono_error (&error);
+ mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+ }
return field;
} else {
MonoMethod *meth;