+static guint
+field_hash (gconstpointer key)
+{
+ const MonoClassField *field = key;
+ return g_str_hash (field->name) ^ mono_metadata_type_hash (field->type); /**/
+}
+
+static gboolean
+field_equals (gconstpointer _a, gconstpointer _b)
+{
+ const MonoClassField *a = _a;
+ const MonoClassField *b = _b;
+ return !strcmp (a->name, b->name) && mono_metadata_type_equal (a->type, b->type);
+}
+
+
+static gboolean
+verify_class_fields (MonoClass *class)
+{
+ gpointer iter = NULL;
+ MonoClassField *field;
+ MonoGenericContext *context = mono_class_get_context (class);
+ GHashTable *unique_fields = g_hash_table_new_full (&field_hash, &field_equals, NULL, NULL);
+ if (class->generic_container)
+ context = &class->generic_container->context;
+
+ while ((field = mono_class_get_fields (class, &iter)) != NULL) {
+ if (!mono_type_is_valid_type_in_context (field->type, context)) {
+ g_hash_table_destroy (unique_fields);
+ return FALSE;
+ }
+ if (g_hash_table_lookup (unique_fields, field)) {
+ g_hash_table_destroy (unique_fields);
+ return FALSE;
+ }
+ g_hash_table_insert (unique_fields, field, field);
+ }
+ g_hash_table_destroy (unique_fields);
+ return TRUE;
+}
+
+static gboolean
+verify_interfaces (MonoClass *class)
+{
+ int i;
+ for (i = 0; i < class->interface_count; ++i) {
+ MonoClass *iface = class->interfaces [i];
+ if (!(iface->flags & TYPE_ATTRIBUTE_INTERFACE))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+verify_valuetype_layout_with_target (MonoClass *class, MonoClass *target_class)
+{
+ int type;
+ gpointer iter = NULL;
+ MonoClassField *field;
+ MonoClass *field_class;
+
+ if (!class->valuetype)
+ return TRUE;
+
+ type = class->byval_arg.type;
+ /*primitive type fields are not properly decoded*/
+ if ((type >= MONO_TYPE_BOOLEAN && type <= MONO_TYPE_R8) || (type >= MONO_TYPE_I && type <= MONO_TYPE_U))
+ return TRUE;
+
+ while ((field = mono_class_get_fields (class, &iter)) != NULL) {
+ if (!field->type)
+ return FALSE;
+
+ if (field->type->attrs & (FIELD_ATTRIBUTE_STATIC | FIELD_ATTRIBUTE_HAS_FIELD_RVA))
+ continue;
+
+ field_class = mono_class_get_generic_type_definition (mono_class_from_mono_type (field->type));
+
+ if (field_class == target_class || class == field_class || !verify_valuetype_layout_with_target (field_class, target_class))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_valuetype_layout (MonoClass *class)
+{
+ gboolean res;
+ res = verify_valuetype_layout_with_target (class, class);
+ return res;
+}
+