static void mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup);
static void mono_generic_class_setup_parent (MonoClass *klass, MonoClass *gklass);
+static gboolean mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data);
+
+
/*
We use gclass recording to allow recursive system f types to be referenced by a parent.
gpointer exception_data = mono_class_get_exception_data (klass);
switch (mono_class_get_failure(klass)) {
- case MONO_EXCEPTION_TYPE_LOAD: {
- mono_error_set_type_load_class (oerror, klass, "Error Loading class");
- return;
- }
+ case MONO_EXCEPTION_TYPE_LOAD:
case MONO_EXCEPTION_INVALID_PROGRAM: {
MonoErrorBoxed *box = (MonoErrorBoxed*)exception_data;
mono_error_set_from_boxed (oerror, box);
if (gtd) {
mono_class_setup_fields (gtd);
if (mono_class_has_failure (gtd)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
}
if (!klass->parent->size_inited) {
mono_class_setup_fields (klass->parent);
if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
}
if (explicit_size) {
if ((packing_size & 0xffffff00) != 0) {
- char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, packing_size);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load struct '%s' with packing size %d >= 256", klass->name, packing_size);
return;
}
klass->packing_size = packing_size;
field->offset = offset;
if (field->offset == (guint32)-1 && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Missing field layout info for %s", field->name));
+ mono_class_set_type_load_failure (klass, "Missing field layout info for %s", field->name);
break;
}
if (field->offset < -1) { /*-1 is used to encode special static fields */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Invalid negative field offset %d for %s", field->offset, field->name));
+ mono_class_set_type_load_failure (klass, "Invalid negative field offset %d for %s", field->offset, field->name);
break;
}
if (klass->generic_container) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Generic class cannot have explicit layout."));
+ mono_class_set_type_load_failure (klass, "Generic class cannot have explicit layout.");
break;
}
}
if (field_class) {
mono_class_setup_fields (field_class);
if (mono_class_has_failure (field_class)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
break;
}
}
char *class_name = mono_type_get_full_name (klass);
char *type_name = mono_type_full_name (field->type);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
g_warning ("Invalid type %s for instance field %s:%s", type_name, class_name, field->name);
g_free (class_name);
g_free (type_name);
klass->blittable = blittable;
if (klass->enumtype && !mono_class_enum_basetype (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
if (explicit_size && real_size) {
/*valuetypes can't be neither bigger than 1Mb or empty. */
if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject))))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
mono_memory_barrier ();
klass->fields_inited = 1;
if (klass->parent) {
mono_class_setup_fields (klass->parent);
if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
real_size = klass->parent->instance_size;
ftype = mono_type_get_basic_type_from_generic (ftype);
if (type_has_references (klass, ftype)) {
if (field->offset % sizeof (gpointer)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
}
}
// FIXME: Too much code does this
#if 0
if (!MONO_TYPE_IS_REFERENCE (field->type) && ref_bitmap [field->offset / sizeof (gpointer)]) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, field->offset);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, field->offset);
}
#endif
}
continue;
if (mono_type_has_exceptions (field->type)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
break;
}
mono_class_setup_methods (gklass);
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, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ mono_class_set_type_load_failure (klass, "Generic type definition failed to load");
return;
}
gklass->methods [i], klass, mono_class_get_context (klass), &error);
if (!mono_error_ok (&error)) {
char *method = mono_method_full_name (gklass->methods [i], TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not inflate method %s due to %s", method, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not inflate method %s due to %s", method, mono_error_get_message (&error));
g_free (method);
mono_error_cleanup (&error);
int idx = mono_metadata_translate_token_index (klass->image, MONO_TABLE_METHOD, klass->method.first + i + 1);
methods [i] = mono_get_method_checked (klass->image, MONO_TOKEN_METHOD_DEF | idx, klass, NULL, &error);
if (!methods [i]) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not load method %d due to %s", i, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not load method %d due to %s", i, mono_error_get_message (&error));
mono_error_cleanup (&error);
}
}
mono_class_init (gklass);
mono_class_setup_properties (gklass);
if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ mono_class_set_type_load_failure (klass, "Generic type definition failed to load");
return;
}
mono_class_setup_events (gklass);
if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ mono_class_set_type_load_failure (klass, "Generic type definition failed to load");
return;
}
if (count) {
mono_class_setup_methods (klass);
if (mono_class_has_failure (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Generic type definition failed to load"));
+ mono_class_set_type_load_failure (klass, "Generic type definition failed to load");
return;
}
}
ifaces = mono_class_get_implemented_interfaces (k, &error);
if (!mono_error_ok (&error)) {
char *name = mono_type_get_full_name (k);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Error getting the interfaces of %s due to %s", name, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Error getting the interfaces of %s due to %s", name, mono_error_get_message (&error));
g_free (name);
mono_error_cleanup (&error);
cur_slot = -1;
count = count_virtual_methods (ic);
if (count == -1) {
char *name = mono_type_get_full_name (ic);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Error calculating interface offset of %s", name));
+ mono_class_set_type_load_failure (klass, "Error calculating interface offset of %s", name);
g_free (name);
cur_slot = -1;
goto end;
mono_class_setup_vtable_full (mono_class_get_generic_type_definition (klass), in_setup);
if (mono_class_has_failure (klass->generic_class->container_class)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Failed to load generic definition vtable"));
+ mono_class_set_type_load_failure (klass, "Failed to load generic definition vtable");
return FALSE;
}
if (mono_class_has_gtd_parent (klass, arg) || mono_class_has_gtd_parent (arg, klass))
continue;
if (!mono_class_check_vtable_constraints (arg, in_setup)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Failed to load generic parameter %d", i));
+ mono_class_set_type_load_failure (klass, "Failed to load generic parameter %d", i);
return FALSE;
}
}
if (!is_ok (&error)) {
mono_loader_unlock ();
g_list_remove (in_setup, klass);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf(klass->image, "Could not load list of method overrides due to %s", mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not load list of method overrides due to %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
return;
}
if (ok)
mono_class_setup_vtable_general (klass, overrides, onum, in_setup);
else
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not load list of method overrides"));
+ mono_class_set_type_load_failure (klass, "Could not load list of method overrides");
g_free (overrides);
cmsig = mono_method_signature (cm);
imsig = mono_method_signature (im);
if (!cmsig || !imsig) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not resolve the signature of a virtual method"));
+ mono_class_set_type_load_failure (klass, "Could not resolve the signature of a virtual method");
return FALSE;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, im, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
char *decl_name = mono_method_full_name (im, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
return FALSE;
cmsig = mono_method_signature (cm);
imsig = mono_method_signature (im);
if (!cmsig || !imsig) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not resolve the signature of a virtual method"));
+ mono_class_set_type_load_failure (klass, "Could not resolve the signature of a virtual method");
return FALSE;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, im, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
char *decl_name = mono_method_full_name (im, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
return FALSE;
MonoMethod *body = overrides [i * 2 + 1];
if (mono_class_get_generic_type_definition (body->klass) != mono_class_get_generic_type_definition (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method belongs to a different class than the declared one"));
+ mono_class_set_type_load_failure (klass, "Method belongs to a different class than the declared one");
return FALSE;
}
if (!(body->flags & METHOD_ATTRIBUTE_VIRTUAL) || (body->flags & METHOD_ATTRIBUTE_STATIC)) {
if (body->flags & METHOD_ATTRIBUTE_STATIC)
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method must not be static to override a base type"));
+ mono_class_set_type_load_failure (klass, "Method must not be static to override a base type");
else
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method must be virtual to override a base type"));
+ mono_class_set_type_load_failure (klass, "Method must be virtual to override a base type");
return FALSE;
}
if (!(decl->flags & METHOD_ATTRIBUTE_VIRTUAL) || (decl->flags & METHOD_ATTRIBUTE_STATIC)) {
if (body->flags & METHOD_ATTRIBUTE_STATIC)
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Cannot override a static method in a base type"));
+ mono_class_set_type_load_failure (klass, "Cannot override a static method in a base type");
else
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Cannot override a non virtual method in a base type"));
+ mono_class_set_type_load_failure (klass, "Cannot override a non virtual method in a base type");
return FALSE;
}
if (!mono_class_is_assignable_from_slow (decl->klass, klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Method overrides a class or interface that is not extended or implemented by this type"));
+ mono_class_set_type_load_failure (klass, "Method overrides a class or interface that is not extended or implemented by this type");
return FALSE;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (body, decl, NULL)) {
char *body_name = mono_method_full_name (body, TRUE);
char *decl_name = mono_method_full_name (decl, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
return FALSE;
ifaces = mono_class_get_implemented_interfaces (klass, &error);
if (!mono_error_ok (&error)) {
char *name = mono_type_get_full_name (klass);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not resolve %s interfaces due to %s", name, mono_error_get_message (&error)));
+ mono_class_set_type_load_failure (klass, "Could not resolve %s interfaces due to %s", name, mono_error_get_message (&error));
g_free (name);
mono_error_cleanup (&error);
return;
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, mono_image_strdup_printf (klass->image, "Parent %s failed to load", name));
+ mono_class_set_type_load_failure (klass, "Parent %s failed to load", name);
g_free (name);
return;
}
mono_class_setup_vtable_full (gklass, in_setup);
if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
if (gklass->vtable [i]) {
MonoMethod *inflated = mono_class_inflate_generic_method_full_checked (gklass->vtable [i], klass, mono_class_get_context (klass), &error);
if (!mono_error_ok (&error)) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not inflate method due to %s", mono_error_get_message (&error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not inflate method due to %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
return;
}
int dslot;
dslot = mono_method_get_vtable_slot (decl);
if (dslot == -1) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
m1sig = mono_method_signature (m1);
if (!cmsig || !m1sig) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, m1, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
char *decl_name = mono_method_full_name (m1, TRUE);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Method %s overrides method '%s' which is not accessible", body_name, decl_name));
+ mono_class_set_type_load_failure (klass, "Method %s overrides method '%s' which is not accessible", body_name, decl_name);
g_free (body_name);
g_free (decl_name);
goto fail;
if (vtable [i] == NULL || (vtable [i]->flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_STATIC))) {
char *type_name = mono_type_get_full_name (klass);
char *method_name = vtable [i] ? mono_method_full_name (vtable [i], TRUE) : g_strdup ("none");
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Type %s has invalid vtable method slot %d with method %s", type_name, i, method_name));
+ mono_class_set_type_load_failure (klass, "Type %s has invalid vtable method slot %d with method %s", type_name, i, method_name);
g_free (type_name);
g_free (method_name);
return;
fail:
{
char *name = mono_type_get_full_name (klass);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "VTable setup of type %s failed", name));
+ mono_class_set_type_load_failure (klass, "VTable setup of type %s failed", name);
g_free (name);
if (override_map)
g_hash_table_destroy (override_map);
}
if (klass->init_pending) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Recursive type definition detected"));
+ mono_class_set_type_load_failure (klass, "Recursive type definition detected");
goto leave;
}
klass->init_pending = 1;
if (mono_verifier_is_enabled_for_class (klass) && !mono_verifier_verify_class (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, concat_two_strings_with_zero (klass->image, klass->name, klass->image->assembly_name));
+ mono_class_set_type_load_failure (klass, "%s", concat_two_strings_with_zero (klass->image, klass->name, klass->image->assembly_name));
goto leave;
}
if (!element_class->inited)
mono_class_init (element_class);
if (mono_class_has_failure (element_class)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
goto leave;
}
}
if (!mono_class_has_failure (gklass))
mono_class_setup_methods (gklass);
if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Generic Type Defintion failed to init"));
+ mono_class_set_type_load_failure (klass, "Generic Type Defintion failed to init");
goto leave;
}
mono_class_setup_vtable (gklass);
if (mono_class_has_failure (gklass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
goto leave;
}
/* This will compute klass->parent->vtable_size for some classes */
mono_class_init (klass->parent);
if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
goto leave;
}
if (!klass->parent->vtable_size) {
/* FIXME: Get rid of this somehow */
mono_class_setup_vtable (klass->parent);
if (mono_class_has_failure (klass->parent)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
goto leave;
}
}
mono_security_core_clr_check_inheritance (klass);
if (klass->generic_class && !mono_verifier_class_is_valid_generic_instantiation (klass))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Invalid generic instantiation"));
+ mono_class_set_type_load_failure (klass, "Invalid generic instantiation");
goto leave;
/* but it can not be made available for application (i.e. user code) since all COM calls
* are considered native calls. In this case we fail with a TypeLoadException (just like
* Silverlight 2 does */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
return;
}
}
if (!parent) {
/* set the parent to something useful and safe, but mark the type as broken */
parent = mono_defaults.object_class;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "");
}
klass->parent = parent;
static void
mono_class_set_failure_and_error (MonoClass *klass, MonoError *error, const char *msg)
{
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, msg));
+ mono_class_set_type_load_failure (klass, "%s", msg);
mono_error_set_type_load_class (error, klass, "%s", msg);
}
parent = mono_class_inflate_generic_class_checked (parent, context, error);
if (parent == NULL) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
goto parent_failure;
}
klass->nested_in = mono_class_create_from_typedef (image, nesting_tokeen, error);
if (!mono_error_ok (error)) {
/*FIXME implement a mono_class_set_failure_from_mono_error */
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
if (!mono_metadata_interfaces_from_typedef_full (
image, type_token, &interfaces, &icount, FALSE, context, error)){
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
if (!enum_basetype) {
/*set it to a default value as the whole runtime can't handle this to be null*/
klass->cast_class = klass->element_class = mono_defaults.int32_class;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
* work.
*/
if (klass->generic_container && !mono_metadata_load_generic_param_constraints_checked (image, type_token, klass->generic_container, error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup_printf (klass->image, "Could not load generic parameter constrains due to %s", mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "Could not load generic parameter constrains due to %s", mono_error_get_message (error));
mono_loader_unlock ();
mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED);
return NULL;
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_class_set_type_load_failure (klass, "");
mono_error_cleanup (&error);
}
}
if (count - pos > 0) {
mono_class_setup_vtable (klass->parent);
if (mono_class_has_failure (klass->parent))
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Failed to setup parent interfaces"));
+ mono_class_set_type_load_failure (klass, "Failed to setup parent interfaces");
else
setup_interface_offsets (klass, klass->parent->vtable_size, TRUE);
}
if (!eclass->size_inited)
mono_class_setup_fields (eclass);
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);
+ mono_class_set_type_load_failure (klass, "");
klass->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE;
*
* LOCKING: Acquires the loader lock.
*/
-gboolean
+static gboolean
mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data)
{
if (mono_class_has_failure (klass))
return TRUE;
}
+/**
+ * mono_class_set_type_load_failure:
+ * @klass: class in which the failure was detected
+ * @fmt: Printf-style error message string.
+ *
+ * Collect detected failure informaion in the class for later processing.
+ * The error is stored as a MONO_EXCEPTION_TYPE_LOAD failure.
+ * Note that only the first failure is kept.
+ *
+ * Returns FALSE if a failure was already set on the class, or TRUE otherwise.
+ *
+ * LOCKING: Acquires the loader lock.
+ */
+gboolean
+mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...)
+{
+ MonoError prepare_error;
+ va_list args;
+
+ if (mono_class_has_failure (klass))
+ return FALSE;
+
+ mono_error_init (&prepare_error);
+
+ va_start (args, fmt);
+ mono_error_vset_type_load_class (&prepare_error, klass, fmt, args);
+ va_end (args);
+
+ MonoErrorBoxed *box = mono_error_box (&prepare_error, klass->image);
+ mono_error_cleanup (&prepare_error);
+ return mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, box);
+}
+
/*
* mono_class_get_exception_data:
*
gpointer exception_data = mono_class_get_exception_data (klass);
switch (mono_class_get_failure(klass)) {
- case MONO_EXCEPTION_TYPE_LOAD: {
- MonoString *name;
- MonoException *ex;
- char *str = mono_type_get_full_name (klass);
- char *astr = klass->image->assembly? mono_stringify_assembly_name (&klass->image->assembly->aname): NULL;
- name = mono_string_new (mono_domain_get (), str);
- g_free (str);
- ex = mono_get_exception_type_load (name, astr);
- g_free (astr);
- return ex;
- }
case MONO_EXCEPTION_MISSING_METHOD:
case MONO_EXCEPTION_MISSING_FIELD:
case MONO_EXCEPTION_FILE_NOT_FOUND:
case MONO_EXCEPTION_BAD_IMAGE:
g_assert_not_reached ();
+ case MONO_EXCEPTION_TYPE_LOAD:
case MONO_EXCEPTION_INVALID_PROGRAM: {
MonoErrorBoxed *box = (MonoErrorBoxed*)exception_data;
MonoError unboxed_error;
mono_class_setup_interfaces (gklass, error);
if (!mono_error_ok (error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, "Could not setup the interfaces"));
+ mono_class_set_type_load_failure (klass, "Could not setup the interfaces");
return;
}
for (i = 0; i < interface_count; i++) {
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, mono_image_strdup (klass->image, "Could not setup the interfaces"));
+ mono_class_set_type_load_failure (klass, "Could not setup the interfaces");
return;
}
}
MonoClassField *gfield = >d->fields [field_idx];
MonoType *gtype = mono_field_get_type_checked (gfield, error);
if (!mono_error_ok (error)) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
}
field->type = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
if (!mono_error_ok (error)) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
}
} else {
const char *sig;
if (!mono_verifier_verify_field_signature (image, cols [MONO_FIELD_SIGNATURE], NULL)) {
mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);;
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, mono_image_strdup (klass->image, mono_error_get_message (error)));
+ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error));
return;
}
field->type = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
if (!field->type) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ mono_class_set_type_load_failure (klass, "Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
}
}
}