case MONO_RESOLTION_SCOPE_TYPEREF: {
MonoClass *enclosing = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | idx);
GList *tmp;
- mono_class_init (enclosing);
- for (tmp = enclosing->nested_classes; tmp; tmp = tmp->next) {
- res = tmp->data;
- if (strcmp (res->name, name) == 0)
- return res;
+
+ if (enclosing->inited) {
+ /* Micro-optimization: don't scan the metadata tables if enclosing is already inited */
+ for (tmp = enclosing->nested_classes; tmp; tmp = tmp->next) {
+ res = tmp->data;
+ if (strcmp (res->name, name) == 0)
+ return res;
+ }
+ } else {
+ /* Don't call mono_class_init as we might've been called by it recursively */
+ int i = mono_metadata_nesting_typedef (enclosing->image, enclosing->type_token, 1);
+ while (i) {
+ guint32 class_nested = mono_metadata_decode_row_col (&enclosing->image->tables [MONO_TABLE_NESTEDCLASS], i - 1, MONO_NESTED_CLASS_NESTED);
+ guint32 string_offset = mono_metadata_decode_row_col (&enclosing->image->tables [MONO_TABLE_TYPEDEF], class_nested - 1, MONO_TYPEDEF_NAME);
+ const char *nname = mono_metadata_string_heap (enclosing->image, string_offset);
+
+ if (strcmp (nname, name) == 0)
+ return mono_class_create_from_typedef (enclosing->image, MONO_TOKEN_TYPE_DEF | class_nested);
+
+ i = mono_metadata_nesting_typedef (enclosing->image, enclosing->type_token, i + 1);
+ }
}
g_warning ("TypeRef ResolutionScope not yet handled (%d)", idx);
return NULL;
r->byref = original->byref;
if (t->type == MONO_TYPE_PTR)
t->data.type = dup_type (t->data.type, original->data.type);
+ else if (t->type == MONO_TYPE_ARRAY)
+ t->data.array = mono_dup_array_type (t->data.array);
+ else if (t->type == MONO_TYPE_FNPTR)
+ t->data.method = mono_metadata_signature_deep_dup (t->data.method);
mono_stats.generics_metadata_size += sizeof (MonoType);
return r;
}
+/* Copy everything mono_metadata_free_array free. */
+MonoArrayType *
+mono_dup_array_type (MonoArrayType *a)
+{
+ a = g_memdup (a, sizeof (MonoArrayType));
+ if (a->sizes)
+ a->sizes = g_memdup (a->sizes, a->numsizes * sizeof (int));
+ if (a->lobounds)
+ a->lobounds = g_memdup (a->lobounds, a->numlobounds * sizeof (int));
+ return a;
+}
+
+/* Copy everything mono_metadata_free_method_signature free. */
+MonoMethodSignature*
+mono_metadata_signature_deep_dup (MonoMethodSignature *sig)
+{
+ int i;
+
+ sig = mono_metadata_signature_dup (sig);
+
+ sig->ret = dup_type (sig->ret, sig->ret);
+ for (i = 0; i < sig->param_count; ++i)
+ sig->params [i] = dup_type (sig->params [i], sig->params [i]);
+
+ return sig;
+}
+
static void
_mono_type_get_assembly_name (MonoClass *klass, GString *str)
{
g_string_append_c (str, '.');
else
g_string_append_c (str, '+');
- }
- if (*klass->name_space) {
+ } else if (*klass->name_space) {
g_string_append (str, klass->name_space);
g_string_append_c (str, '.');
}
}
/**
- * class_compute_field_layout:
+ * mono_class_setup_fields:
* @m: pointer to the metadata.
* @class: The class to initialize
*
* Initializes the class->fields.
*/
static void
-class_compute_field_layout (MonoClass *class)
+mono_class_setup_fields (MonoClass *class)
{
MonoImage *m = class->image;
const int top = class->field.count;
if (class->size_inited)
return;
+ class->instance_size = 0;
+ class->class_size = 0;
+
if (class->parent) {
if (!class->parent->size_inited)
- class_compute_field_layout (class->parent);
+ mono_class_setup_fields (class->parent);
class->instance_size += class->parent->instance_size;
class->min_align = class->parent->min_align;
/* we use |= since it may have been set already */
}
if (class->init_pending) {
- /*
- * We might be called recursively from mono_class_from_typeref if
- * one of our fields has a type which is a nested type of this class,
- * and the compiler encodes it as a typeref, like older versions of
- * MS ilasm do.
- */
- if (class->size_inited) {
- mono_loader_unlock ();
- return;
- }
-
+ mono_loader_unlock ();
/* this indicates a cyclic dependency */
g_error ("pending init %s.%s\n", class->name_space, class->name);
}
/*
* Computes the size used by the fields, and their locations
*/
- if (!class->size_inited)
- class_compute_field_layout (class);
+ if (has_cached_info) {
+ class->instance_size = cached_info.instance_size;
+ class->class_size = cached_info.class_size;
+ class->packing_size = cached_info.packing_size;
+ class->min_align = cached_info.min_align;
+ class->blittable = cached_info.blittable;
+ class->has_references = cached_info.has_references;
+ class->has_static_refs = cached_info.has_static_refs;
+ }
+ else
+ if (!class->size_inited)
+ mono_class_setup_fields (class);
/* initialize method pointers */
if (class->rank) {
}
if (class->enumtype)
- class_compute_field_layout (class);
+ mono_class_setup_fields (class);
if ((type_token = mono_metadata_nested_in_typedef (image, type_token)))
class->nested_in = mono_class_create_from_typedef (image, type_token);
switch (type->type) {
case MONO_TYPE_ARRAY:
- class = mono_array_class_get (type->data.array->eklass, type->data.array->rank);
+ class = mono_bounded_array_class_get (type->data.array->eklass, type->data.array->rank, TRUE);
break;
case MONO_TYPE_SZARRAY:
class = mono_array_class_get (type->data.klass, 1);
if (eclass->generic_class)
mono_class_init (eclass);
if (!eclass->size_inited)
- class_compute_field_layout (eclass);
+ mono_class_setup_fields (eclass);
class->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE;
class->rank = rank;
static MonoClassField *
mono_class_get_field_idx (MonoClass *class, int idx)
{
+ mono_class_setup_fields (class);
+
if (class->field.count){
if ((idx >= class->field.first) && (idx < class->field.last)){
return &class->fields [idx - class->field.first];
int i;
while (klass) {
+ mono_class_setup_fields (klass);
for (i = 0; i < klass->field.count; ++i) {
if (strcmp (name, klass->fields [i].name) == 0)
return &klass->fields [i];
int i;
while (klass) {
+ mono_class_setup_fields (klass);
for (i = 0; i < klass->field.count; ++i) {
if (&klass->fields [i] == field)
return mono_metadata_make_token (MONO_TABLE_FIELD, klass->field.first + i + 1);
return mono_class_from_mono_type (inflated);
}
+typedef struct {
+ gconstpointer key;
+ gpointer value;
+} FindUserData;
+
+static void
+find_nocase (gpointer key, gpointer value, gpointer user_data)
+{
+ char *name = (char*)key;
+ FindUserData *data = (FindUserData*)user_data;
+
+ if (!data->value && (g_strcasecmp (name, (char*)data->key) == 0))
+ data->value = value;
+}
+
/**
* mono_class_from_name_case:
* @image: The MonoImage where the type is looked up in, or NULL for looking up in all loaded assemblies
const char *nspace;
guint32 i, visib;
+ if (image->dynamic) {
+ guint32 token = 0;
+ FindUserData user_data;
+
+ mono_loader_lock ();
+
+ user_data.key = name_space;
+ user_data.value = NULL;
+ g_hash_table_foreach (image->name_cache, find_nocase, &user_data);
+
+ if (user_data.value) {
+ GHashTable *nspace_table = (GHashTable*)user_data.value;
+
+ user_data.key = name;
+ user_data.value = NULL;
+
+ g_hash_table_foreach (nspace_table, find_nocase, &user_data);
+
+ if (user_data.value)
+ token = GPOINTER_TO_UINT (user_data.value);
+ }
+
+ mono_loader_unlock ();
+
+ if (token)
+ return mono_class_get (image, MONO_TOKEN_TYPE_DEF | token);
+ else
+ return NULL;
+
+ }
+
/* add a cache if needed */
for (i = 1; i <= t->rows; ++i) {
mono_metadata_decode_row (t, i - 1, cols, MONO_TYPEDEF_SIZE);
/**
- * mono_class_from_name_case:
+ * mono_class_from_name:
* @image: The MonoImage where the type is looked up in, or NULL for looking up in all loaded assemblies
* @name_space: the type namespace
* @name: the type short name.
if (!klass->inited)
mono_class_init (klass);
if (!*iter) {
+ mono_class_setup_fields (klass);
/* start from the first */
if (klass->field.count) {
return *iter = &klass->fields [0];
MonoDomain *domain = mono_domain_get ();
MonoSecurityManager* secman = mono_security_manager_get_methods ();
MonoMethod *method = klass->exception_data;
- guint32 error = (method) ? MONO_METADATA_INHERITANCEDEMAND_CLASS : MONO_METADATA_INHERITANCEDEMAND_METHOD;
+ guint32 error = (method) ? MONO_METADATA_INHERITANCEDEMAND_METHOD : MONO_METADATA_INHERITANCEDEMAND_CLASS;
MonoObject *exc = NULL;
gpointer args [4];