- for (im_index = 0; im_index < ic->method.count; im_index++) {
- MonoMethod *im = ic->methods [im_index];
- int im_slot = ic_offset + im->slot;
-
- if (im->flags & METHOD_ATTRIBUTE_STATIC)
- continue;
-
- TRACE_INTERFACE_VTABLE (printf (" [class is not abstract, checking slot %d for interface '%s'.'%s', method %s, slot check is %d]\n",
- im_slot, ic->name_space, ic->name, im->name, (vtable [im_slot] == NULL)));
- if (vtable [im_slot] == NULL) {
- print_unimplemented_interface_method_info (class, ic, im, im_slot, overrides, onum);
- mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
- if (override_map)
- g_hash_table_destroy (override_map);
- return;
- }
- }
- }
- }
- } else {
- for (k = class; k ; k = k->parent) {
- int nifaces = 0;
-
- ifaces = mono_class_get_implemented_interfaces (k);
- if (ifaces) {
- nifaces = ifaces->len;
- if (k->generic_class) {
- pifaces = mono_class_get_implemented_interfaces (
- k->generic_class->container_class);
- g_assert (pifaces && (pifaces->len == nifaces));
- }
- }
- for (i = 0; i < nifaces; i++) {
- MonoClass *pic = NULL;
- int j, l, io;
-
- ic = g_ptr_array_index (ifaces, i);
- if (pifaces)
- pic = g_ptr_array_index (pifaces, i);
- g_assert (ic->interface_id <= k->max_interface_id);
- io = mono_class_interface_offset (k, ic);
-
- g_assert (io >= 0);
- g_assert (io <= max_vtsize);
-
- if (k == class) {
- mono_class_setup_methods (ic);
- for (l = 0; l < ic->method.count; l++) {
- MonoMethod *im = ic->methods [l];
-
- if (vtable [io + l] && !(vtable [io + l]->flags & METHOD_ATTRIBUTE_ABSTRACT))
- continue;
-
- for (j = 0; j < class->method.count; ++j) {
- MonoMethod *cm = class->methods [j];
- if (!(cm->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
- !((cm->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) ||
- !(cm->flags & METHOD_ATTRIBUTE_NEW_SLOT))
- continue;
- if (!strcmp(cm->name, im->name) &&
- mono_metadata_signature_equal (mono_method_signature (cm), mono_method_signature (im))) {
-
- /* CAS - SecurityAction.InheritanceDemand on interface */
- if (security_enabled && (im->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
- mono_secman_inheritancedemand_method (cm, im);
- }
-
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
- check_core_clr_override_method (class, cm, im);
-
- g_assert (io + l <= max_vtsize);
- vtable [io + l] = cm;
- TRACE_INTERFACE_VTABLE (printf (" [NOA] Filling slot %d (%d+%d) with method '%s'.'%s':'%s' ", io + l, io, l, cm->klass->name_space, cm->klass->name, cm->name));
- TRACE_INTERFACE_VTABLE (print_method_signatures (im, cm));
- TRACE_INTERFACE_VTABLE (printf ("\n"));
- }
- }
- }
- } else {
- /* already implemented */
- if (io >= k->vtable_size)
- continue;
- }
-
- // Override methods with the same fully qualified name
- for (l = 0; l < ic->method.count; l++) {
- MonoMethod *im = ic->methods [l];
- char *qname, *fqname, *cname, *the_cname;
- MonoClass *k1;
-
- if (vtable [io + l])
- continue;
-
- if (pic) {
- the_cname = mono_type_get_name_full (&pic->byval_arg, MONO_TYPE_NAME_FORMAT_IL);
- cname = the_cname;
- } else {
- the_cname = NULL;
- cname = (char*)ic->name;
- }
-
- qname = g_strconcat (cname, ".", im->name, NULL);
- if (ic->name_space && ic->name_space [0])
- fqname = g_strconcat (ic->name_space, ".", cname, ".", im->name, NULL);
- else
- fqname = NULL;
-
- for (k1 = class; k1; k1 = k1->parent) {
- for (j = 0; j < k1->method.count; ++j) {
- MonoMethod *cm = k1->methods [j];
-
- if (!(cm->flags & METHOD_ATTRIBUTE_VIRTUAL))
- continue;
-
- if (((fqname && !strcmp (cm->name, fqname)) || !strcmp (cm->name, qname)) &&
- mono_metadata_signature_equal (mono_method_signature (cm), mono_method_signature (im)) &&
- ((vtable [io + l] == NULL) || mono_class_is_subclass_of (cm->klass, vtable [io + l]->klass, FALSE))) {
-
- /* CAS - SecurityAction.InheritanceDemand on interface */
- if (security_enabled && (im->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
- mono_secman_inheritancedemand_method (cm, im);
- }
-
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
- check_core_clr_override_method (class, cm, im);
-
- g_assert (io + l <= max_vtsize);
- vtable [io + l] = cm;
- TRACE_INTERFACE_VTABLE (printf (" [FQN] Filling slot %d (%d+%d) with method '%s'.'%s':'%s' ", io + l, io, l, cm->klass->name_space, cm->klass->name, cm->name));
- TRACE_INTERFACE_VTABLE (print_method_signatures (im, cm));
- TRACE_INTERFACE_VTABLE (printf ("\n"));
- break;
- }
- }
- }
- g_free (the_cname);
- g_free (qname);
- g_free (fqname);
- }
-
- // Override methods with the same name
- for (l = 0; l < ic->method.count; l++) {
- MonoMethod *im = ic->methods [l];
- MonoClass *k1;
-
- g_assert (io + l <= max_vtsize);
-
- if (vtable [io + l] && !(vtable [io + l]->flags & METHOD_ATTRIBUTE_ABSTRACT))
- continue;
-
- for (k1 = class; k1; k1 = k1->parent) {
- for (j = 0; j < k1->method.count; ++j) {
- MonoMethod *cm = k1->methods [j];
-
- if (!(cm->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
- !(cm->flags & METHOD_ATTRIBUTE_PUBLIC))
- continue;
-
- if (!strcmp(cm->name, im->name) &&
- mono_metadata_signature_equal (mono_method_signature (cm), mono_method_signature (im))) {
-
- /* CAS - SecurityAction.InheritanceDemand on interface */
- if (security_enabled && (im->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
- mono_secman_inheritancedemand_method (cm, im);
- }
-
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
- check_core_clr_override_method (class, cm, im);
-
- g_assert (io + l <= max_vtsize);
- vtable [io + l] = cm;
- TRACE_INTERFACE_VTABLE (printf (" [SQN] Filling slot %d (%d+%d) with method '%s'.'%s':'%s' ", io + l, io, l, cm->klass->name_space, cm->klass->name, cm->name));
- TRACE_INTERFACE_VTABLE (print_method_signatures (im, cm));
- TRACE_INTERFACE_VTABLE (printf ("\n"));
- break;
- }
-
- }
- g_assert (io + l <= max_vtsize);
- if (vtable [io + l] && !(vtable [io + l]->flags & METHOD_ATTRIBUTE_ABSTRACT))
- break;
- }
- }
-
- if (!(class->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
- for (l = 0; l < ic->method.count; l++) {
- char *msig;
- MonoMethod *im = ic->methods [l];
- if (im->flags & METHOD_ATTRIBUTE_STATIC)
- continue;
- g_assert (io + l <= max_vtsize);
-
- /*
- * If one of our parents already implements this interface
- * we can inherit the implementation.
- */
- if (!(vtable [io + l])) {
- MonoClass *parent = class->parent;
-
- for (; parent; parent = parent->parent) {
- if (MONO_CLASS_IMPLEMENTS_INTERFACE (parent, ic->interface_id) &&
- parent->vtable) {
- vtable [io + l] = parent->vtable [mono_class_interface_offset (parent, ic) + l];
- TRACE_INTERFACE_VTABLE (printf (" [INH] Filling slot %d (%d+%d) with method '%s'.'%s':'%s'\n", io + l, io, l, vtable [io + l]->klass->name_space, vtable [io + l]->klass->name, vtable [io + l]->name));
- }
- }
- }
-
- if (!(vtable [io + l])) {
- for (j = 0; j < onum; ++j) {
- g_print (" at slot %d: %s (%d) overrides %s (%d)\n", io+l, overrides [j*2+1]->name,
- overrides [j*2+1]->slot, overrides [j*2]->name, overrides [j*2]->slot);
- }
- msig = mono_signature_get_desc (mono_method_signature (im), FALSE);
- printf ("no implementation for interface method %s::%s(%s) in class %s.%s\n",
- mono_type_get_name (&ic->byval_arg), im->name, msig, class->name_space, class->name);
- g_free (msig);
- for (j = 0; j < class->method.count; ++j) {
- MonoMethod *cm = class->methods [j];
- msig = mono_signature_get_desc (mono_method_signature (cm), TRUE);
-
- printf ("METHOD %s(%s)\n", cm->name, msig);
- g_free (msig);
- }
-
- mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
-
- if (ifaces)
- g_ptr_array_free (ifaces, TRUE);
- if (override_map)
- g_hash_table_destroy (override_map);