X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fclass.c;h=95ab07ff6b9664d20741a1b5a12c8535dda0ce79;hb=eac667af686b6308852f7072ad4253dfa4ed569e;hp=b0c708b6a7eb33bbad13d586c74d67da8d247fa7;hpb=26bb76023822a37e7f25cd7b19e1569e76c75487;p=mono.git diff --git a/mono/metadata/class.c b/mono/metadata/class.c index b0c708b6a7e..95ab07ff6b9 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -65,6 +65,7 @@ static char* mono_assembly_name_from_token (MonoImage *image, guint32 type_token static gboolean mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass); static void mono_field_resolve_type (MonoClassField *field, MonoError *error); static guint32 mono_field_resolve_flags (MonoClassField *field); +static void mono_class_setup_vtable_full (MonoClass *class, GList *in_setup); void (*mono_debugger_class_init_func) (MonoClass *klass) = NULL; @@ -237,15 +238,11 @@ static void _mono_type_get_assembly_name (MonoClass *klass, GString *str) { MonoAssembly *ta = klass->image->assembly; - const char *quote = g_ascii_isspace (ta->aname.name [0]) ? "\"" : ""; + char *name; - g_string_append_printf ( - str, ", %s%s%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s", - quote, ta->aname.name, quote, - ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision, - ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral", - ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null", - (ta->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : ""); + name = mono_stringify_assembly_name (&ta->aname); + g_string_append_printf (str, ", %s", name); + g_free (name); } static inline void @@ -1220,12 +1217,7 @@ static gpointer mono_class_alloc (MonoClass *class, int size) { if (class->generic_class) - /* - * This should be freed in free_generic_class () in metadata.c. - * FIXME: It would be better to allocate this from the image set mempool, by - * adding an image_set field to MonoGenericClass. - */ - return g_malloc (size); + return mono_image_set_alloc (class->generic_class->owner, size); else return mono_image_alloc (class->image, size); } @@ -1548,13 +1540,6 @@ mono_class_has_references (MonoClass *klass) } } -/* useful until we keep track of gc-references in corlib etc. */ -#ifdef HAVE_SGEN_GC -#define IS_GC_REFERENCE(t) FALSE -#else -#define IS_GC_REFERENCE(t) ((t)->type == MONO_TYPE_U && class->image == mono_defaults.corlib) -#endif - /* * mono_type_get_basic_type_from_generic: * @type: a type @@ -2484,6 +2469,10 @@ collect_implemented_interfaces_aux (MonoClass *klass, GPtrArray **res, MonoError *res = g_ptr_array_new (); g_ptr_array_add (*res, ic); mono_class_init (ic); + if (ic->exception_type) { + mono_error_set_type_load_class (error, ic, "Error Loading class"); + return; + } collect_implemented_interfaces_aux (ic, res, error); if (!mono_error_ok (error)) @@ -3320,6 +3309,58 @@ mono_class_setup_interface_offsets (MonoClass *class) mono_loader_unlock (); } + +/*Checks if @klass has @parent as one of it's parents type gtd + * + * For example: + * Foo + * Bar : Foo>> + * + */ +static gboolean +mono_class_has_gtd_parent (MonoClass *klass, MonoClass *parent) +{ + klass = mono_class_get_generic_type_definition (klass); + parent = mono_class_get_generic_type_definition (parent); + mono_class_setup_supertypes (klass); + mono_class_setup_supertypes (parent); + + return klass->idepth >= parent->idepth && + mono_class_get_generic_type_definition (klass->supertypes [parent->idepth - 1]) == parent; +} + +gboolean +mono_class_check_vtable_constraints (MonoClass *class, GList *in_setup) +{ + MonoGenericInst *ginst; + int i; + if (!class->generic_class) { + mono_class_setup_vtable_full (class, in_setup); + return class->exception_type == 0; + } + + mono_class_setup_vtable_full (mono_class_get_generic_type_definition (class), in_setup); + if (class->generic_class->container_class->exception_type) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to load generic definition vtable")); + return FALSE; + } + + ginst = class->generic_class->context.class_inst; + for (i = 0; i < ginst->type_argc; ++i) { + MonoClass *arg; + if (ginst->type_argv [i]->type != MONO_TYPE_GENERICINST) + continue; + arg = mono_class_from_mono_type (ginst->type_argv [i]); + /*Those 2 will be checked by mono_class_setup_vtable itself*/ + if (mono_class_has_gtd_parent (class, arg) || mono_class_has_gtd_parent (arg, class)) + continue; + if (!mono_class_check_vtable_constraints (arg, in_setup)) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Failed to load generic parameter %d", i)); + return FALSE; + } + } + return TRUE; +} /* * mono_class_setup_vtable: @@ -3335,6 +3376,12 @@ mono_class_setup_interface_offsets (MonoClass *class) */ void mono_class_setup_vtable (MonoClass *class) +{ + mono_class_setup_vtable_full (class, NULL); +} + +static void +mono_class_setup_vtable_full (MonoClass *class, GList *in_setup) { MonoMethod **overrides; MonoGenericContext *context; @@ -3358,6 +3405,9 @@ mono_class_setup_vtable (MonoClass *class) if (class->exception_type) return; + if (g_list_find (in_setup, class)) + return; + mono_loader_lock (); if (class->vtable) { @@ -3366,8 +3416,15 @@ mono_class_setup_vtable (MonoClass *class) } mono_stats.generic_vtable_count ++; + in_setup = g_list_prepend (in_setup, class); if (class->generic_class) { + if (!mono_class_check_vtable_constraints (class, in_setup)) { + mono_loader_unlock (); + g_list_remove (in_setup, class); + return; + } + context = mono_class_get_context (class); type_token = class->generic_class->container_class->type_token; } else { @@ -3388,13 +3445,14 @@ mono_class_setup_vtable (MonoClass *class) } if (ok) - mono_class_setup_vtable_general (class, overrides, onum); + mono_class_setup_vtable_general (class, overrides, onum, in_setup); else mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not load list of method overrides")); g_free (overrides); mono_loader_unlock (); + g_list_remove (in_setup, class); return; } @@ -3526,7 +3584,14 @@ check_interface_method_override (MonoClass *class, MonoMethod *im, MonoMethod *c TRACE_INTERFACE_VTABLE (printf ("[RANK CHECK FAILED]")); return FALSE; } - if (! mono_metadata_signature_equal (mono_method_signature (cm), mono_method_signature (im))) { + cmsig = mono_method_signature (cm); + imsig = mono_method_signature (im); + if (!cmsig || !imsig) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not resolve the signature of a virtual method")); + return FALSE; + } + + if (! mono_metadata_signature_equal (cmsig, imsig)) { TRACE_INTERFACE_VTABLE (printf ("[(INJECTED) SIGNATURE CHECK FAILED ")); TRACE_INTERFACE_VTABLE (print_method_signatures (im, cm)); TRACE_INTERFACE_VTABLE (printf ("]")); @@ -3773,7 +3838,7 @@ mono_class_need_stelemref_method (MonoClass *class) * LOCKING: this is supposed to be called with the loader lock held. */ void -mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int onum) +mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int onum, GList *in_setup) { MonoError error; MonoClass *k, *ic; @@ -3814,7 +3879,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o if (class->parent) { mono_class_init (class->parent); - mono_class_setup_vtable (class->parent); + mono_class_setup_vtable_full (class->parent, in_setup); if (class->parent->exception_type) { char *name = mono_type_get_full_name (class->parent); @@ -3854,7 +3919,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o MonoClass *gklass = class->generic_class->container_class; MonoMethod **tmp; - mono_class_setup_vtable (gklass); + mono_class_setup_vtable_full (gklass, in_setup); if (gklass->exception_type != MONO_EXCEPTION_NONE) { mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); return; @@ -4536,24 +4601,23 @@ mono_class_init (MonoClass *class) g_assert (class); /* Double-checking locking pattern */ - if (class->inited) + if (class->inited || class->exception_type) return class->exception_type == MONO_EXCEPTION_NONE; - /*g_print ("Init class %s\n", class->name);*/ + /*g_print ("Init class %s\n", mono_type_get_full_name (class));*/ /* We do everything inside the lock to prevent races */ mono_loader_lock (); - if (class->inited) { + if (class->inited || class->exception_type) { mono_loader_unlock (); /* Somebody might have gotten in before us */ return class->exception_type == MONO_EXCEPTION_NONE; } if (class->init_pending) { - mono_loader_unlock (); - /* this indicates a cyclic dependency */ - g_error ("pending init %s.%s\n", class->name_space, class->name); + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Recursive type definition detected")); + goto leave; } class->init_pending = 1; @@ -4654,6 +4718,7 @@ mono_class_init (MonoClass *class) /* AOT case */ class->vtable_size = cached_info.vtable_size; class->has_finalize = cached_info.has_finalize; + class->has_finalize_inited = TRUE; class->ghcimpl = cached_info.ghcimpl; class->has_cctor = cached_info.has_cctor; } else if (class->rank == 1 && class->byval_arg.type == MONO_TYPE_SZARRAY) { @@ -4671,12 +4736,14 @@ mono_class_init (MonoClass *class) } else { class->vtable_size = szarray_vtable_size[slot]; } + class->has_finalize_inited = TRUE; } else if (class->generic_class && !MONO_CLASS_IS_INTERFACE (class)) { MonoClass *gklass = class->generic_class->container_class; /* Generic instance case */ class->ghcimpl = gklass->ghcimpl; - class->has_finalize = gklass->has_finalize; + class->has_finalize = mono_class_has_finalizer (gklass); + class->has_finalize_inited = TRUE; class->has_cctor = gklass->has_cctor; mono_class_setup_vtable (gklass); @@ -4701,45 +4768,6 @@ mono_class_init (MonoClass *class) } */ - /* Interfaces and valuetypes are not supposed to have finalizers */ - if (!(MONO_CLASS_IS_INTERFACE (class) || class->valuetype)) { - MonoMethod *cmethod = NULL; - - if (class->parent && class->parent->has_finalize) { - class->has_finalize = 1; - } else { - if (class->type_token) { - cmethod = find_method_in_metadata (class, "Finalize", 0, METHOD_ATTRIBUTE_VIRTUAL); - } else if (class->parent) { - /* FIXME: Optimize this */ - mono_class_setup_vtable (class); - if (class->exception_type || mono_loader_get_last_error ()) - goto leave; - cmethod = class->vtable [finalize_slot]; - } - - if (cmethod) { - /* Check that this is really the finalizer method */ - mono_class_setup_vtable (class); - if (class->exception_type || mono_loader_get_last_error ()) - goto leave; - - g_assert (class->vtable_size > finalize_slot); - - class->has_finalize = 0; - if (class->parent) { - cmethod = class->vtable [finalize_slot]; - g_assert (cmethod); - if (cmethod->is_inflated) - cmethod = ((MonoMethodInflated*)cmethod)->declaring; - if (cmethod != default_finalize) { - class->has_finalize = 1; - } - } - } - } - } - /* C# doesn't allow interfaces to have cctors */ if (!MONO_CLASS_IS_INTERFACE (class) || class->image != mono_defaults.corlib) { MonoMethod *cmethod = NULL; @@ -4804,6 +4832,9 @@ mono_class_init (MonoClass *class) mono_loader_clear_error (); } + if (class->generic_class && !mono_verifier_class_is_valid_generic_instantiation (class)) + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Invalid generic instantiation")); + goto leave; leave: @@ -4820,6 +4851,66 @@ mono_class_init (MonoClass *class) return class->exception_type == MONO_EXCEPTION_NONE; } +/* + * mono_class_has_finalizer: + * + * Return whenever KLASS has a finalizer, initializing klass->has_finalizer in the + * process. + */ +gboolean +mono_class_has_finalizer (MonoClass *klass) +{ + if (!klass->has_finalize_inited) { + MonoClass *class = klass; + + mono_loader_lock (); + + /* Interfaces and valuetypes are not supposed to have finalizers */ + if (!(MONO_CLASS_IS_INTERFACE (class) || class->valuetype)) { + MonoMethod *cmethod = NULL; + + if (class->parent && class->parent->has_finalize) { + class->has_finalize = 1; + } else { + if (class->parent) { + /* + * Can't search in metadata for a method named Finalize, because that + * ignores overrides. + */ + mono_class_setup_vtable (class); + if (class->exception_type || mono_loader_get_last_error ()) + goto leave; + cmethod = class->vtable [finalize_slot]; + } + + if (cmethod) { + g_assert (class->vtable_size > finalize_slot); + + class->has_finalize = 0; + if (class->parent) { + if (cmethod->is_inflated) + cmethod = ((MonoMethodInflated*)cmethod)->declaring; + if (cmethod != default_finalize) { + class->has_finalize = 1; + } + } + } + } + } + + mono_memory_barrier (); + klass->has_finalize_inited = TRUE; + + mono_loader_unlock (); + } + + return klass->has_finalize; + + leave: + mono_loader_unlock (); + return FALSE; +} + gboolean mono_is_corlib_image (MonoImage *image) { @@ -5133,7 +5224,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) if ((class = mono_internal_hash_table_lookup (&image->class_cache, GUINT_TO_POINTER (type_token)))) { mono_loader_unlock (); - return class->exception_type ? NULL : class; + return class; } mono_metadata_decode_row (tt, tidx - 1, cols, MONO_TYPEDEF_SIZE); @@ -5182,23 +5273,18 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) if (parent == NULL){ mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not load parent type")); - mono_loader_unlock (); - mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); - return NULL; + mono_loader_clear_error (); + goto parent_failure; } for (tmp = parent; tmp; tmp = tmp->parent) { if (tmp == class) { mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Cycle found while resolving parent")); - mono_loader_unlock (); - mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); - return NULL; + goto parent_failure; } if (class->generic_container && tmp->generic_class && tmp->generic_class->container_class == class) { mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Parent extends generic instance of this type")); - mono_loader_unlock (); - mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); - return NULL; + goto parent_failure; } } } @@ -5283,6 +5369,8 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) if (class->enumtype) { MonoType *enum_basetype = mono_class_find_enum_basetype (class); if (!enum_basetype) { + /*set it to a default value as the whole runtime can't handle this to be null*/ + class->cast_class = class->element_class = mono_defaults.int32_class; mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); mono_loader_unlock (); mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); @@ -5316,6 +5404,13 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) mono_profiler_class_loaded (class, MONO_PROFILE_OK); return class; + +parent_failure: + mono_class_setup_mono_type (class); + mono_loader_unlock (); + mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); + return NULL; + } /** is klass Nullable? */ @@ -5344,14 +5439,16 @@ mono_generic_class_get_class (MonoGenericClass *gclass) { MonoClass *klass, *gklass; + if (gclass->cached_class) + return gclass->cached_class; + mono_loader_lock (); if (gclass->cached_class) { mono_loader_unlock (); return gclass->cached_class; } - gclass->cached_class = g_malloc0 (sizeof (MonoClass)); - klass = gclass->cached_class; + klass = mono_image_set_alloc0 (gclass->owner, sizeof (MonoClass)); gklass = gclass->container_class; @@ -5390,7 +5487,14 @@ mono_generic_class_get_class (MonoGenericClass *gclass) */ if (gklass->parent) { - klass->parent = mono_class_inflate_generic_class (gklass->parent, mono_generic_class_get_context (gclass)); + MonoError error; + klass->parent = mono_class_inflate_generic_class_checked (gklass->parent, mono_generic_class_get_context (gclass), &error); + if (!mono_error_ok (&error)) { + /*Set parent to something safe as the runtime doesn't handle well this kind of failure.*/ + klass->parent = mono_defaults.object_class; + mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); + mono_error_cleanup (&error); + } } if (klass->parent) @@ -5418,6 +5522,9 @@ mono_generic_class_get_class (MonoGenericClass *gclass) } } + mono_memory_barrier (); + gclass->cached_class = klass; + mono_profiler_class_loaded (klass, MONO_PROFILE_OK); inflated_classes ++; @@ -5509,48 +5616,75 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is if (count - pos > 0) { mono_class_setup_vtable (klass->parent); - g_assert (!klass->parent->exception_type); - setup_interface_offsets (klass, klass->parent->vtable_size); + if (klass->parent->exception_type) + mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to setup parent interfaces")); + else + setup_interface_offsets (klass, klass->parent->vtable_size); } return klass; } #define FAST_CACHE_SIZE 16 -static MonoClass *var_cache_fast [FAST_CACHE_SIZE]; -static MonoClass *mvar_cache_fast [FAST_CACHE_SIZE]; -static GHashTable *var_cache_slow; -static GHashTable *mvar_cache_slow; static MonoClass * get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar) { int n = mono_generic_param_num (param); + MonoImage *image = param->image; GHashTable *ht; - if (n < FAST_CACHE_SIZE) - return (is_mvar ? mvar_cache_fast : var_cache_fast) [n]; - ht = is_mvar ? mvar_cache_slow : var_cache_slow; - return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL; + g_assert (image); + + if (n < FAST_CACHE_SIZE) { + if (is_mvar) + return image->mvar_cache_fast ? image->mvar_cache_fast [n] : NULL; + else + return image->var_cache_fast ? image->var_cache_fast [n] : NULL; + } else { + ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow; + return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL; + } } +/* + * LOCKING: Acquires the loader lock. + */ static void set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass) { int n = mono_generic_param_num (param); + MonoImage *image = param->image; GHashTable *ht; + g_assert (image); + if (n < FAST_CACHE_SIZE) { - (is_mvar ? mvar_cache_fast : var_cache_fast) [n] = klass; + if (is_mvar) { + /* No locking needed */ + if (!image->mvar_cache_fast) + image->mvar_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE); + image->mvar_cache_fast [n] = klass; + } else { + if (!image->var_cache_fast) + image->var_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE); + image->var_cache_fast [n] = klass; + } return; } - ht = is_mvar ? mvar_cache_slow : var_cache_slow; + ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow; if (!ht) { - ht = g_hash_table_new (NULL, NULL); - if (is_mvar) - mvar_cache_slow = ht; - else - var_cache_slow = ht; + mono_loader_lock (); + 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_loader_unlock (); } g_hash_table_insert (ht, GINT_TO_POINTER (n), klass); @@ -6940,7 +7074,8 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name name = buf; } - if (get_class_from_name) { + /* FIXME: get_class_from_name () can't handle types in the EXPORTEDTYPE table */ + if (get_class_from_name && image->tables [MONO_TABLE_EXPORTEDTYPE].rows == 0) { gboolean res = get_class_from_name (image, name_space, name, &class); if (res) { if (!class) @@ -7094,7 +7229,7 @@ mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass) MonoGenericContainer *container = klass_gtd->generic_container; /*Viable candidates are instances of the same generic interface*/ - if (mono_class_get_generic_type_definition (oklass) != klass_gtd) + if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd) return FALSE; klass_argv = &klass->generic_class->context.class_inst->type_argv [0]; @@ -7136,12 +7271,16 @@ mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass) gboolean mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) { + /*FIXME this will cause a lot of irrelevant stuff to be loaded.*/ if (!klass->inited) mono_class_init (klass); if (!oklass->inited) mono_class_init (oklass); + if (klass->exception_type || oklass->exception_type) + return FALSE; + if ((klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR)) return klass == oklass; @@ -7230,7 +7369,7 @@ mono_class_is_variant_compatible_slow (MonoClass *klass, MonoClass *oklass) MonoGenericContainer *container = klass_gtd->generic_container; /*Viable candidates are instances of the same generic interface*/ - if (mono_class_get_generic_type_definition (oklass) != klass_gtd) + if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd) return FALSE; klass_argv = &klass->generic_class->context.class_inst->type_argv [0]; @@ -7284,7 +7423,12 @@ mono_class_implement_interface_slow (MonoClass *target, MonoClass *candidate) if (tb && tb->interfaces) { for (j = mono_array_length (tb->interfaces) - 1; j >= 0; --j) { MonoReflectionType *iface = mono_array_get (tb->interfaces, MonoReflectionType*, j); - MonoClass *iface_class = mono_class_from_mono_type (iface->type); + MonoClass *iface_class; + + /* we can't realize the type here since it can do pretty much anything. */ + if (!iface->type) + continue; + iface_class = mono_class_from_mono_type (iface->type); if (iface_class == target) return TRUE; if (is_variant && mono_class_is_variant_compatible_slow (target, iface_class)) @@ -7393,7 +7537,7 @@ mono_class_get_finalizer (MonoClass *klass) if (!klass->inited) mono_class_init (klass); - if (!klass->has_finalize) + if (!mono_class_has_finalizer (klass)) return NULL; if (mono_class_get_cached_class_info (klass, &cached_info)) @@ -7966,7 +8110,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) method++; } while (method < &klass->methods [klass->method.count]) { - if (((*method)->flags & METHOD_ATTRIBUTE_VIRTUAL)) + if (*method && ((*method)->flags & METHOD_ATTRIBUTE_VIRTUAL)) break; method ++; } @@ -8495,13 +8639,19 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in for (i = 0; i < klass->method.count; ++i) { guint32 cols [MONO_METHOD_SIZE]; MonoMethod *method; + MonoMethodSignature *sig; /* class->method.first points into the methodptr table */ mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, klass->method.first + i, cols, MONO_METHOD_SIZE); if (!strcmp (mono_metadata_string_heap (klass->image, cols [MONO_METHOD_NAME]), name)) { method = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass); - if ((param_count == -1) || mono_method_signature (method)->param_count == param_count) { + if (param_count == -1) { + res = method; + break; + } + sig = mono_method_signature (method); + if (sig && sig->param_count == param_count) { res = method; break; } @@ -8872,6 +9022,9 @@ can_access_type (MonoClass *access_klass, MonoClass *member_klass) { int access_level; + if (access_klass->image->assembly && access_klass->image->assembly->corlib_internal) + return TRUE; + if (access_klass->element_class && !access_klass->enumtype) access_klass = access_klass->element_class; @@ -8931,6 +9084,9 @@ static gboolean can_access_member (MonoClass *access_klass, MonoClass *member_klass, MonoClass* context_klass, int access_level) { MonoClass *member_generic_def; + if (access_klass->image->assembly && access_klass->image->assembly->corlib_internal) + return TRUE; + if (((access_klass->generic_class && access_klass->generic_class->container_class) || access_klass->generic_container) && (member_generic_def = get_generic_definition_class (member_klass))) { @@ -8978,11 +9134,11 @@ gboolean mono_method_can_access_field (MonoMethod *method, MonoClassField *field) { /* FIXME: check all overlapping fields */ - int can = can_access_member (method->klass, field->parent, NULL, field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK); + int can = can_access_member (method->klass, field->parent, NULL, mono_field_get_type (field)->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK); if (!can) { MonoClass *nested = method->klass->nested_in; while (nested) { - can = can_access_member (nested, field->parent, NULL, field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK); + can = can_access_member (nested, field->parent, NULL, mono_field_get_type (field)->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK); if (can) return TRUE; nested = nested->nested_in; @@ -9267,7 +9423,6 @@ mono_class_setup_interfaces (MonoClass *klass, MonoError *error) klass->interfaces [i] = mono_class_inflate_generic_class_checked (gklass->interfaces [i], mono_generic_class_get_context (klass->generic_class), error); if (!mono_error_ok (error)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Could not setup the interfaces")); - g_free (klass->interfaces); klass->interfaces = NULL; return; }