Here is a proof of concept for a patch for reflection.c

Any comments?
Index: mono/metadata/reflection.c
===================================================================
--- mono/metadata/reflection.c	(revision 125493)
+++ mono/metadata/reflection.c	(working copy)
@@ -8185,6 +8185,35 @@
 	return FALSE;
 }
 
+/** added start **/
+
+gboolean
+mono_custom_attrs_has_attr_partial (MonoCustomAttrInfo *ainfo, const char *attr_assembly, const char *attr_name_space, const char *attr_name)
+{
+	int i;
+	MonoClass *klass;
+
+	if (attr_name == NULL)
+		return FALSE;
+
+	for (i = 0; i < ainfo->num_attrs; ++i) {
+		klass = ainfo->attrs [i].ctor->klass;
+		if (attr_assembly != NULL)
+			if (strcmp (klass->image->assembly_name, attr_assembly) )
+				continue;
+			
+		if (attr_name_space != NULL)
+			if (strcmp (klass->name_space, attr_name_space) )
+				continue;
+
+		if (!strcmp (klass->name, attr_name) )
+				return TRUE;
+	}
+	return FALSE;
+}
+
+/** added end **/
+
 MonoObject*
 mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
 {
@@ -8210,6 +8239,120 @@
 		return NULL;
 }
 
+/** added start **/
+/*NOTE, this doesn't work with dynamic assemblies*/
+gboolean
+mono_image_has_assembly_ref (MonoImage *image, const char *target_assembly)
+{
+        MonoTableInfo *t;
+        int i;
+
+	//TODO: Fix this to work with dynamic assemblies.
+        if (image->dynamic)
+            return FALSE;
+
+        t = &image->tables [MONO_TABLE_ASSEMBLYREF];
+        for (i = 0; i < t->rows; i++) {
+            const char *ref_name = mono_metadata_string_heap (image, mono_metadata_decode_row_col (t, i, MONO_ASSEMBLYREF_NAME));
+            if (!strcmp (target_assembly, ref_name))
+                return TRUE;
+        }
+        return FALSE;
+}
+
+
+gboolean
+mono_index_has_custom_attr (MonoImage *image, guint32 idx, const char *attr_assembly, const char *attr_name_space, const char *attr_name)
+{
+	guint32 mtoken, i, x;
+	guint32 cols [MONO_CUSTOM_ATTR_SIZE];
+	MonoTableInfo *ca;
+	MonoMethod* attr_ctor;
+
+	ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+
+	if (attr_name == NULL)
+		return FALSE;
+
+	if (attr_assembly != NULL)
+		if (!mono_image_has_assembly_ref(image, attr_assembly))
+			return FALSE;
+
+	i = mono_metadata_custom_attrs_from_index (image, idx);
+	if (!i)
+		return FALSE;
+	i --;
+
+	for (x = i; i < ca->rows; x++) {
+		if (mono_metadata_decode_row_col (ca, x, MONO_CUSTOM_ATTR_PARENT) != idx)
+			break;
+		mono_metadata_decode_row (ca, x, cols, MONO_CUSTOM_ATTR_SIZE);
+		mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
+		switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
+		case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
+			mtoken |= MONO_TOKEN_METHOD_DEF;
+			break;
+		case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
+			mtoken |= MONO_TOKEN_MEMBER_REF;
+			break;
+		default:
+			g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
+			break;
+		}
+		attr_ctor = mono_get_method (image, mtoken, NULL);
+		if (!attr_ctor) {
+			g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken);
+			return FALSE;
+		} else {
+			if (attr_assembly != NULL)
+				if (strcmp (attr_ctor->klass->image->assembly_name, attr_assembly) )
+					continue;
+			
+			if (attr_name_space != NULL)
+				if (strcmp (attr_ctor->klass->name_space, attr_name_space) )
+					continue;
+
+			if (!strcmp (attr_ctor->klass->name, attr_name) )
+				return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+gboolean
+mono_method_has_custom_attr (MonoMethod *method, const char *attr_assembly, const char *attr_name_space, const char *attr_name)
+{
+	guint32 idx;
+
+	/*
+	 * An instantiated method has the same cattrs as the generic method definition.
+	 *
+	 * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
+	 *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
+	 */
+	if (method->is_inflated)
+		method = ((MonoMethodInflated *) method)->declaring;
+	
+	if (method->dynamic || method->klass->image->dynamic) {
+		gboolean result;
+		MonoCustomAttrInfo *ainfo = lookup_custom_attr (method->klass->image, method);
+
+		if (ainfo != NULL) {
+			result = mono_custom_attrs_has_attr_partial (ainfo, attr_assembly, attr_name_space, attr_name);
+			mono_custom_attrs_free (ainfo);
+			return result;	
+		}
+	}
+
+	idx = mono_method_get_index (method);
+	idx <<= MONO_CUSTOM_ATTR_BITS;
+	idx |= MONO_CUSTOM_ATTR_METHODDEF;
+	return mono_index_has_custom_attr (method->klass->image, idx, attr_assembly, attr_name_space, attr_name);
+}
+
+/** added end **/
+
 /*
  * mono_reflection_get_custom_attrs_info:
  * @obj: a reflection object handle
_______________________________________________
Mono-devel-list mailing list
[email protected]
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to