method = imethod->declaring;
}
- if (!method->is_generic && !method->klass->generic_container)
+ /*
+ * A method only needs to be inflated if the context has argument for which it is
+ * parametric. Eg:
+ *
+ * class Foo<T> { void Bar(); } - doesn't need to be inflated if only mvars' are supplied
+ * class Foo { void Bar<T> (); } - doesn't need to be if only vars' are supplied
+ *
+ */
+ if (!((method->is_generic && context->method_inst) ||
+ (method->klass->generic_container && context->class_inst)))
return method;
/*
}
for (i = 0; i < size; ++i) {
MonoMethod *cm = vtable [i];
- if (cm) {
- char *cm_name = mono_method_full_name (cm, TRUE);
- char newness = (i < parent_size) ? 'O' : ((i < first_non_interface_slot) ? 'I' : 'N');
- printf (" [%c][%03d][INDEX %03d] %s\n", newness, i, cm->slot, cm_name);
- g_free (cm_name);
- }
+ char *cm_name = cm ? mono_method_full_name (cm, TRUE) : g_strdup ("nil");
+ char newness = (i < parent_size) ? 'O' : ((i < first_non_interface_slot) ? 'I' : 'N');
+
+ printf (" [%c][%03d][INDEX %03d] %s [%p]\n", newness, i, cm ? cm->slot : - 1, cm_name, cm);
+ g_free (cm_name);
}
g_free (full_name);
if (im->flags & METHOD_ATTRIBUTE_STATIC)
continue;
+ TRACE_INTERFACE_VTABLE (printf ("\tchecking iface method %s\n", mono_method_full_name (im,1)));
+
// If there is an explicit implementation, just use it right away,
// otherwise look for a matching method
if (override_im == NULL) {
g_assert (cm->slot < max_vtsize);
if (!override_map)
override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
+ TRACE_INTERFACE_VTABLE (printf ("adding iface override from %s [%p] to %s [%p]\n",
+ mono_method_full_name (m1, 1), m1,
+ mono_method_full_name (cm, 1), cm));
g_hash_table_insert (override_map, m1, cm);
break;
}
overrides [i * 2 + 1]->slot = decl->slot;
if (!override_map)
override_map = g_hash_table_new (mono_aligned_addr_hash, NULL);
+ TRACE_INTERFACE_VTABLE (printf ("adding explicit override from %s [%p] to %s [%p]\n",
+ mono_method_full_name (decl, 1), decl,
+ mono_method_full_name (overrides [i * 2 + 1], 1), overrides [i * 2 + 1]));
g_hash_table_insert (override_map, decl, overrides [i * 2 + 1]);
if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
* overriden, then change the other occurances too.
*/
if (override_map) {
+ MonoMethod *cm;
+
for (i = 0; i < max_vtsize; ++i)
if (vtable [i]) {
- MonoMethod *cm = g_hash_table_lookup (override_map, vtable [i]);
+ TRACE_INTERFACE_VTABLE (printf ("checking slot %d method %s[%p] for overrides\n", i, mono_method_full_name (vtable [i], 1), vtable [i]));
+
+ cm = g_hash_table_lookup (override_map, vtable [i]);
if (cm)
vtable [i] = cm;
}
int i;
mono_class_setup_fields_locking (klass);
- if (klass->exception_type)
- return 0;
while (klass) {
+ if (!klass->fields)
+ return 0;
for (i = 0; i < klass->field.count; ++i) {
if (&klass->fields [i] == field) {
int idx = klass->field.first + i + 1;
if (!klass->ext->field_def_values [field_index].data) {
cindex = mono_metadata_get_constant_index (field->parent->image, mono_class_get_field_token (field), 0);
- g_assert (cindex);
+ if (!cindex)
+ return NULL;
+
g_assert (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA));
mono_metadata_decode_row (&field->parent->image->tables [MONO_TABLE_CONSTANT], cindex - 1, constant_cols, MONO_CONSTANT_SIZE);
static gboolean
mono_gparam_is_reference_conversible (MonoClass *target, MonoClass *candidate, gboolean check_for_reference_conv)
{
+ if (target == candidate)
+ return TRUE;
+
if (check_for_reference_conv &&
mono_type_is_generic_argument (&target->byval_arg) &&
mono_type_is_generic_argument (&candidate->byval_arg)) {
MonoGenericParam *gparam = candidate->byval_arg.data.generic_param;
MonoGenericParamInfo *pinfo = mono_generic_param_info (gparam);
+
if (!pinfo || (pinfo->flags & GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) == 0)
return FALSE;
}
MonoClass *klass_gtd = mono_class_get_generic_type_definition (klass);
MonoGenericContainer *container = klass_gtd->generic_container;
+ if (klass == oklass)
+ return TRUE;
+
/*Viable candidates are instances of the same generic interface*/
if (mono_class_get_generic_type_definition (oklass) != klass_gtd || oklass == klass_gtd)
return FALSE;
MonoClass *param1_class = mono_class_from_mono_type (klass_argv [j]);
MonoClass *param2_class = mono_class_from_mono_type (oklass_argv [j]);
- if (param1_class->valuetype != param2_class->valuetype)
+ if (param1_class->valuetype != param2_class->valuetype || (param1_class->valuetype && param1_class != param2_class))
return FALSE;
/*