X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fclass.c;h=b6dfce09f9e39ad98a279da4486c2cb0e398fb4b;hb=fd4f3021f2259b2361a6910aab442f4164cab880;hp=75e4451c4111d2c8b9a9e29bccabe3fe53235f64;hpb=61b243e8ca3fd16e1c5eb90435aa726f7a9c1d5f;p=mono.git diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 75e4451c411..b6dfce09f9e 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -7,6 +7,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #ifdef HAVE_ALLOCA_H @@ -285,13 +286,9 @@ mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError done: /* Generic case, should be avoided for when a better error is possible. */ if (!res && mono_error_ok (error)) { - if (mono_loader_get_last_error ()) { /*FIXME plug the above to not leak errors*/ - mono_error_set_from_loader_error (error); - } else { - char *name = mono_class_name_from_token (image, type_token); - char *assembly = mono_assembly_name_from_token (image, type_token); - mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token); - } + char *name = mono_class_name_from_token (image, type_token); + char *assembly = mono_assembly_name_from_token (image, type_token); + mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token); } mono_loader_assert_no_error (); return res; @@ -905,11 +902,7 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context) MonoError error; MonoType *result; result = mono_class_inflate_generic_type_checked (type, context, &error); - - if (!mono_error_ok (&error)) { - mono_error_cleanup (&error); - return NULL; - } + mono_error_cleanup (&error); return result; } @@ -955,6 +948,11 @@ mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoG return inflated; } +/* + * mono_class_inflate_generic_class: + * + * Inflate the class @gklass with @context. Set @error on failure. + */ MonoClass* mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error) { @@ -969,24 +967,6 @@ mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext return res; } -/* - * mono_class_inflate_generic_class: - * - * Inflate the class GKLASS with CONTEXT. - */ -MonoClass* -mono_class_inflate_generic_class (MonoClass *gklass, MonoGenericContext *context) -{ - MonoError error; - MonoClass *res; - - res = mono_class_inflate_generic_class_checked (gklass, context, &error); - g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/ - - return res; -} - - static MonoGenericContext inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with, MonoError *error) @@ -1381,11 +1361,11 @@ mono_type_has_exceptions (MonoType *type) case MONO_TYPE_CLASS: case MONO_TYPE_VALUETYPE: case MONO_TYPE_SZARRAY: - return type->data.klass->exception_type; + return mono_class_has_failure (type->data.klass); case MONO_TYPE_ARRAY: - return type->data.array->eklass->exception_type; + return mono_class_has_failure (type->data.array->eklass); case MONO_TYPE_GENERICINST: - return mono_generic_class_get_class (type->data.generic_class)->exception_type; + return mono_class_has_failure (mono_generic_class_get_class (type->data.generic_class)); default: return FALSE; } @@ -1497,6 +1477,7 @@ mono_class_setup_fields (MonoClass *klass) int i, blittable = TRUE; guint32 real_size = 0; guint32 packing_size = 0; + int instance_size; gboolean explicit_size; MonoClassField *field; MonoGenericContainer *container = NULL; @@ -1566,13 +1547,13 @@ mono_class_setup_fields (MonoClass *klass) if (gtd) { mono_class_setup_fields (gtd); - if (gtd->exception_type) { + if (mono_class_has_failure (gtd)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); return; } } - klass->instance_size = 0; + instance_size = 0; if (!klass->rank) klass->sizes.class_size = 0; @@ -1581,18 +1562,18 @@ mono_class_setup_fields (MonoClass *klass) mono_class_init (klass->parent); if (!klass->parent->size_inited) { mono_class_setup_fields (klass->parent); - if (klass->parent->exception_type) { + if (mono_class_has_failure (klass->parent)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); return; } } - klass->instance_size += klass->parent->instance_size; + instance_size += klass->parent->instance_size; klass->min_align = klass->parent->min_align; /* we use |= since it may have been set already */ klass->has_references |= klass->parent->has_references; blittable = klass->parent->blittable; } else { - klass->instance_size = sizeof (MonoObject); + instance_size = sizeof (MonoObject); klass->min_align = 1; } @@ -1614,14 +1595,16 @@ mono_class_setup_fields (MonoClass *klass) return; } klass->packing_size = packing_size; - real_size += klass->instance_size; + real_size += instance_size; } if (!top) { if (explicit_size && real_size) { - klass->instance_size = MAX (real_size, klass->instance_size); + instance_size = MAX (real_size, instance_size); } klass->blittable = blittable; + if (!klass->instance_size) + klass->instance_size = instance_size; mono_memory_barrier (); klass->size_inited = 1; klass->fields_inited = 1; @@ -1697,7 +1680,7 @@ mono_class_setup_fields (MonoClass *klass) MonoClass *field_class = mono_class_from_mono_type (field->type); if (field_class) { mono_class_setup_fields (field_class); - if (field_class->exception_type) { + if (mono_class_has_failure (field_class)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); break; } @@ -1735,12 +1718,12 @@ mono_class_setup_fields (MonoClass *klass) return; } if (explicit_size && real_size) { - klass->instance_size = MAX (real_size, klass->instance_size); + instance_size = MAX (real_size, instance_size); } - if (klass->exception_type) + if (mono_class_has_failure (klass)) return; - mono_class_layout_fields (klass); + mono_class_layout_fields (klass, instance_size); /*valuetypes can't be neither bigger than 1Mb or empty. */ if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject)))) @@ -1821,6 +1804,7 @@ type_has_references (MonoClass *klass, MonoType *ftype) /* * mono_class_layout_fields: * @class: a class + * @instance_size: base instance size * * Compute the placement of fields inside an object or struct, according to * the layout rules and set the following fields in @class: @@ -1833,7 +1817,7 @@ type_has_references (MonoClass *klass, MonoType *ftype) * LOCKING: this is supposed to be called with the loader lock held. */ void -mono_class_layout_fields (MonoClass *klass) +mono_class_layout_fields (MonoClass *klass, int instance_size) { int i; const int top = klass->field.count; @@ -1914,7 +1898,6 @@ mono_class_layout_fields (MonoClass *klass) /* * Compute field layout and total size (not considering static fields) */ - switch (layout) { case TYPE_ATTRIBUTE_AUTO_LAYOUT: case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT: @@ -1929,7 +1912,7 @@ mono_class_layout_fields (MonoClass *klass) if (klass->parent) { mono_class_setup_fields (klass->parent); - if (klass->parent->exception_type) { + if (mono_class_has_failure (klass->parent)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); return; } @@ -1990,11 +1973,11 @@ mono_class_layout_fields (MonoClass *klass) real_size = field->offset + size; } - klass->instance_size = MAX (real_size, klass->instance_size); + instance_size = MAX (real_size, instance_size); - if (klass->instance_size & (klass->min_align - 1)) { - klass->instance_size += klass->min_align - 1; - klass->instance_size &= ~(klass->min_align - 1); + if (instance_size & (klass->min_align - 1)) { + instance_size += klass->min_align - 1; + instance_size &= ~(klass->min_align - 1); } } break; @@ -2079,10 +2062,10 @@ mono_class_layout_fields (MonoClass *klass) g_free (ref_bitmap); } - klass->instance_size = MAX (real_size, klass->instance_size); - if (klass->instance_size & (klass->min_align - 1)) { - klass->instance_size += klass->min_align - 1; - klass->instance_size &= ~(klass->min_align - 1); + instance_size = MAX (real_size, instance_size); + if (instance_size & (klass->min_align - 1)) { + instance_size += klass->min_align - 1; + instance_size &= ~(klass->min_align - 1); } break; } @@ -2098,11 +2081,17 @@ mono_class_layout_fields (MonoClass *klass) * unaligned accesses otherwise. See #78990 for a testcase. */ if (mono_align_small_structs) { - if (klass->instance_size <= sizeof (MonoObject) + sizeof (gpointer)) - klass->min_align = MAX (klass->min_align, klass->instance_size - sizeof (MonoObject)); + if (instance_size <= sizeof (MonoObject) + sizeof (gpointer)) + klass->min_align = MAX (klass->min_align, instance_size - sizeof (MonoObject)); } } + if (klass->instance_size && !klass->image->dynamic) { + /* Might be already set using cached info */ + g_assert (klass->instance_size == instance_size); + } else { + klass->instance_size = instance_size; + } mono_memory_barrier (); klass->size_inited = 1; @@ -2187,9 +2176,9 @@ mono_class_setup_methods (MonoClass *klass) MonoClass *gklass = klass->generic_class->container_class; mono_class_init (gklass); - if (!gklass->exception_type) + if (!mono_class_has_failure (gklass)) mono_class_setup_methods (gklass); - if (gklass->exception_type) { + if (mono_class_has_failure (gklass)) { /* FIXME make exception_data less opaque so it's possible to dup it here */ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load")); return; @@ -2370,7 +2359,7 @@ mono_class_get_method_by_index (MonoClass *klass, int index) return m; } else { mono_class_setup_methods (klass); - if (klass->exception_type) /*FIXME do proper error handling*/ + if (mono_class_has_failure (klass)) /*FIXME do proper error handling*/ return NULL; g_assert (index >= 0 && index < klass->method.count); return klass->methods [index]; @@ -2392,7 +2381,7 @@ mono_class_get_inflated_method (MonoClass *klass, MonoMethod *method) g_assert (method->klass == gklass); mono_class_setup_methods (gklass); - g_assert (!gklass->exception_type); /*FIXME do proper error handling*/ + g_assert (!mono_class_has_failure (gklass)); /*FIXME do proper error handling*/ for (i = 0; i < gklass->method.count; ++i) { if (gklass->methods [i] == method) { @@ -2441,7 +2430,7 @@ mono_class_get_vtable_entry (MonoClass *klass, int offset) g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */ } else { mono_class_setup_vtable (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return NULL; m = klass->vtable [offset]; } @@ -2487,7 +2476,7 @@ mono_class_setup_properties (MonoClass *klass) mono_class_init (gklass); mono_class_setup_properties (gklass); - if (gklass->exception_type) { + if (mono_class_has_failure (gklass)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load")); return; } @@ -2519,7 +2508,7 @@ mono_class_setup_properties (MonoClass *klass) if (count) { mono_class_setup_methods (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return; } @@ -2620,7 +2609,7 @@ mono_class_setup_events (MonoClass *klass) MonoGenericContext *context = NULL; mono_class_setup_events (gklass); - if (gklass->exception_type) { + if (mono_class_has_failure (gklass)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load")); return; } @@ -2660,7 +2649,7 @@ mono_class_setup_events (MonoClass *klass) if (count) { mono_class_setup_methods (klass); - if (klass->exception_type) { + if (mono_class_has_failure (klass)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load")); return; } @@ -2859,7 +2848,7 @@ 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) { + if (mono_class_has_failure (ic)) { mono_error_set_type_load_class (error, ic, "Error Loading class"); return; } @@ -3294,7 +3283,7 @@ count_virtual_methods (MonoClass *klass) if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)) { mono_class_setup_methods (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return -1; for (i = 0; i < klass->method.count; ++i) { @@ -3762,11 +3751,11 @@ mono_class_check_vtable_constraints (MonoClass *klass, GList *in_setup) int i; if (!klass->generic_class) { mono_class_setup_vtable_full (klass, in_setup); - return klass->exception_type == 0; + return !mono_class_has_failure (klass); } mono_class_setup_vtable_full (mono_class_get_generic_type_definition (klass), in_setup); - if (klass->generic_class->container_class->exception_type) { + if (mono_class_has_failure (klass->generic_class->container_class)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to load generic definition vtable")); return FALSE; } @@ -3809,6 +3798,7 @@ mono_class_setup_vtable (MonoClass *klass) static void mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup) { + MonoError error; MonoMethod **overrides; MonoGenericContext *context; guint32 type_token; @@ -3824,7 +3814,7 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup) return; } - if (klass->exception_type) + if (mono_class_has_failure (klass)) return; if (g_list_find (in_setup, klass)) @@ -3859,7 +3849,14 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup) * This is true since we don't do layout all over again for them, we simply inflate * the layout of the parent. */ - mono_reflection_get_dynamic_overrides (klass, &overrides, &onum); + mono_reflection_get_dynamic_overrides (klass, &overrides, &onum, &error); + if (!is_ok (&error)) { + mono_loader_unlock (); + g_list_remove (in_setup, klass); + mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf("Could not load list of method overrides due to %s", mono_error_get_message (&error))); + mono_error_cleanup (&error); + return; + } } else { /* The following call fails if there are missing methods in the type */ /* FIXME it's probably a good idea to avoid this for generic instances. */ @@ -4218,7 +4215,7 @@ print_unimplemented_interface_method_info (MonoClass *klass, MonoClass *ic, Mono g_free (method_signature); g_free (type_name); mono_class_setup_methods (klass); - if (klass->exception_type) { + if (mono_class_has_failure (klass)) { char *name = mono_type_get_full_name (klass); mono_trace_warning (MONO_TRACE_TYPE, "CLASS %s failed to resolve methods\n", name); g_free (name); @@ -4342,7 +4339,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o mono_class_init (klass->parent); mono_class_setup_vtable_full (klass->parent, in_setup); - if (klass->parent->exception_type) { + if (mono_class_has_failure (klass->parent)) { char *name = mono_type_get_full_name (klass->parent); mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Parent %s failed to load", name)); g_free (name); @@ -4381,7 +4378,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o MonoMethod **tmp; mono_class_setup_vtable_full (gklass, in_setup); - if (gklass->exception_type != MONO_EXCEPTION_NONE) { + if (mono_class_has_failure (gklass)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); return; } @@ -4437,7 +4434,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o mono_class_setup_methods (parent_interface); /*FIXME Just kill this whole chunk of dead code*/ TRACE_INTERFACE_VTABLE (printf (" +++ Inheriting interface %s.%s\n", parent_interface->name_space, parent_interface->name)); - for (j = 0; j < parent_interface->method.count && !klass->exception_type; j++) { + for (j = 0; j < parent_interface->method.count && !mono_class_has_failure (klass); j++) { vtable [interface_offset + j] = parent->vtable [parent_interface_offset + j]; TRACE_INTERFACE_VTABLE (printf (" --- Inheriting: [%03d][(%03d)+(%03d)] => [%03d][(%03d)+(%03d)]\n", parent_interface_offset + j, parent_interface_offset, j, @@ -4499,7 +4496,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o while ((cm = mono_class_get_virtual_methods (klass, &iter))) { virt_methods = g_slist_prepend (virt_methods, cm); } - if (klass->exception_type) + if (mono_class_has_failure (klass)) goto fail; } @@ -4514,7 +4511,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o ic_offset = mono_class_interface_offset (klass, ic); mono_class_setup_methods (ic); - if (ic->exception_type) + if (mono_class_has_failure (ic)) goto fail; // Check if this interface is explicitly implemented (instead of just inherited) @@ -4561,7 +4558,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o } } TRACE_INTERFACE_VTABLE (printf ("\n")); - if (klass->exception_type) /*Might be set by check_interface_method_override*/ + if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/ goto fail; } @@ -4582,7 +4579,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o } break; } - if (klass->exception_type) /*Might be set by check_interface_method_override*/ + if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/ goto fail; TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("\n")); } @@ -4677,7 +4674,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o break; } } - if (k->exception_type) + if (mono_class_has_failure (k)) goto fail; if (slot >= 0) @@ -4852,7 +4849,7 @@ mono_method_get_vtable_slot (MonoMethod *method) { if (method->slot == -1) { mono_class_setup_vtable (method->klass); - if (method->klass->exception_type) + if (mono_class_has_failure (method->klass)) return -1; if (method->slot == -1) { MonoClass *gklass; @@ -4948,7 +4945,7 @@ generic_array_methods (MonoClass *klass) if (generic_array_method_num) return generic_array_method_num; mono_class_setup_methods (klass->parent); /*This is setting up System.Array*/ - g_assert (!klass->parent->exception_type); /*So hitting this assert is a huge problem*/ + g_assert (!mono_class_has_failure (klass->parent)); /*So hitting this assert is a huge problem*/ for (i = 0; i < klass->parent->method.count; i++) { MonoMethod *m = klass->parent->methods [i]; if (!strncmp (m->name, "InternalArray__", 15)) { @@ -5108,18 +5105,18 @@ mono_class_init (MonoClass *klass) g_assert (klass); /* Double-checking locking pattern */ - if (klass->inited || klass->exception_type) - return klass->exception_type == MONO_EXCEPTION_NONE; + if (klass->inited || mono_class_has_failure (klass)) + return !mono_class_has_failure (klass); /*g_print ("Init class %s\n", mono_type_get_full_name (klass));*/ /* We do everything inside the lock to prevent races */ mono_loader_lock (); - if (klass->inited || klass->exception_type) { + if (klass->inited || mono_class_has_failure (klass)) { mono_loader_unlock (); /* Somebody might have gotten in before us */ - return klass->exception_type == MONO_EXCEPTION_NONE; + return !mono_class_has_failure (klass); } if (klass->init_pending) { @@ -5139,7 +5136,7 @@ mono_class_init (MonoClass *klass) MonoClass *element_class = klass->element_class; if (!element_class->inited) mono_class_init (element_class); - if (element_class->exception_type != MONO_EXCEPTION_NONE) { + if (mono_class_has_failure (element_class)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); goto leave; } @@ -5157,9 +5154,9 @@ mono_class_init (MonoClass *klass) mono_class_init (gklass); // FIXME: Why is this needed ? - if (!gklass->exception_type) + if (!mono_class_has_failure (gklass)) mono_class_setup_methods (gklass); - if (gklass->exception_type) { + if (mono_class_has_failure (gklass)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Generic Type Defintion failed to init")); goto leave; } @@ -5192,7 +5189,7 @@ mono_class_init (MonoClass *klass) else if (!klass->size_inited){ mono_class_setup_fields (klass); - if (klass->exception_type || mono_loader_get_last_error ()) + if (mono_class_has_failure (klass) || mono_loader_get_last_error ()) goto leave; } @@ -5246,7 +5243,7 @@ mono_class_init (MonoClass *klass) klass->has_cctor = gklass->has_cctor; mono_class_setup_vtable (gklass); - if (gklass->exception_type) { + if (mono_class_has_failure (gklass)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); goto leave; } @@ -5278,7 +5275,7 @@ mono_class_init (MonoClass *klass) klass->has_cctor = 1; } else { mono_class_setup_methods (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) goto leave; for (i = 0; i < klass->method.count; ++i) { @@ -5297,7 +5294,7 @@ mono_class_init (MonoClass *klass) int first_iface_slot; /* This will compute klass->parent->vtable_size for some classes */ mono_class_init (klass->parent); - if (klass->parent->exception_type) { + if (mono_class_has_failure (klass->parent)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); goto leave; } @@ -5306,7 +5303,7 @@ mono_class_init (MonoClass *klass) if (!klass->parent->vtable_size) { /* FIXME: Get rid of this somehow */ mono_class_setup_vtable (klass->parent); - if (klass->parent->exception_type) { + if (mono_class_has_failure (klass->parent)) { mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); goto leave; } @@ -5325,7 +5322,7 @@ mono_class_init (MonoClass *klass) mono_security_core_clr_check_inheritance (klass); if (mono_loader_get_last_error ()) { - if (klass->exception_type == MONO_EXCEPTION_NONE) { + if (!mono_class_has_failure (klass)) { set_failure_from_loader_error (klass, mono_loader_get_last_error ()); } mono_loader_clear_error (); @@ -5344,7 +5341,7 @@ mono_class_init (MonoClass *klass) mono_loader_unlock (); - return klass->exception_type == MONO_EXCEPTION_NONE; + return !mono_class_has_failure (klass); } /* @@ -5379,7 +5376,7 @@ mono_class_has_finalizer (MonoClass *klass) * ignores overrides. */ mono_class_setup_vtable (klass); - if (klass->exception_type || mono_loader_get_last_error ()) + if (mono_class_has_failure (klass) || mono_loader_get_last_error ()) cmethod = NULL; else cmethod = klass->vtable [finalize_slot]; @@ -5734,22 +5731,6 @@ mono_class_set_failure_and_error (MonoClass *klass, MonoError *error, const char mono_error_set_type_load_class (error, klass, msg); } -static void -mono_class_set_failure_from_loader_error (MonoClass *klass, MonoError *error, char *msg) -{ - MonoLoaderError *lerror = mono_loader_get_last_error (); - - if (lerror) { - set_failure_from_loader_error (klass, lerror); - mono_error_set_from_loader_error (error); - if (msg) - g_free (msg); - } else { - mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, msg); - mono_error_set_type_load_class (error, klass, msg); - } -} - /** * mono_class_create_from_typedef: * @image: image where the token is valid @@ -6261,7 +6242,7 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo) if (count - pos > 0) { mono_class_setup_vtable (klass->parent); - if (klass->parent->exception_type) + if (mono_class_has_failure (klass->parent)) 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, TRUE); @@ -6780,7 +6761,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) { /*Arrays of those two types are invalid.*/ - mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); + mono_class_set_failure (klass, MONO_EXCEPTION_INVALID_PROGRAM, NULL); } else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) { if (!eclass->ref_info_handle || eclass->wastypebuilder) { g_warning ("Only incomplete TypeBuilder objects are allowed to be an enum without base_type"); @@ -6797,7 +6778,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) mono_class_init (eclass); if (!eclass->size_inited) mono_class_setup_fields (eclass); - if (eclass->exception_type) /*FIXME we fail the array type, but we have to let other fields be set.*/ + if (mono_class_has_failure (eclass)) /*FIXME we fail the array type, but we have to let other fields be set.*/ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); klass->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE; @@ -6985,7 +6966,7 @@ static MonoClassField * mono_class_get_field_idx (MonoClass *klass, int idx) { mono_class_setup_fields_locking (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return NULL; while (klass) { @@ -7067,7 +7048,7 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp int i; mono_class_setup_fields_locking (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return NULL; while (klass) { @@ -7473,7 +7454,7 @@ mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error) mono_error_set_bad_image (error, image,"Bad token table for dynamic image: %x", table); return NULL; } - klass = (MonoClass *)mono_lookup_dynamic_token (image, type_token, NULL); /*FIXME proper error handling*/ + klass = (MonoClass *)mono_lookup_dynamic_token (image, type_token, NULL, error); goto done; } @@ -7523,8 +7504,11 @@ mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext mono_error_init (error); //FIXME: this will not fix the very issue for which mono_type_get_full exists -but how to do it then? - if (image_is_dynamic (image)) - return mono_class_get_type ((MonoClass *)mono_lookup_dynamic_token (image, type_token, context)); + if (image_is_dynamic (image)) { + MonoClass *klass = (MonoClass *)mono_lookup_dynamic_token (image, type_token, context, error); + return_val_if_nok (error, NULL); + return mono_class_get_type (klass); + } if ((type_token & 0xff000000) != MONO_TOKEN_TYPE_SPEC) { MonoClass *klass = mono_class_get_checked (image, type_token, error); @@ -7733,7 +7717,8 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char { MonoError error; MonoClass *res = mono_class_from_name_case_checked (image, name_space, name, &error); - g_assert (!mono_error_ok (&error)); + mono_error_cleanup (&error); + return res; } @@ -7836,13 +7821,15 @@ return_nested_in (MonoClass *klass, char *nested) } static MonoClass* -search_modules (MonoImage *image, const char *name_space, const char *name) +search_modules (MonoImage *image, const char *name_space, const char *name, MonoError *error) { MonoTableInfo *file_table = &image->tables [MONO_TABLE_FILE]; MonoImage *file_image; MonoClass *klass; int i; + mono_error_init (error); + /* * The EXPORTEDTYPES table only contains public types, so have to search the * modules as well. @@ -7857,8 +7844,8 @@ search_modules (MonoImage *image, const char *name_space, const char *name) file_image = mono_image_load_file_for_image (image, i + 1); if (file_image) { - klass = mono_class_from_name (file_image, name_space, name); - if (klass) + klass = mono_class_from_name_checked (file_image, name_space, name, error); + if (klass || !is_ok (error)) return klass; } } @@ -7867,7 +7854,7 @@ search_modules (MonoImage *image, const char *name_space, const char *name) } static MonoClass * -mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, GHashTable* visited_images) +mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, GHashTable* visited_images, MonoError *error) { GHashTable *nspace_table; MonoImage *loaded_image; @@ -7900,8 +7887,11 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons if (get_class_from_name && image->tables [MONO_TABLE_EXPORTEDTYPE].rows == 0) { gboolean res = get_class_from_name (image, name_space, name, &klass); if (res) { - if (!klass) - klass = search_modules (image, name_space, name); + if (!klass) { + klass = search_modules (image, name_space, name, error); + if (!is_ok (error)) + return NULL; + } if (nested) return klass ? return_nested_in (klass, nested) : NULL; else @@ -7924,15 +7914,15 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons for (i = 0; i < image->module_count; ++i) { MonoImage *module = image->modules [i]; - klass = mono_class_from_name (module, name_space, name); - if (klass) + klass = mono_class_from_name_checked (module, name_space, name, error); + if (klass || !is_ok (error)) return klass; } } if (!token) { - klass = search_modules (image, name_space, name); - if (klass) + klass = search_modules (image, name_space, name, error); + if (klass || !is_ok (error)) return klass; } @@ -7953,7 +7943,7 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons loaded_image = mono_assembly_load_module (image->assembly, impl >> MONO_IMPLEMENTATION_BITS); if (!loaded_image) return NULL; - klass = mono_class_from_name_checked_aux (loaded_image, name_space, name, error, visited_images); + klass = mono_class_from_name_checked_aux (loaded_image, name_space, name, visited_images, error); if (nested) return klass ? return_nested_in (klass, nested) : NULL; return klass; @@ -7966,9 +7956,9 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons g_assert (image->references [assembly_idx - 1]); if (image->references [assembly_idx - 1] == (gpointer)-1) return NULL; - klass = mono_class_from_name_checked_aux (image->references [assembly_idx - 1]->image, name_space, name, error, visited_images); + klass = mono_class_from_name_checked_aux (image->references [assembly_idx - 1]->image, name_space, name, visited_images, error); if (nested) - return return_nested_in (klass, nested); + return klass ? return_nested_in (klass, nested) : NULL; return klass; } else { g_assert_not_reached (); @@ -8003,7 +7993,7 @@ mono_class_from_name_checked (MonoImage *image, const char* name_space, const ch visited_images = g_hash_table_new (g_direct_hash, g_direct_equal); - klass = mono_class_from_name_checked_aux (image, name_space, name, error, visited_images); + klass = mono_class_from_name_checked_aux (image, name_space, name, visited_images, error); g_hash_table_destroy (visited_images); @@ -8030,10 +8020,8 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name MonoClass *klass; klass = mono_class_from_name_checked (image, name_space, name, &error); - if (!mono_error_ok (&error)) { - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); /* FIXME Don't swallow the error */ - } + mono_error_cleanup (&error); /* FIXME Don't swallow the error */ + return klass; } @@ -8346,6 +8334,7 @@ mono_gparam_is_assignable_from (MonoClass *target, MonoClass *candidate) gboolean mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) { + MonoError error; /*FIXME this will cause a lot of irrelevant stuff to be loaded.*/ if (!klass->inited) mono_class_init (klass); @@ -8353,7 +8342,7 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) if (!oklass->inited) mono_class_init (oklass); - if (klass->exception_type || oklass->exception_type) + if (mono_class_has_failure (klass) || mono_class_has_failure (oklass)) return FALSE; if (mono_type_is_generic_argument (&klass->byval_arg)) { @@ -8379,12 +8368,18 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) } /* interface_offsets might not be set for dynamic classes */ - if (oklass->ref_info_handle && !oklass->interface_bitmap) + if (oklass->ref_info_handle && !oklass->interface_bitmap) { /* * oklass might be a generic type parameter but they have * interface_offsets set. */ - return mono_reflection_call_is_assignable_to (oklass, klass); + gboolean result = mono_reflection_call_is_assignable_to (oklass, klass, &error); + if (!is_ok (&error)) { + mono_error_cleanup (&error); + return FALSE; + } + return result; + } if (!oklass->interface_bitmap) /* Happens with generic instances of not-yet created dynamic types */ return FALSE; @@ -8392,7 +8387,6 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) return TRUE; if (mono_class_has_variant_generic_params (klass)) { - MonoError error; int i; mono_class_setup_interfaces (oklass, &error); if (!mono_error_ok (&error)) { @@ -8789,8 +8783,9 @@ mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class, if (image_is_dynamic (image)) { MonoClass *tmp_handle_class; - gpointer obj = mono_lookup_dynamic_token_class (image, token, TRUE, &tmp_handle_class, context); + gpointer obj = mono_lookup_dynamic_token_class (image, token, TRUE, &tmp_handle_class, context, error); + mono_error_assert_ok (error); g_assert (tmp_handle_class); if (handle_class) *handle_class = tmp_handle_class; @@ -8870,30 +8865,18 @@ mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class, return NULL; } -/** - * This function might need to call runtime functions so it can't be part - * of the metadata library. - */ -static MonoLookupDynamicToken lookup_dynamic = NULL; - -void -mono_install_lookup_dynamic_token (MonoLookupDynamicToken func) -{ - lookup_dynamic = func; -} - gpointer -mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context) +mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error) { MonoClass *handle_class; - - return lookup_dynamic (image, token, TRUE, &handle_class, context); + mono_error_init (error); + return mono_reflection_lookup_dynamic_token (image, token, TRUE, &handle_class, context, error); } gpointer -mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context) +mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error) { - return lookup_dynamic (image, token, valid_token, handle_class, context); + return mono_reflection_lookup_dynamic_token (image, token, valid_token, handle_class, context, error); } static MonoGetCachedClassInfo get_cached_class_info = NULL; @@ -9185,7 +9168,7 @@ mono_class_get_fields (MonoClass* klass, gpointer *iter) return NULL; if (!*iter) { mono_class_setup_fields_locking (klass); - if (klass->exception_type) + if (mono_class_has_failure (klass)) return NULL; /* start from the first */ if (klass->field.count) { @@ -9974,7 +9957,7 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p gboolean mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data) { - if (klass->exception_type) + if (mono_class_has_failure (klass)) return FALSE; mono_loader_lock (); @@ -10048,7 +10031,7 @@ mono_class_get_exception_for_failure (MonoClass *klass) { gpointer exception_data = mono_class_get_exception_data (klass); - switch (klass->exception_type) { + switch (mono_class_get_failure(klass)) { case MONO_EXCEPTION_TYPE_LOAD: { MonoString *name; MonoException *ex; @@ -10087,18 +10070,12 @@ mono_class_get_exception_for_failure (MonoClass *klass) case MONO_EXCEPTION_BAD_IMAGE: { return mono_get_exception_bad_image_format ((const char *)exception_data); } + case MONO_EXCEPTION_INVALID_PROGRAM: { + return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", ""); + } default: { - MonoLoaderError *error; - MonoException *ex; - - error = mono_loader_get_last_error (); - if (error != NULL){ - ex = mono_loader_error_prepare_exception (error); - return ex; - } - /* TODO - handle other class related failures */ - return NULL; + return mono_get_exception_execution_engine ("Unknown class failure"); } } }