Skip to content

Commit

Permalink
[runtime] Thread MonoError through mono_class_get_overrides_full. (mo…
Browse files Browse the repository at this point in the history
…no#6069)

* [runtime] Thread MonoError through mono_class_get_overrides_full.

* [runtime] Use goto_if_nok
  • Loading branch information
kumpera authored and lambdageek committed Dec 6, 2017
1 parent 657ff6d commit b683e10
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 68 deletions.
5 changes: 2 additions & 3 deletions mono/metadata/class-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,9 +956,8 @@ mono_class_get_vtable_size (MonoClass *klass);
gboolean
mono_class_is_open_constructed_type (MonoType *t);

gboolean
mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod ***overrides, gint32 *num_overrides,
MonoGenericContext *generic_context);
void
mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod ***overrides, gint32 *num_overrides, MonoGenericContext *generic_context, MonoError *error);

MonoMethod*
mono_class_get_cctor (MonoClass *klass) MONO_LLVM_INTERNAL;
Expand Down
67 changes: 32 additions & 35 deletions mono/metadata/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -3592,11 +3592,10 @@ static void
mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
{
MonoError error;
MonoMethod **overrides;
MonoMethod **overrides = NULL;
MonoGenericContext *context;
guint32 type_token;
int onum = 0;
gboolean ok = TRUE;

if (klass->vtable)
return;
Expand Down Expand Up @@ -3644,24 +3643,24 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
*/
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_type_load_failure (klass, "Could not load list of method overrides due to %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
return;
goto done;
}
} 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. */
ok = mono_class_get_overrides_full (klass->image, type_token, &overrides, &onum, context);
mono_class_get_overrides_full (klass->image, type_token, &overrides, &onum, context, &error);
if (!is_ok (&error)) {
mono_class_set_type_load_failure (klass, "Could not load list of method overrides due to %s", mono_error_get_message (&error));
goto done;
}
}

if (ok)
mono_class_setup_vtable_general (klass, overrides, onum, in_setup);
else
mono_class_set_type_load_failure (klass, "Could not load list of method overrides");

mono_class_setup_vtable_general (klass, overrides, onum, in_setup);

done:
g_free (overrides);
mono_error_cleanup (&error);

mono_loader_unlock ();
g_list_remove (in_setup, klass);
Expand Down Expand Up @@ -4136,6 +4135,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
GSList *virt_methods = NULL, *l;
int stelemref_slot = 0;

error_init (&error);

if (klass->vtable)
return;

Expand Down Expand Up @@ -4202,11 +4203,7 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
for (i = 0; i < gklass->vtable_size; ++i)
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)) {
mono_class_set_type_load_failure (klass, "Could not inflate method due to %s", mono_error_get_message (&error));
mono_error_cleanup (&error);
return;
}
goto_if_nok (&error, fail);
tmp [i] = inflated;
tmp [i]->slot = gklass->vtable [i]->slot;
}
Expand Down Expand Up @@ -4285,20 +4282,19 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o

MonoMethod **iface_overrides;
int iface_onum;
gboolean ok = mono_class_get_overrides_full (ic->image, ic->type_token, &iface_overrides, &iface_onum, mono_class_get_context (ic));
if (ok) {
for (int i = 0; i < iface_onum; i++) {
MonoMethod *decl = iface_overrides [i*2];
MonoMethod *override = iface_overrides [i*2 + 1];
if (!apply_override (klass, vtable, decl, override))
goto fail;
mono_class_get_overrides_full (ic->image, ic->type_token, &iface_overrides, &iface_onum, mono_class_get_context (ic), &error);
goto_if_nok (&error, fail);
for (int i = 0; i < iface_onum; i++) {
MonoMethod *decl = iface_overrides [i*2];
MonoMethod *override = iface_overrides [i*2 + 1];
if (!apply_override (klass, vtable, decl, override))
goto fail;

if (!override_map)
override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
g_hash_table_insert (override_map, decl, override);
}
g_free (iface_overrides);
if (!override_map)
override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
g_hash_table_insert (override_map, decl, override);
}
g_free (iface_overrides);
}

/* override interface methods */
Expand Down Expand Up @@ -4484,11 +4480,8 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
cmsig = mono_method_signature (cm);
m1sig = mono_method_signature (m1);

if (!cmsig || !m1sig) {
/* FIXME proper error message */
mono_class_set_type_load_failure (klass, "");
return;
}
if (!cmsig || !m1sig) /* FIXME proper error message, use signature_checked? */
goto fail;

if (!strcmp(cm->name, m1->name) &&
mono_metadata_signature_equal (cmsig, m1sig)) {
Expand Down Expand Up @@ -4677,7 +4670,11 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o
fail:
{
char *name = mono_type_get_full_name (klass);
mono_class_set_type_load_failure (klass, "VTable setup of type %s failed", name);
if (!is_ok (&error))
mono_class_set_type_load_failure (klass, "VTable setup of type %s failed due to: %s", name, mono_error_get_message (&error));
else
mono_class_set_type_load_failure (klass, "VTable setup of type %s failed", name);
mono_error_cleanup (&error);
g_free (name);
g_free (vtable);
if (override_map)
Expand Down
56 changes: 26 additions & 30 deletions mono/metadata/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -6262,37 +6262,34 @@ method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *co
/*
* mono_class_get_overrides_full:
*
* Return the method overrides belonging to class @type_token in @overrides, and
* the number of overrides in @num_overrides.
* Compute the method overrides belonging to class @type_token in @overrides, and the number of overrides in @num_overrides.
*
* Returns: TRUE on success, FALSE on failure.
*/
gboolean
mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod ***overrides, gint32 *num_overrides,
MonoGenericContext *generic_context)
void
mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod ***overrides, gint32 *num_overrides, MonoGenericContext *generic_context, MonoError *error)
{
MonoError error;
locator_t loc;
MonoTableInfo *tdef = &image->tables [MONO_TABLE_METHODIMPL];
guint32 start, end;
gint32 i, num;
guint32 cols [MONO_METHODIMPL_SIZE];
MonoMethod **result;
gint32 ok = TRUE;

error_init (error)

*overrides = NULL;
if (num_overrides)
*num_overrides = 0;

if (!tdef->base)
return TRUE;
return;

loc.t = tdef;
loc.col_idx = MONO_METHODIMPL_CLASS;
loc.idx = mono_metadata_token_index (type_token);

if (!mono_binary_search (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
return TRUE;
return;

start = loc.result;
end = start + 1;
Expand All @@ -6316,33 +6313,32 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod
for (i = 0; i < num; ++i) {
MonoMethod *method;

if (!mono_verifier_verify_methodimpl_row (image, start + i, &error)) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
if (!mono_verifier_verify_methodimpl_row (image, start + i, error))
break;
}

mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE);
method = method_from_method_def_or_ref (
image, cols [MONO_METHODIMPL_DECLARATION], generic_context, &error);
if (method == NULL) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
}
method = method_from_method_def_or_ref (image, cols [MONO_METHODIMPL_DECLARATION], generic_context, error);
if (!method)
break;

result [i * 2] = method;
method = method_from_method_def_or_ref (
image, cols [MONO_METHODIMPL_BODY], generic_context, &error);
if (method == NULL) {
mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
}
method = method_from_method_def_or_ref (image, cols [MONO_METHODIMPL_BODY], generic_context, error);
if (!method)
break;

result [i * 2 + 1] = method;
}

*overrides = result;
if (num_overrides)
*num_overrides = num;
return ok;
if (!is_ok (error)) {
g_free (result);
*overrides = NULL;
if (num_overrides)
*num_overrides = 0;
} else {
*overrides = result;
if (num_overrides)
*num_overrides = num;
}
}

/**
Expand Down

0 comments on commit b683e10

Please sign in to comment.