2 #include "mono/metadata/gc-internals.h"
3 #include "mono/metadata/mono-endian.h"
4 #include "mono/metadata/object-internals.h"
5 #include "mono/metadata/reflection-cache.h"
6 #include "mono/metadata/reflection-custom-attrs-internals.h"
7 #include "mono/metadata/reflection-emit-internals.h"
8 #include "mono/metadata/reflection-internals.h"
9 #include "mono/metadata/tabledefs.h"
10 #include "mono/metadata/tokentype.h"
11 #include "mono/metadata/verify-internals.h"
12 #include "mono/utils/checked-build.h"
15 #define CHECK_ADD4_OVERFLOW_UN(a, b) ((guint32)(0xFFFFFFFFU) - (guint32)(b) < (guint32)(a))
16 #define CHECK_ADD8_OVERFLOW_UN(a, b) ((guint64)(0xFFFFFFFFFFFFFFFFUL) - (guint64)(b) < (guint64)(a))
18 #if SIZEOF_VOID_P == 4
19 #define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD4_OVERFLOW_UN(a, b)
21 #define CHECK_ADDP_OVERFLOW_UN(a,b) CHECK_ADD8_OVERFLOW_UN(a, b)
24 #define ADDP_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADDP_OVERFLOW_UN (a, b))
25 #define ADD_IS_GREATER_OR_OVF(a, b, c) (((a) + (b) > (c)) || CHECK_ADD4_OVERFLOW_UN (a, b))
27 static gboolean
type_is_reference (MonoType
*type
);
29 static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_typed_argument
, System
.Reflection
, CustomAttributeTypedArgument
);
30 static GENERATE_GET_CLASS_WITH_CACHE (custom_attribute_named_argument
, System
.Reflection
, CustomAttributeNamedArgument
);
33 * LOCKING: Acquires the loader lock.
35 static MonoCustomAttrInfo
*
36 lookup_custom_attr (MonoImage
*image
, gpointer member
)
38 MONO_REQ_GC_NEUTRAL_MODE
;
40 MonoCustomAttrInfo
* res
;
42 res
= (MonoCustomAttrInfo
*)mono_image_property_lookup (image
, member
, MONO_PROP_DYNAMIC_CATTR
);
47 res
= (MonoCustomAttrInfo
*)g_memdup (res
, MONO_SIZEOF_CUSTOM_ATTR_INFO
+ sizeof (MonoCustomAttrEntry
) * res
->num_attrs
);
53 custom_attr_visible (MonoImage
*image
, MonoReflectionCustomAttr
*cattr
)
55 MONO_REQ_GC_UNSAFE_MODE
;
57 /* FIXME: Need to do more checks */
58 if (cattr
->ctor
->method
&& (cattr
->ctor
->method
->klass
->image
!= image
)) {
59 int visibility
= cattr
->ctor
->method
->klass
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
61 if ((visibility
!= TYPE_ATTRIBUTE_PUBLIC
) && (visibility
!= TYPE_ATTRIBUTE_NESTED_PUBLIC
))
69 type_is_reference (MonoType
*type
)
72 case MONO_TYPE_BOOLEAN
:
86 case MONO_TYPE_VALUETYPE
:
94 free_param_data (MonoMethodSignature
*sig
, void **params
) {
96 for (i
= 0; i
< sig
->param_count
; ++i
) {
97 if (!type_is_reference (sig
->params
[i
]))
103 * Find the field index in the metadata FieldDef table.
106 find_field_index (MonoClass
*klass
, MonoClassField
*field
) {
109 for (i
= 0; i
< klass
->field
.count
; ++i
) {
110 if (field
== &klass
->fields
[i
])
111 return klass
->field
.first
+ 1 + i
;
117 * Find the property index in the metadata Property table.
120 find_property_index (MonoClass
*klass
, MonoProperty
*property
) {
123 for (i
= 0; i
< klass
->ext
->property
.count
; ++i
) {
124 if (property
== &klass
->ext
->properties
[i
])
125 return klass
->ext
->property
.first
+ 1 + i
;
131 * Find the event index in the metadata Event table.
134 find_event_index (MonoClass
*klass
, MonoEvent
*event
) {
137 for (i
= 0; i
< klass
->ext
->event
.count
; ++i
) {
138 if (event
== &klass
->ext
->events
[i
])
139 return klass
->ext
->event
.first
+ 1 + i
;
145 * Load the type with name @n on behalf of image @image. On failure sets @error and returns NULL.
146 * The @is_enum flag only affects the error message that's displayed on failure.
149 cattr_type_from_name (char *n
, MonoImage
*image
, gboolean is_enum
, MonoError
*error
)
151 MonoError inner_error
;
152 MonoType
*t
= mono_reflection_type_from_name_checked (n
, image
, &inner_error
);
154 mono_error_set_type_load_name (error
, g_strdup(n
), NULL
,
155 "Could not load %s %s while decoding custom attribute: %s",
156 is_enum
? "enum type": "type",
158 mono_error_get_message (&inner_error
));
159 mono_error_cleanup (&inner_error
);
166 load_cattr_enum_type (MonoImage
*image
, const char *p
, const char **end
, MonoError
*error
)
170 int slen
= mono_metadata_decode_value (p
, &p
);
172 mono_error_init (error
);
174 n
= (char *)g_memdup (p
, slen
+ 1);
176 t
= cattr_type_from_name (n
, image
, TRUE
, error
);
178 return_val_if_nok (error
, NULL
);
181 return mono_class_from_mono_type (t
);
185 load_cattr_value (MonoImage
*image
, MonoType
*t
, const char *p
, const char **end
, MonoError
*error
)
187 int slen
, type
= t
->type
;
188 MonoClass
*tklass
= t
->data
.klass
;
190 mono_error_init (error
);
196 case MONO_TYPE_BOOLEAN
: {
197 MonoBoolean
*bval
= (MonoBoolean
*)g_malloc (sizeof (MonoBoolean
));
205 guint16
*val
= (guint16
*)g_malloc (sizeof (guint16
));
210 #if SIZEOF_VOID_P == 4
217 guint32
*val
= (guint32
*)g_malloc (sizeof (guint32
));
222 #if SIZEOF_VOID_P == 8
223 case MONO_TYPE_U
: /* error out instead? this should probably not happen */
228 guint64
*val
= (guint64
*)g_malloc (sizeof (guint64
));
234 double *val
= (double *)g_malloc (sizeof (double));
239 case MONO_TYPE_VALUETYPE
:
240 if (t
->data
.klass
->enumtype
) {
241 type
= mono_class_enum_basetype (t
->data
.klass
)->type
;
244 MonoClass
*k
= t
->data
.klass
;
246 if (mono_is_corlib_image (k
->image
) && strcmp (k
->name_space
, "System") == 0 && strcmp (k
->name
, "DateTime") == 0){
247 guint64
*val
= (guint64
*)g_malloc (sizeof (guint64
));
253 g_error ("generic valutype %s not handled in custom attr value decoding", t
->data
.klass
->name
);
256 case MONO_TYPE_STRING
:
257 if (*p
== (char)0xFF) {
261 slen
= mono_metadata_decode_value (p
, &p
);
263 return mono_string_new_len_checked (mono_domain_get (), p
, slen
, error
);
264 case MONO_TYPE_CLASS
: {
265 MonoReflectionType
*rt
;
268 if (*p
== (char)0xFF) {
273 slen
= mono_metadata_decode_value (p
, &p
);
274 n
= (char *)g_memdup (p
, slen
+ 1);
276 t
= cattr_type_from_name (n
, image
, FALSE
, error
);
278 return_val_if_nok (error
, NULL
);
281 rt
= mono_type_get_object_checked (mono_domain_get (), t
, error
);
282 if (!mono_error_ok (error
))
287 case MONO_TYPE_OBJECT
: {
290 MonoClass
*subc
= NULL
;
295 } else if (subt
== 0x0E) {
296 type
= MONO_TYPE_STRING
;
298 } else if (subt
== 0x1D) {
299 MonoType simple_type
= {{0}};
303 type
= MONO_TYPE_SZARRAY
;
305 tklass
= mono_defaults
.systemtype_class
;
306 } else if (etype
== 0x55) {
307 tklass
= load_cattr_enum_type (image
, p
, &p
, error
);
308 if (!mono_error_ok (error
))
312 /* See Partition II, Appendix B3 */
313 etype
= MONO_TYPE_OBJECT
;
314 simple_type
.type
= (MonoTypeEnum
)etype
;
315 tklass
= mono_class_from_mono_type (&simple_type
);
318 } else if (subt
== 0x55) {
321 slen
= mono_metadata_decode_value (p
, &p
);
322 n
= (char *)g_memdup (p
, slen
+ 1);
324 t
= cattr_type_from_name (n
, image
, FALSE
, error
);
326 return_val_if_nok (error
, NULL
);
328 subc
= mono_class_from_mono_type (t
);
329 } else if (subt
>= MONO_TYPE_BOOLEAN
&& subt
<= MONO_TYPE_R8
) {
330 MonoType simple_type
= {{0}};
331 simple_type
.type
= (MonoTypeEnum
)subt
;
332 subc
= mono_class_from_mono_type (&simple_type
);
334 g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt
);
336 val
= load_cattr_value (image
, &subc
->byval_arg
, p
, end
, error
);
338 if (mono_error_ok (error
)) {
339 obj
= mono_object_new_checked (mono_domain_get (), subc
, error
);
340 g_assert (!subc
->has_references
);
341 if (mono_error_ok (error
))
342 mono_gc_memmove_atomic ((char*)obj
+ sizeof (MonoObject
), val
, mono_class_value_size (subc
, NULL
));
348 case MONO_TYPE_SZARRAY
: {
350 guint32 i
, alen
, basetype
;
353 if (alen
== 0xffffffff) {
357 arr
= mono_array_new_checked (mono_domain_get(), tklass
, alen
, error
);
358 return_val_if_nok (error
, NULL
);
359 basetype
= tklass
->byval_arg
.type
;
360 if (basetype
== MONO_TYPE_VALUETYPE
&& tklass
->enumtype
)
361 basetype
= mono_class_enum_basetype (tklass
)->type
;
366 case MONO_TYPE_BOOLEAN
:
367 for (i
= 0; i
< alen
; i
++) {
368 MonoBoolean val
= *p
++;
369 mono_array_set (arr
, MonoBoolean
, i
, val
);
375 for (i
= 0; i
< alen
; i
++) {
376 guint16 val
= read16 (p
);
377 mono_array_set (arr
, guint16
, i
, val
);
384 for (i
= 0; i
< alen
; i
++) {
385 guint32 val
= read32 (p
);
386 mono_array_set (arr
, guint32
, i
, val
);
391 for (i
= 0; i
< alen
; i
++) {
394 mono_array_set (arr
, double, i
, val
);
400 for (i
= 0; i
< alen
; i
++) {
401 guint64 val
= read64 (p
);
402 mono_array_set (arr
, guint64
, i
, val
);
406 case MONO_TYPE_CLASS
:
407 case MONO_TYPE_OBJECT
:
408 case MONO_TYPE_STRING
:
409 case MONO_TYPE_SZARRAY
:
410 for (i
= 0; i
< alen
; i
++) {
411 MonoObject
*item
= (MonoObject
*)load_cattr_value (image
, &tklass
->byval_arg
, p
, &p
, error
);
412 if (!mono_error_ok (error
))
414 mono_array_setref (arr
, i
, item
);
418 g_error ("Type 0x%02x not handled in custom attr array decoding", basetype
);
424 g_error ("Type 0x%02x not handled in custom attr value decoding", type
);
430 load_cattr_value_boxed (MonoDomain
*domain
, MonoImage
*image
, MonoType
*t
, const char* p
, const char** end
, MonoError
*error
)
432 mono_error_init (error
);
434 gboolean is_ref
= type_is_reference (t
);
436 void *val
= load_cattr_value (image
, t
, p
, end
, error
);
437 if (!is_ok (error
)) {
444 return (MonoObject
*)val
;
446 MonoObject
*boxed
= mono_value_box_checked (domain
, mono_class_from_mono_type (t
), val
, error
);
452 create_cattr_typed_arg (MonoType
*t
, MonoObject
*val
, MonoError
*error
)
454 static MonoMethod
*ctor
;
456 void *params
[2], *unboxed
;
458 mono_error_init (error
);
461 ctor
= mono_class_get_method_from_name (mono_class_get_custom_attribute_typed_argument_class (), ".ctor", 2);
463 params
[0] = mono_type_get_object_checked (mono_domain_get (), t
, error
);
464 return_val_if_nok (error
, NULL
);
467 retval
= mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_typed_argument_class (), error
);
468 return_val_if_nok (error
, NULL
);
469 unboxed
= mono_object_unbox (retval
);
471 mono_runtime_invoke_checked (ctor
, unboxed
, params
, error
);
472 return_val_if_nok (error
, NULL
);
478 create_cattr_named_arg (void *minfo
, MonoObject
*typedarg
, MonoError
*error
)
480 static MonoMethod
*ctor
;
482 void *unboxed
, *params
[2];
484 mono_error_init (error
);
487 ctor
= mono_class_get_method_from_name (mono_class_get_custom_attribute_named_argument_class (), ".ctor", 2);
490 params
[1] = typedarg
;
491 retval
= mono_object_new_checked (mono_domain_get (), mono_class_get_custom_attribute_named_argument_class (), error
);
492 return_val_if_nok (error
, NULL
);
494 unboxed
= mono_object_unbox (retval
);
496 mono_runtime_invoke_checked (ctor
, unboxed
, params
, error
);
497 return_val_if_nok (error
, NULL
);
504 mono_custom_attrs_from_builders (MonoImage
*alloc_img
, MonoImage
*image
, MonoArray
*cattrs
)
506 MONO_REQ_GC_UNSAFE_MODE
;
508 int i
, index
, count
, not_visible
;
509 MonoCustomAttrInfo
*ainfo
;
510 MonoReflectionCustomAttr
*cattr
;
514 /* FIXME: check in assembly the Run flag is set */
516 count
= mono_array_length (cattrs
);
518 /* Skip nonpublic attributes since MS.NET seems to do the same */
519 /* FIXME: This needs to be done more globally */
521 for (i
= 0; i
< count
; ++i
) {
522 cattr
= (MonoReflectionCustomAttr
*)mono_array_get (cattrs
, gpointer
, i
);
523 if (!custom_attr_visible (image
, cattr
))
527 int num_attrs
= count
- not_visible
;
528 ainfo
= (MonoCustomAttrInfo
*)mono_image_g_malloc0 (alloc_img
, MONO_SIZEOF_CUSTOM_ATTR_INFO
+ sizeof (MonoCustomAttrEntry
) * num_attrs
);
530 ainfo
->image
= image
;
531 ainfo
->num_attrs
= num_attrs
;
532 ainfo
->cached
= alloc_img
!= NULL
;
534 for (i
= 0; i
< count
; ++i
) {
535 cattr
= (MonoReflectionCustomAttr
*)mono_array_get (cattrs
, gpointer
, i
);
536 if (custom_attr_visible (image
, cattr
)) {
537 unsigned char *saved
= (unsigned char *)mono_image_alloc (image
, mono_array_length (cattr
->data
));
538 memcpy (saved
, mono_array_addr (cattr
->data
, char, 0), mono_array_length (cattr
->data
));
539 ainfo
->attrs
[index
].ctor
= cattr
->ctor
->method
;
540 g_assert (cattr
->ctor
->method
);
541 ainfo
->attrs
[index
].data
= saved
;
542 ainfo
->attrs
[index
].data_size
= mono_array_length (cattr
->data
);
546 g_assert (index
== num_attrs
&& count
== num_attrs
+ not_visible
);
553 create_custom_attr (MonoImage
*image
, MonoMethod
*method
, const guchar
*data
, guint32 len
, MonoError
*error
)
555 const char *p
= (const char*)data
;
557 guint32 i
, j
, num_named
;
559 void *params_buf
[32];
560 void **params
= NULL
;
561 MonoMethodSignature
*sig
;
563 mono_error_init (error
);
565 mono_class_init (method
->klass
);
567 if (!mono_verifier_verify_cattr_content (image
, method
, data
, len
, NULL
)) {
568 mono_error_set_generic_error (error
, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
573 attr
= mono_object_new_checked (mono_domain_get (), method
->klass
, error
);
574 if (!mono_error_ok (error
)) return NULL
;
576 mono_runtime_invoke_checked (method
, attr
, NULL
, error
);
577 if (!mono_error_ok (error
))
583 if (len
< 2 || read16 (p
) != 0x0001) /* Prolog */
586 /*g_print ("got attr %s\n", method->klass->name);*/
588 sig
= mono_method_signature (method
);
589 if (sig
->param_count
< 32) {
591 memset (params
, 0, sizeof (void*) * sig
->param_count
);
593 /* Allocate using GC so it gets GC tracking */
594 params
= (void **)mono_gc_alloc_fixed (sig
->param_count
* sizeof (void*), MONO_GC_DESCRIPTOR_NULL
, MONO_ROOT_SOURCE_REFLECTION
, "custom attribute parameters");
599 for (i
= 0; i
< mono_method_signature (method
)->param_count
; ++i
) {
600 params
[i
] = load_cattr_value (image
, mono_method_signature (method
)->params
[i
], p
, &p
, error
);
601 if (!mono_error_ok (error
))
606 attr
= mono_object_new_checked (mono_domain_get (), method
->klass
, error
);
607 if (!mono_error_ok (error
)) goto fail
;
609 MonoObject
*exc
= NULL
;
610 mono_runtime_try_invoke (method
, attr
, params
, &exc
, error
);
611 if (!mono_error_ok (error
))
614 mono_error_set_exception_instance (error
, (MonoException
*)exc
);
618 num_named
= read16 (named
);
620 for (j
= 0; j
< num_named
; j
++) {
622 char *name
, named_type
, data_type
;
623 named_type
= *named
++;
624 data_type
= *named
++; /* type of data */
625 if (data_type
== MONO_TYPE_SZARRAY
)
626 data_type
= *named
++;
627 if (data_type
== MONO_TYPE_ENUM
) {
630 type_len
= mono_metadata_decode_blob_size (named
, &named
);
631 type_name
= (char *)g_malloc (type_len
+ 1);
632 memcpy (type_name
, named
, type_len
);
633 type_name
[type_len
] = 0;
635 /* FIXME: lookup the type and check type consistency */
638 name_len
= mono_metadata_decode_blob_size (named
, &named
);
639 name
= (char *)g_malloc (name_len
+ 1);
640 memcpy (name
, named
, name_len
);
643 if (named_type
== 0x53) {
644 MonoClassField
*field
;
647 /* how this fail is a blackbox */
648 field
= mono_class_get_field_from_name (mono_object_class (attr
), name
);
650 mono_error_set_generic_error (error
, "System.Reflection", "CustomAttributeFormatException", "Could not find a field with name %s", name
);
655 val
= load_cattr_value (image
, field
->type
, named
, &named
, error
);
656 if (!mono_error_ok (error
)) {
658 if (!type_is_reference (field
->type
))
663 mono_field_set_value (attr
, field
, val
);
664 if (!type_is_reference (field
->type
))
666 } else if (named_type
== 0x54) {
671 prop
= mono_class_get_property_from_name (mono_object_class (attr
), name
);
674 mono_error_set_generic_error (error
, "System.Reflection", "CustomAttributeFormatException", "Could not find a property with name %s", name
);
680 mono_error_set_generic_error (error
, "System.Reflection", "CustomAttributeFormatException", "Could not find the setter for %s", name
);
685 /* can we have more that 1 arg in a custom attr named property? */
686 prop_type
= prop
->get
? mono_method_signature (prop
->get
)->ret
:
687 mono_method_signature (prop
->set
)->params
[mono_method_signature (prop
->set
)->param_count
- 1];
689 pparams
[0] = load_cattr_value (image
, prop_type
, named
, &named
, error
);
690 if (!mono_error_ok (error
)) {
692 if (!type_is_reference (prop_type
))
693 g_free (pparams
[0]);
698 mono_property_set_value_checked (prop
, attr
, pparams
, error
);
699 if (!type_is_reference (prop_type
))
700 g_free (pparams
[0]);
701 if (!is_ok (error
)) {
709 free_param_data (method
->signature
, params
);
710 if (params
!= params_buf
)
711 mono_gc_free_fixed (params
);
716 free_param_data (method
->signature
, params
);
717 if (params
!= params_buf
)
718 mono_gc_free_fixed (params
);
723 * mono_reflection_create_custom_attr_data_args:
725 * Create an array of typed and named arguments from the cattr blob given by DATA.
726 * TYPED_ARGS and NAMED_ARGS will contain the objects representing the arguments,
727 * NAMED_ARG_INFO will contain information about the named arguments.
730 mono_reflection_create_custom_attr_data_args (MonoImage
*image
, MonoMethod
*method
, const guchar
*data
, guint32 len
, MonoArray
**typed_args
, MonoArray
**named_args
, CattrNamedArg
**named_arg_info
, MonoError
*error
)
732 MonoArray
*typedargs
, *namedargs
;
733 MonoClass
*attrklass
;
735 const char *p
= (const char*)data
;
737 guint32 i
, j
, num_named
;
738 CattrNamedArg
*arginfo
= NULL
;
742 *named_arg_info
= NULL
;
744 mono_error_init (error
);
746 if (!mono_verifier_verify_cattr_content (image
, method
, data
, len
, NULL
)) {
747 mono_error_set_generic_error (error
, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
751 mono_class_init (method
->klass
);
753 domain
= mono_domain_get ();
755 if (len
< 2 || read16 (p
) != 0x0001) /* Prolog */
758 typedargs
= mono_array_new_checked (domain
, mono_get_object_class (), mono_method_signature (method
)->param_count
, error
);
759 return_if_nok (error
);
763 for (i
= 0; i
< mono_method_signature (method
)->param_count
; ++i
) {
766 obj
= load_cattr_value_boxed (domain
, image
, mono_method_signature (method
)->params
[i
], p
, &p
, error
);
767 return_if_nok (error
);
768 mono_array_setref (typedargs
, i
, obj
);
772 num_named
= read16 (named
);
773 namedargs
= mono_array_new_checked (domain
, mono_get_object_class (), num_named
, error
);
774 return_if_nok (error
);
776 attrklass
= method
->klass
;
778 arginfo
= g_new0 (CattrNamedArg
, num_named
);
779 *named_arg_info
= arginfo
;
781 for (j
= 0; j
< num_named
; j
++) {
783 char *name
, named_type
, data_type
;
784 named_type
= *named
++;
785 data_type
= *named
++; /* type of data */
786 if (data_type
== MONO_TYPE_SZARRAY
)
787 data_type
= *named
++;
788 if (data_type
== MONO_TYPE_ENUM
) {
791 type_len
= mono_metadata_decode_blob_size (named
, &named
);
792 if (ADDP_IS_GREATER_OR_OVF ((const guchar
*)named
, type_len
, data
+ len
))
795 type_name
= (char *)g_malloc (type_len
+ 1);
796 memcpy (type_name
, named
, type_len
);
797 type_name
[type_len
] = 0;
799 /* FIXME: lookup the type and check type consistency */
802 name_len
= mono_metadata_decode_blob_size (named
, &named
);
803 if (ADDP_IS_GREATER_OR_OVF ((const guchar
*)named
, name_len
, data
+ len
))
805 name
= (char *)g_malloc (name_len
+ 1);
806 memcpy (name
, named
, name_len
);
809 if (named_type
== 0x53) {
811 MonoClassField
*field
= mono_class_get_field_from_name (attrklass
, name
);
818 arginfo
[j
].type
= field
->type
;
819 arginfo
[j
].field
= field
;
821 obj
= load_cattr_value_boxed (domain
, image
, field
->type
, named
, &named
, error
);
822 if (!is_ok (error
)) {
826 mono_array_setref (namedargs
, j
, obj
);
828 } else if (named_type
== 0x54) {
831 MonoProperty
*prop
= mono_class_get_property_from_name (attrklass
, name
);
833 if (!prop
|| !prop
->set
) {
838 prop_type
= prop
->get
? mono_method_signature (prop
->get
)->ret
:
839 mono_method_signature (prop
->set
)->params
[mono_method_signature (prop
->set
)->param_count
- 1];
841 arginfo
[j
].type
= prop_type
;
842 arginfo
[j
].prop
= prop
;
844 obj
= load_cattr_value_boxed (domain
, image
, prop_type
, named
, &named
, error
);
845 if (!is_ok (error
)) {
849 mono_array_setref (namedargs
, j
, obj
);
854 *typed_args
= typedargs
;
855 *named_args
= namedargs
;
858 mono_error_set_generic_error (error
, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
860 *named_arg_info
= NULL
;
864 reflection_resolve_custom_attribute_data (MonoReflectionMethod
*ref_method
, MonoReflectionAssembly
*assembly
, gpointer data
, guint32 len
, MonoArray
**ctor_args
, MonoArray
**named_args
, MonoError
*error
)
867 MonoArray
*typedargs
, *namedargs
;
870 CattrNamedArg
*arginfo
= NULL
;
873 mono_error_init (error
);
881 image
= assembly
->assembly
->image
;
882 method
= ref_method
->method
;
883 domain
= mono_object_domain (ref_method
);
885 if (!mono_class_init (method
->klass
)) {
886 mono_error_set_for_class_failure (error
, method
->klass
);
890 mono_reflection_create_custom_attr_data_args (image
, method
, (const guchar
*)data
, len
, &typedargs
, &namedargs
, &arginfo
, error
);
894 if (!typedargs
|| !namedargs
)
897 for (i
= 0; i
< mono_method_signature (method
)->param_count
; ++i
) {
898 MonoObject
*obj
= mono_array_get (typedargs
, MonoObject
*, i
);
899 MonoObject
*typedarg
;
901 typedarg
= create_cattr_typed_arg (mono_method_signature (method
)->params
[i
], obj
, error
);
904 mono_array_setref (typedargs
, i
, typedarg
);
907 for (i
= 0; i
< mono_array_length (namedargs
); ++i
) {
908 MonoObject
*obj
= mono_array_get (namedargs
, MonoObject
*, i
);
909 MonoObject
*typedarg
, *namedarg
, *minfo
;
911 if (arginfo
[i
].prop
) {
912 minfo
= (MonoObject
*)mono_property_get_object_checked (domain
, NULL
, arginfo
[i
].prop
, error
);
916 minfo
= (MonoObject
*)mono_field_get_object_checked (domain
, NULL
, arginfo
[i
].field
, error
);
921 typedarg
= create_cattr_typed_arg (arginfo
[i
].type
, obj
, error
);
924 namedarg
= create_cattr_named_arg (minfo
, typedarg
, error
);
928 mono_array_setref (namedargs
, i
, namedarg
);
931 *ctor_args
= typedargs
;
932 *named_args
= namedargs
;
936 return mono_error_ok (error
);
940 ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal (MonoReflectionMethod
*ref_method
, MonoReflectionAssembly
*assembly
, gpointer data
, guint32 len
, MonoArray
**ctor_args
, MonoArray
**named_args
)
943 (void) reflection_resolve_custom_attribute_data (ref_method
, assembly
, data
, len
, ctor_args
, named_args
, &error
);
944 mono_error_set_pending_exception (&error
);
948 create_custom_attr_data (MonoImage
*image
, MonoCustomAttrEntry
*cattr
, MonoError
*error
)
950 static MonoMethod
*ctor
;
956 mono_error_init (error
);
958 g_assert (image
->assembly
);
961 ctor
= mono_class_get_method_from_name (mono_defaults
.customattribute_data_class
, ".ctor", 4);
963 domain
= mono_domain_get ();
964 attr
= mono_object_new_checked (domain
, mono_defaults
.customattribute_data_class
, error
);
965 return_val_if_nok (error
, NULL
);
966 params
[0] = mono_method_get_object_checked (domain
, cattr
->ctor
, NULL
, error
);
967 return_val_if_nok (error
, NULL
);
968 params
[1] = mono_assembly_get_object_checked (domain
, image
->assembly
, error
);
969 return_val_if_nok (error
, NULL
);
970 params
[2] = (gpointer
)&cattr
->data
;
971 params
[3] = &cattr
->data_size
;
973 mono_runtime_invoke_checked (ctor
, attr
, params
, error
);
974 return_val_if_nok (error
, NULL
);
979 mono_custom_attrs_construct_by_type (MonoCustomAttrInfo
*cinfo
, MonoClass
*attr_klass
, MonoError
*error
)
985 mono_error_init (error
);
987 for (i
= 0; i
< cinfo
->num_attrs
; ++i
) {
988 MonoCustomAttrEntry
*centry
= &cinfo
->attrs
[i
];
990 /* The cattr type is not finished yet */
991 /* We should include the type name but cinfo doesn't contain it */
992 mono_error_set_type_load_name (error
, NULL
, NULL
, "Custom attribute constructor is null because the custom attribute type is not finished yet.");
999 for (i
= 0; i
< cinfo
->num_attrs
; ++i
) {
1000 MonoMethod
*ctor
= cinfo
->attrs
[i
].ctor
;
1002 if (mono_class_is_assignable_from (attr_klass
, ctor
->klass
))
1006 n
= cinfo
->num_attrs
;
1009 result
= mono_array_new_cached (mono_domain_get (), mono_defaults
.attribute_class
, n
, error
);
1010 return_val_if_nok (error
, NULL
);
1012 for (i
= 0; i
< cinfo
->num_attrs
; ++i
) {
1013 MonoCustomAttrEntry
*centry
= &cinfo
->attrs
[i
];
1014 if (!attr_klass
|| mono_class_is_assignable_from (attr_klass
, centry
->ctor
->klass
)) {
1015 attr
= create_custom_attr (cinfo
->image
, centry
->ctor
, centry
->data
, centry
->data_size
, error
);
1016 if (!mono_error_ok (error
))
1018 mono_array_setref (result
, n
, attr
);
1026 mono_custom_attrs_construct (MonoCustomAttrInfo
*cinfo
)
1029 MonoArray
*result
= mono_custom_attrs_construct_by_type (cinfo
, NULL
, &error
);
1030 mono_error_assert_ok (&error
); /*FIXME proper error handling*/
1036 mono_custom_attrs_data_construct (MonoCustomAttrInfo
*cinfo
, MonoError
*error
)
1042 mono_error_init (error
);
1043 result
= mono_array_new_checked (mono_domain_get (), mono_defaults
.customattribute_data_class
, cinfo
->num_attrs
, error
);
1044 return_val_if_nok (error
, NULL
);
1045 for (i
= 0; i
< cinfo
->num_attrs
; ++i
) {
1046 attr
= create_custom_attr_data (cinfo
->image
, &cinfo
->attrs
[i
], error
);
1047 return_val_if_nok (error
, NULL
);
1048 mono_array_setref (result
, i
, attr
);
1054 * mono_custom_attrs_from_index:
1056 * Returns: NULL if no attributes are found or if a loading error occurs.
1059 mono_custom_attrs_from_index (MonoImage
*image
, guint32 idx
)
1062 MonoCustomAttrInfo
*result
= mono_custom_attrs_from_index_checked (image
, idx
, &error
);
1063 mono_error_cleanup (&error
);
1067 * mono_custom_attrs_from_index_checked:
1069 * Returns: NULL if no attributes are found. On error returns NULL and sets @error.
1072 mono_custom_attrs_from_index_checked (MonoImage
*image
, guint32 idx
, MonoError
*error
)
1074 guint32 mtoken
, i
, len
;
1075 guint32 cols
[MONO_CUSTOM_ATTR_SIZE
];
1077 MonoCustomAttrInfo
*ainfo
;
1078 GList
*tmp
, *list
= NULL
;
1080 MonoCustomAttrEntry
* attr
;
1082 mono_error_init (error
);
1084 ca
= &image
->tables
[MONO_TABLE_CUSTOMATTRIBUTE
];
1086 i
= mono_metadata_custom_attrs_from_index (image
, idx
);
1090 while (i
< ca
->rows
) {
1091 if (mono_metadata_decode_row_col (ca
, i
, MONO_CUSTOM_ATTR_PARENT
) != idx
)
1093 list
= g_list_prepend (list
, GUINT_TO_POINTER (i
));
1096 len
= g_list_length (list
);
1099 ainfo
= (MonoCustomAttrInfo
*)g_malloc0 (MONO_SIZEOF_CUSTOM_ATTR_INFO
+ sizeof (MonoCustomAttrEntry
) * len
);
1100 ainfo
->num_attrs
= len
;
1101 ainfo
->image
= image
;
1102 for (i
= len
, tmp
= list
; i
!= 0; --i
, tmp
= tmp
->next
) {
1103 mono_metadata_decode_row (ca
, GPOINTER_TO_UINT (tmp
->data
), cols
, MONO_CUSTOM_ATTR_SIZE
);
1104 mtoken
= cols
[MONO_CUSTOM_ATTR_TYPE
] >> MONO_CUSTOM_ATTR_TYPE_BITS
;
1105 switch (cols
[MONO_CUSTOM_ATTR_TYPE
] & MONO_CUSTOM_ATTR_TYPE_MASK
) {
1106 case MONO_CUSTOM_ATTR_TYPE_METHODDEF
:
1107 mtoken
|= MONO_TOKEN_METHOD_DEF
;
1109 case MONO_CUSTOM_ATTR_TYPE_MEMBERREF
:
1110 mtoken
|= MONO_TOKEN_MEMBER_REF
;
1113 g_error ("Unknown table for custom attr type %08x", cols
[MONO_CUSTOM_ATTR_TYPE
]);
1116 attr
= &ainfo
->attrs
[i
- 1];
1117 attr
->ctor
= mono_get_method_checked (image
, mtoken
, NULL
, NULL
, error
);
1119 g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image
->name
, mtoken
, mono_error_get_message (error
));
1125 if (!mono_verifier_verify_cattr_blob (image
, cols
[MONO_CUSTOM_ATTR_VALUE
], NULL
)) {
1126 /*FIXME raising an exception here doesn't make any sense*/
1127 g_warning ("Invalid custom attribute blob on image %s for index %x", image
->name
, idx
);
1132 data
= mono_metadata_blob_heap (image
, cols
[MONO_CUSTOM_ATTR_VALUE
]);
1133 attr
->data_size
= mono_metadata_decode_value (data
, &data
);
1134 attr
->data
= (guchar
*)data
;
1142 mono_custom_attrs_from_method (MonoMethod
*method
)
1145 MonoCustomAttrInfo
* result
= mono_custom_attrs_from_method_checked (method
, &error
);
1146 mono_error_cleanup (&error
); /* FIXME want a better API that doesn't swallow the error */
1151 mono_custom_attrs_from_method_checked (MonoMethod
*method
, MonoError
*error
)
1155 mono_error_init (error
);
1158 * An instantiated method has the same cattrs as the generic method definition.
1160 * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
1161 * Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
1163 if (method
->is_inflated
)
1164 method
= ((MonoMethodInflated
*) method
)->declaring
;
1166 if (method_is_dynamic (method
) || image_is_dynamic (method
->klass
->image
))
1167 return lookup_custom_attr (method
->klass
->image
, method
);
1170 /* Synthetic methods */
1173 idx
= mono_method_get_index (method
);
1174 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1175 idx
|= MONO_CUSTOM_ATTR_METHODDEF
;
1176 return mono_custom_attrs_from_index_checked (method
->klass
->image
, idx
, error
);
1180 mono_custom_attrs_from_class (MonoClass
*klass
)
1183 MonoCustomAttrInfo
*result
= mono_custom_attrs_from_class_checked (klass
, &error
);
1184 mono_error_cleanup (&error
);
1189 mono_custom_attrs_from_class_checked (MonoClass
*klass
, MonoError
*error
)
1193 mono_error_init (error
);
1195 if (klass
->generic_class
)
1196 klass
= klass
->generic_class
->container_class
;
1198 if (image_is_dynamic (klass
->image
))
1199 return lookup_custom_attr (klass
->image
, klass
);
1201 if (klass
->byval_arg
.type
== MONO_TYPE_VAR
|| klass
->byval_arg
.type
== MONO_TYPE_MVAR
) {
1202 idx
= mono_metadata_token_index (klass
->sizes
.generic_param_token
);
1203 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1204 idx
|= MONO_CUSTOM_ATTR_GENERICPAR
;
1206 idx
= mono_metadata_token_index (klass
->type_token
);
1207 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1208 idx
|= MONO_CUSTOM_ATTR_TYPEDEF
;
1210 return mono_custom_attrs_from_index_checked (klass
->image
, idx
, error
);
1214 mono_custom_attrs_from_assembly (MonoAssembly
*assembly
)
1217 MonoCustomAttrInfo
*result
= mono_custom_attrs_from_assembly_checked (assembly
, &error
);
1218 mono_error_cleanup (&error
);
1223 mono_custom_attrs_from_assembly_checked (MonoAssembly
*assembly
, MonoError
*error
)
1227 mono_error_init (error
);
1229 if (image_is_dynamic (assembly
->image
))
1230 return lookup_custom_attr (assembly
->image
, assembly
);
1231 idx
= 1; /* there is only one assembly */
1232 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1233 idx
|= MONO_CUSTOM_ATTR_ASSEMBLY
;
1234 return mono_custom_attrs_from_index_checked (assembly
->image
, idx
, error
);
1237 static MonoCustomAttrInfo
*
1238 mono_custom_attrs_from_module (MonoImage
*image
, MonoError
*error
)
1242 if (image_is_dynamic (image
))
1243 return lookup_custom_attr (image
, image
);
1244 idx
= 1; /* there is only one module */
1245 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1246 idx
|= MONO_CUSTOM_ATTR_MODULE
;
1247 return mono_custom_attrs_from_index_checked (image
, idx
, error
);
1251 mono_custom_attrs_from_property (MonoClass
*klass
, MonoProperty
*property
)
1254 MonoCustomAttrInfo
* result
= mono_custom_attrs_from_property_checked (klass
, property
, &error
);
1255 mono_error_cleanup (&error
);
1260 mono_custom_attrs_from_property_checked (MonoClass
*klass
, MonoProperty
*property
, MonoError
*error
)
1264 if (image_is_dynamic (klass
->image
)) {
1265 property
= mono_metadata_get_corresponding_property_from_generic_type_definition (property
);
1266 return lookup_custom_attr (klass
->image
, property
);
1268 idx
= find_property_index (klass
, property
);
1269 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1270 idx
|= MONO_CUSTOM_ATTR_PROPERTY
;
1271 return mono_custom_attrs_from_index_checked (klass
->image
, idx
, error
);
1275 mono_custom_attrs_from_event (MonoClass
*klass
, MonoEvent
*event
)
1278 MonoCustomAttrInfo
* result
= mono_custom_attrs_from_event_checked (klass
, event
, &error
);
1279 mono_error_cleanup (&error
);
1284 mono_custom_attrs_from_event_checked (MonoClass
*klass
, MonoEvent
*event
, MonoError
*error
)
1288 if (image_is_dynamic (klass
->image
)) {
1289 event
= mono_metadata_get_corresponding_event_from_generic_type_definition (event
);
1290 return lookup_custom_attr (klass
->image
, event
);
1292 idx
= find_event_index (klass
, event
);
1293 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1294 idx
|= MONO_CUSTOM_ATTR_EVENT
;
1295 return mono_custom_attrs_from_index_checked (klass
->image
, idx
, error
);
1299 mono_custom_attrs_from_field (MonoClass
*klass
, MonoClassField
*field
)
1302 MonoCustomAttrInfo
* result
= mono_custom_attrs_from_field_checked (klass
, field
, &error
);
1303 mono_error_cleanup (&error
);
1308 mono_custom_attrs_from_field_checked (MonoClass
*klass
, MonoClassField
*field
, MonoError
*error
)
1311 mono_error_init (error
);
1313 if (image_is_dynamic (klass
->image
)) {
1314 field
= mono_metadata_get_corresponding_field_from_generic_type_definition (field
);
1315 return lookup_custom_attr (klass
->image
, field
);
1317 idx
= find_field_index (klass
, field
);
1318 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1319 idx
|= MONO_CUSTOM_ATTR_FIELDDEF
;
1320 return mono_custom_attrs_from_index_checked (klass
->image
, idx
, error
);
1324 * mono_custom_attrs_from_param:
1325 * @method: handle to the method that we want to retrieve custom parameter information from
1326 * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
1328 * The result must be released with mono_custom_attrs_free().
1330 * Returns: the custom attribute object for the specified parameter, or NULL if there are none.
1333 mono_custom_attrs_from_param (MonoMethod
*method
, guint32 param
)
1336 MonoCustomAttrInfo
*result
= mono_custom_attrs_from_param_checked (method
, param
, &error
);
1337 mono_error_cleanup (&error
);
1342 * mono_custom_attrs_from_param_checked:
1343 * @method: handle to the method that we want to retrieve custom parameter information from
1344 * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
1345 * @error: set on error
1347 * The result must be released with mono_custom_attrs_free().
1349 * Returns: the custom attribute object for the specified parameter, or NULL if there are none. On failure returns NULL and sets @error.
1352 mono_custom_attrs_from_param_checked (MonoMethod
*method
, guint32 param
, MonoError
*error
)
1355 guint32 i
, idx
, method_index
;
1356 guint32 param_list
, param_last
, param_pos
, found
;
1358 MonoReflectionMethodAux
*aux
;
1360 mono_error_init (error
);
1363 * An instantiated method has the same cattrs as the generic method definition.
1365 * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
1366 * Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
1368 if (method
->is_inflated
)
1369 method
= ((MonoMethodInflated
*) method
)->declaring
;
1371 if (image_is_dynamic (method
->klass
->image
)) {
1372 MonoCustomAttrInfo
*res
, *ainfo
;
1375 aux
= (MonoReflectionMethodAux
*)g_hash_table_lookup (((MonoDynamicImage
*)method
->klass
->image
)->method_aux_hash
, method
);
1376 if (!aux
|| !aux
->param_cattr
)
1379 /* Need to copy since it will be freed later */
1380 ainfo
= aux
->param_cattr
[param
];
1383 size
= MONO_SIZEOF_CUSTOM_ATTR_INFO
+ sizeof (MonoCustomAttrEntry
) * ainfo
->num_attrs
;
1384 res
= (MonoCustomAttrInfo
*)g_malloc0 (size
);
1385 memcpy (res
, ainfo
, size
);
1389 image
= method
->klass
->image
;
1390 method_index
= mono_method_get_index (method
);
1393 ca
= &image
->tables
[MONO_TABLE_METHOD
];
1395 param_list
= mono_metadata_decode_row_col (ca
, method_index
- 1, MONO_METHOD_PARAMLIST
);
1396 if (method_index
== ca
->rows
) {
1397 ca
= &image
->tables
[MONO_TABLE_PARAM
];
1398 param_last
= ca
->rows
+ 1;
1400 param_last
= mono_metadata_decode_row_col (ca
, method_index
, MONO_METHOD_PARAMLIST
);
1401 ca
= &image
->tables
[MONO_TABLE_PARAM
];
1404 for (i
= param_list
; i
< param_last
; ++i
) {
1405 param_pos
= mono_metadata_decode_row_col (ca
, i
- 1, MONO_PARAM_SEQUENCE
);
1406 if (param_pos
== param
) {
1414 idx
<<= MONO_CUSTOM_ATTR_BITS
;
1415 idx
|= MONO_CUSTOM_ATTR_PARAMDEF
;
1416 return mono_custom_attrs_from_index_checked (image
, idx
, error
);
1420 mono_custom_attrs_has_attr (MonoCustomAttrInfo
*ainfo
, MonoClass
*attr_klass
)
1423 for (i
= 0; i
< ainfo
->num_attrs
; ++i
) {
1424 MonoClass
*klass
= ainfo
->attrs
[i
].ctor
->klass
;
1425 if (mono_class_has_parent (klass
, attr_klass
) || (MONO_CLASS_IS_INTERFACE (attr_klass
) && mono_class_is_assignable_from (attr_klass
, klass
)))
1432 mono_custom_attrs_get_attr (MonoCustomAttrInfo
*ainfo
, MonoClass
*attr_klass
)
1435 MonoObject
*res
= mono_custom_attrs_get_attr_checked (ainfo
, attr_klass
, &error
);
1436 mono_error_assert_ok (&error
); /*FIXME proper error handling*/
1441 mono_custom_attrs_get_attr_checked (MonoCustomAttrInfo
*ainfo
, MonoClass
*attr_klass
, MonoError
*error
)
1446 mono_error_init (error
);
1449 for (i
= 0; i
< ainfo
->num_attrs
; ++i
) {
1450 MonoClass
*klass
= ainfo
->attrs
[i
].ctor
->klass
;
1451 if (mono_class_has_parent (klass
, attr_klass
)) {
1456 if (attr_index
== -1)
1459 attrs
= mono_custom_attrs_construct_by_type (ainfo
, NULL
, error
);
1460 if (!mono_error_ok (error
))
1462 return mono_array_get (attrs
, MonoObject
*, attr_index
);
1466 * mono_reflection_get_custom_attrs_info:
1467 * @obj: a reflection object handle
1469 * Return the custom attribute info for attributes defined for the
1470 * reflection handle @obj. The objects.
1472 * FIXME this function leaks like a sieve for SRE objects.
1475 mono_reflection_get_custom_attrs_info (MonoObject
*obj
)
1478 MonoCustomAttrInfo
*result
= mono_reflection_get_custom_attrs_info_checked (obj
, &error
);
1479 mono_error_assert_ok (&error
);
1484 * mono_reflection_get_custom_attrs_info_checked:
1485 * @obj: a reflection object handle
1486 * @error: set on error
1488 * Return the custom attribute info for attributes defined for the
1489 * reflection handle @obj. The objects.
1491 * On failure returns NULL and sets @error.
1493 * FIXME this function leaks like a sieve for SRE objects.
1496 mono_reflection_get_custom_attrs_info_checked (MonoObject
*obj
, MonoError
*error
)
1499 MonoCustomAttrInfo
*cinfo
= NULL
;
1501 mono_error_init (error
);
1503 klass
= obj
->vtable
->klass
;
1504 if (klass
== mono_defaults
.runtimetype_class
) {
1505 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
1506 return_val_if_nok (error
, NULL
);
1507 klass
= mono_class_from_mono_type (type
);
1508 /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
1509 cinfo
= mono_custom_attrs_from_class_checked (klass
, error
);
1510 return_val_if_nok (error
, NULL
);
1511 } else if (strcmp ("Assembly", klass
->name
) == 0 || strcmp ("MonoAssembly", klass
->name
) == 0) {
1512 MonoReflectionAssembly
*rassembly
= (MonoReflectionAssembly
*)obj
;
1513 cinfo
= mono_custom_attrs_from_assembly_checked (rassembly
->assembly
, error
);
1514 return_val_if_nok (error
, NULL
);
1515 } else if (strcmp ("Module", klass
->name
) == 0 || strcmp ("MonoModule", klass
->name
) == 0) {
1516 MonoReflectionModule
*module
= (MonoReflectionModule
*)obj
;
1517 cinfo
= mono_custom_attrs_from_module (module
->image
, error
);
1518 return_val_if_nok (error
, NULL
);
1519 } else if (strcmp ("MonoProperty", klass
->name
) == 0) {
1520 MonoReflectionProperty
*rprop
= (MonoReflectionProperty
*)obj
;
1521 cinfo
= mono_custom_attrs_from_property_checked (rprop
->property
->parent
, rprop
->property
, error
);
1522 return_val_if_nok (error
, NULL
);
1523 } else if (strcmp ("MonoEvent", klass
->name
) == 0) {
1524 MonoReflectionMonoEvent
*revent
= (MonoReflectionMonoEvent
*)obj
;
1525 cinfo
= mono_custom_attrs_from_event_checked (revent
->event
->parent
, revent
->event
, error
);
1526 return_val_if_nok (error
, NULL
);
1527 } else if (strcmp ("MonoField", klass
->name
) == 0) {
1528 MonoReflectionField
*rfield
= (MonoReflectionField
*)obj
;
1529 cinfo
= mono_custom_attrs_from_field_checked (rfield
->field
->parent
, rfield
->field
, error
);
1530 return_val_if_nok (error
, NULL
);
1531 } else if ((strcmp ("MonoMethod", klass
->name
) == 0) || (strcmp ("MonoCMethod", klass
->name
) == 0)) {
1532 MonoReflectionMethod
*rmethod
= (MonoReflectionMethod
*)obj
;
1533 cinfo
= mono_custom_attrs_from_method_checked (rmethod
->method
, error
);
1534 return_val_if_nok (error
, NULL
);
1535 } else if ((strcmp ("MonoGenericMethod", klass
->name
) == 0) || (strcmp ("MonoGenericCMethod", klass
->name
) == 0)) {
1536 MonoReflectionMethod
*rmethod
= (MonoReflectionMethod
*)obj
;
1537 cinfo
= mono_custom_attrs_from_method_checked (rmethod
->method
, error
);
1538 return_val_if_nok (error
, NULL
);
1539 } else if (strcmp ("ParameterInfo", klass
->name
) == 0 || strcmp ("MonoParameterInfo", klass
->name
) == 0) {
1540 MonoReflectionParameter
*param
= (MonoReflectionParameter
*)obj
;
1541 MonoClass
*member_class
= mono_object_class (param
->MemberImpl
);
1542 if (mono_class_is_reflection_method_or_constructor (member_class
)) {
1543 MonoReflectionMethod
*rmethod
= (MonoReflectionMethod
*)param
->MemberImpl
;
1544 cinfo
= mono_custom_attrs_from_param_checked (rmethod
->method
, param
->PositionImpl
+ 1, error
);
1545 return_val_if_nok (error
, NULL
);
1546 } else if (mono_is_sr_mono_property (member_class
)) {
1547 MonoReflectionProperty
*prop
= (MonoReflectionProperty
*)param
->MemberImpl
;
1549 if (!(method
= prop
->property
->get
))
1550 method
= prop
->property
->set
;
1553 cinfo
= mono_custom_attrs_from_param_checked (method
, param
->PositionImpl
+ 1, error
);
1554 return_val_if_nok (error
, NULL
);
1556 #ifndef DISABLE_REFLECTION_EMIT
1557 else if (mono_is_sre_method_on_tb_inst (member_class
)) {/*XXX This is a workaround for Compiler Context*/
1558 MonoMethod
*method
= mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst
*)param
->MemberImpl
, error
);
1559 return_val_if_nok (error
, NULL
);
1560 cinfo
= mono_custom_attrs_from_param_checked (method
, param
->PositionImpl
+ 1, error
);
1561 return_val_if_nok (error
, NULL
);
1562 } else if (mono_is_sre_ctor_on_tb_inst (member_class
)) { /*XX This is a workaround for Compiler Context*/
1563 MonoReflectionCtorOnTypeBuilderInst
*c
= (MonoReflectionCtorOnTypeBuilderInst
*)param
->MemberImpl
;
1564 MonoMethod
*method
= NULL
;
1565 if (mono_is_sre_ctor_builder (mono_object_class (c
->cb
)))
1566 method
= ((MonoReflectionCtorBuilder
*)c
->cb
)->mhandle
;
1567 else if (mono_is_sr_mono_cmethod (mono_object_class (c
->cb
)))
1568 method
= ((MonoReflectionMethod
*)c
->cb
)->method
;
1570 g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class
));
1572 cinfo
= mono_custom_attrs_from_param_checked (method
, param
->PositionImpl
+ 1, error
);
1573 return_val_if_nok (error
, NULL
);
1577 char *type_name
= mono_type_get_full_name (member_class
);
1578 mono_error_set_not_supported (error
,
1579 "Custom attributes on a ParamInfo with member %s are not supported",
1584 } else if (strcmp ("AssemblyBuilder", klass
->name
) == 0) {
1585 MonoReflectionAssemblyBuilder
*assemblyb
= (MonoReflectionAssemblyBuilder
*)obj
;
1586 cinfo
= mono_custom_attrs_from_builders (NULL
, assemblyb
->assembly
.assembly
->image
, assemblyb
->cattrs
);
1587 } else if (strcmp ("TypeBuilder", klass
->name
) == 0) {
1588 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)obj
;
1589 cinfo
= mono_custom_attrs_from_builders (NULL
, &tb
->module
->dynamic_image
->image
, tb
->cattrs
);
1590 } else if (strcmp ("ModuleBuilder", klass
->name
) == 0) {
1591 MonoReflectionModuleBuilder
*mb
= (MonoReflectionModuleBuilder
*)obj
;
1592 cinfo
= mono_custom_attrs_from_builders (NULL
, &mb
->dynamic_image
->image
, mb
->cattrs
);
1593 } else if (strcmp ("ConstructorBuilder", klass
->name
) == 0) {
1594 MonoReflectionCtorBuilder
*cb
= (MonoReflectionCtorBuilder
*)obj
;
1595 cinfo
= mono_custom_attrs_from_builders (NULL
, cb
->mhandle
->klass
->image
, cb
->cattrs
);
1596 } else if (strcmp ("MethodBuilder", klass
->name
) == 0) {
1597 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)obj
;
1598 cinfo
= mono_custom_attrs_from_builders (NULL
, mb
->mhandle
->klass
->image
, mb
->cattrs
);
1599 } else if (strcmp ("FieldBuilder", klass
->name
) == 0) {
1600 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)obj
;
1601 cinfo
= mono_custom_attrs_from_builders (NULL
, &((MonoReflectionTypeBuilder
*)fb
->typeb
)->module
->dynamic_image
->image
, fb
->cattrs
);
1602 } else if (strcmp ("MonoGenericClass", klass
->name
) == 0) {
1603 MonoReflectionGenericClass
*gclass
= (MonoReflectionGenericClass
*)obj
;
1604 cinfo
= mono_reflection_get_custom_attrs_info_checked ((MonoObject
*)gclass
->generic_type
, error
);
1605 return_val_if_nok (error
, NULL
);
1606 } else { /* handle other types here... */
1607 g_error ("get custom attrs not yet supported for %s", klass
->name
);
1614 * mono_reflection_get_custom_attrs_by_type:
1615 * @obj: a reflection object handle
1617 * Return an array with all the custom attributes defined of the
1618 * reflection handle @obj. If @attr_klass is non-NULL, only custom attributes
1619 * of that type are returned. The objects are fully build. Return NULL if a loading error
1623 mono_reflection_get_custom_attrs_by_type (MonoObject
*obj
, MonoClass
*attr_klass
, MonoError
*error
)
1626 MonoCustomAttrInfo
*cinfo
;
1628 mono_error_init (error
);
1630 cinfo
= mono_reflection_get_custom_attrs_info_checked (obj
, error
);
1631 return_val_if_nok (error
, NULL
);
1633 result
= mono_custom_attrs_construct_by_type (cinfo
, attr_klass
, error
);
1635 mono_custom_attrs_free (cinfo
);
1639 result
= mono_array_new_cached (mono_domain_get (), mono_defaults
.attribute_class
, 0, error
);
1646 * mono_reflection_get_custom_attrs:
1647 * @obj: a reflection object handle
1649 * Return an array with all the custom attributes defined of the
1650 * reflection handle @obj. The objects are fully build. Return NULL if a loading error
1654 mono_reflection_get_custom_attrs (MonoObject
*obj
)
1658 return mono_reflection_get_custom_attrs_by_type (obj
, NULL
, &error
);
1662 * mono_reflection_get_custom_attrs_data:
1663 * @obj: a reflection obj handle
1665 * Returns an array of System.Reflection.CustomAttributeData,
1666 * which include information about attributes reflected on
1667 * types loaded using the Reflection Only methods
1670 mono_reflection_get_custom_attrs_data (MonoObject
*obj
)
1674 result
= mono_reflection_get_custom_attrs_data_checked (obj
, &error
);
1675 mono_error_cleanup (&error
);
1680 * mono_reflection_get_custom_attrs_data_checked:
1681 * @obj: a reflection obj handle
1682 * @error: set on error
1684 * Returns an array of System.Reflection.CustomAttributeData,
1685 * which include information about attributes reflected on
1686 * types loaded using the Reflection Only methods
1689 mono_reflection_get_custom_attrs_data_checked (MonoObject
*obj
, MonoError
*error
)
1692 MonoCustomAttrInfo
*cinfo
;
1694 mono_error_init (error
);
1696 cinfo
= mono_reflection_get_custom_attrs_info_checked (obj
, error
);
1697 return_val_if_nok (error
, NULL
);
1699 result
= mono_custom_attrs_data_construct (cinfo
, error
);
1701 mono_custom_attrs_free (cinfo
);
1702 return_val_if_nok (error
, NULL
);
1704 result
= mono_array_new_checked (mono_domain_get (), mono_defaults
.customattribute_data_class
, 0, error
);