}
/* FIXME: This needs a cache, especially for generic instances, since
- * mono_metadata_parse_type () allocates everything from a mempool.
+ * we ask mono_metadata_parse_type_checked () to allocates everything from a mempool.
+ * FIXME part2, mono_metadata_parse_type_checked actually allows for a transient type instead.
+ * FIXME part3, transient types are not 100% transient, so we need to take care of that first.
*/
sig_type = (MonoType *)find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]);
if (!sig_type) {
- sig_type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ MonoError inner_error;
+ sig_type = mono_metadata_parse_type_checked (image, NULL, 0, FALSE, ptr, &ptr, &inner_error);
if (sig_type == NULL) {
- mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x", fname, token);
+ mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x due to: %s", fname, token, mono_error_get_message (&inner_error));
+ mono_error_cleanup (&inner_error);
return NULL;
}
sig_type = (MonoType *)cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type);
/*
* mono_field_from_token:
* @deprecated use the _checked variant
+ * Notes: runtime code MUST not use this function
*/
MonoClassField*
mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, MonoGenericContext *context)
{
MonoError error;
MonoClassField *res = mono_field_from_token_checked (image, token, retklass, context, &error);
- mono_loader_assert_no_error ();
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error);
- }
+ g_assert (mono_error_ok (&error));
return res;
}
See mono/tests/generic-type-load-exception.2.il
FIXME we should better report this error to the caller
*/
- if (!klass->methods || klass->exception_type) {
+ if (!klass->methods || mono_class_has_failure (klass)) {
mono_error_set_type_load_class (error, klass, "Could not find method due to a type load error"); //FIXME get the error from the class
return NULL;
}
static MonoMethodHeader*
-inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
+inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context, MonoError *error)
{
MonoMethodHeader *res;
int i;
res->init_locals = header->init_locals;
res->num_locals = header->num_locals;
res->clauses = header->clauses;
- for (i = 0; i < header->num_locals; ++i)
- res->locals [i] = mono_class_inflate_generic_type (header->locals [i], context);
+
+ mono_error_init (error);
+
+ for (i = 0; i < header->num_locals; ++i) {
+ res->locals [i] = mono_class_inflate_generic_type_checked (header->locals [i], context, error);
+ if (!is_ok (error))
+ goto fail;
+ }
if (res->num_clauses) {
res->clauses = (MonoExceptionClause *)g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses);
for (i = 0; i < header->num_clauses; ++i) {
MonoExceptionClause *clause = &res->clauses [i];
if (clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
continue;
- clause->data.catch_class = mono_class_inflate_generic_class (clause->data.catch_class, context);
+ clause->data.catch_class = mono_class_inflate_generic_class_checked (clause->data.catch_class, context, error);
+ if (!is_ok (error))
+ goto fail;
}
}
return res;
+fail:
+ g_free (res);
+ return NULL;
}
/*
* token is the method_ref/def/spec token used in a call IL instruction.
+ * @deprecated use the _checked variant
+ * Notes: runtime code MUST not use this function
*/
MonoMethodSignature*
mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context)
{
MonoError error;
MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, context, &error);
-
- mono_loader_assert_no_error ();
-
- if (!res) {
- g_assert (!mono_error_ok (&error));
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /* FIXME Don't swallow the error */
- }
+ g_assert (mono_error_ok (&error));
return res;
}
if (table == MONO_TABLE_METHODSPEC) {
/* the verifier (do_invoke_method) will turn the NULL into a verifier error */
- if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated)
+ if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated) {
+ mono_error_set_bad_image (error, image, "Method is a pinvoke or open generic");
return NULL;
+ }
return mono_method_signature_checked (method, error);
}
return sig;
}
+/*
+ * token is the method_ref/def/spec token used in a call IL instruction.
+ * @deprecated use the _checked variant
+ * Notes: runtime code MUST not use this function
+ */
MonoMethodSignature*
mono_method_get_signature (MonoMethod *method, MonoImage *image, guint32 token)
{
MonoError error;
MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, NULL, &error);
-
- mono_loader_assert_no_error ();
-
- if (!res) {
- g_assert (!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);
return res;
}
int i;
mono_class_setup_methods (klass);
- g_assert (!klass->exception_type); /*FIXME this should not fail, right?*/
+ g_assert (!mono_class_has_failure (klass)); /*FIXME this should not fail, right?*/
for (i = 0; i < klass->method.count; ++i) {
MonoMethod *method = klass->methods [i];
if (strcmp (method->name, name) == 0 && sig->param_count == method->signature->param_count)
MonoMethod *
mono_get_method (MonoImage *image, guint32 token, MonoClass *klass)
{
- return mono_get_method_full (image, token, klass, NULL);
+ MonoError error;
+ MonoMethod *result = mono_get_method_checked (image, token, klass, NULL, &error);
+ mono_error_cleanup (&error);
+ return result;
}
MonoMethod *
{
MonoError error;
MonoMethod *result = mono_get_method_checked (image, token, klass, context, &error);
- mono_loader_assert_no_error ();
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error);
- }
+ mono_error_cleanup (&error);
return result;
}
{
MonoError error;
MonoMethod *result = mono_get_method_constrained_checked (image, token, constrained_class, context, cil_method, &error);
-
- mono_loader_assert_no_error ();
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error);
- }
+ mono_error_cleanup (&error);
return result;
}
MonoMethodHeader*
mono_method_get_header (MonoMethod *method)
{
+ MonoError error;
int idx;
guint32 rva;
MonoImage* img;
if (!header)
return NULL;
- iheader = inflate_generic_header (header, mono_method_get_context (method));
+ iheader = inflate_generic_header (header, mono_method_get_context (method), &error);
mono_metadata_free_mh (header);
+ if (!iheader) {
+ mono_loader_set_error_from_mono_error (&error);
+ return NULL;
+ }
mono_image_lock (img);
container = mono_method_get_generic_container (method);
if (!container)
container = method->klass->generic_container;
- header = mono_metadata_parse_mh_full (img, container, (const char *)loc);
+ header = mono_metadata_parse_mh_full (img, container, (const char *)loc, &error);
+ if (!header)
+ mono_loader_set_error_from_mono_error (&error);
return header;
}
return mono_metadata_token_index (method->token);
mono_class_setup_methods (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return 0;
for (i = 0; i < klass->method.count; ++i) {
if (method == klass->methods [i]) {