2 * reflection.c: System.Type icalls and related reflection queries.
5 * Paolo Molaro (lupus@ximian.com)
7 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
8 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9 * Copyright 2011 Rodrigo Kumpera
10 * Copyright 2016 Microsoft
12 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
15 #include "mono/utils/mono-membar.h"
16 #include "mono/metadata/reflection-internals.h"
17 #include "mono/metadata/tabledefs.h"
18 #include "mono/metadata/metadata-internals.h"
19 #include <mono/metadata/profiler-private.h>
20 #include "mono/metadata/class-internals.h"
21 #include "mono/metadata/gc-internals.h"
22 #include "mono/metadata/domain-internals.h"
23 #include "mono/metadata/opcodes.h"
24 #include "mono/metadata/assembly.h"
25 #include "mono/metadata/object-internals.h"
26 #include <mono/metadata/exception.h>
27 #include <mono/metadata/marshal.h>
28 #include <mono/metadata/security-manager.h>
29 #include <mono/metadata/reflection-cache.h>
30 #include <mono/metadata/sre-internals.h>
39 #include "mono-endian.h"
40 #include <mono/metadata/gc-internals.h>
41 #include <mono/metadata/mempool-internals.h>
42 #include <mono/metadata/security-core-clr.h>
43 #include <mono/metadata/debug-helpers.h>
44 #include <mono/metadata/verify-internals.h>
45 #include <mono/metadata/mono-ptr-array.h>
46 #include <mono/utils/mono-string.h>
47 #include <mono/utils/mono-error-internals.h>
48 #include <mono/utils/checked-build.h>
49 #include <mono/utils/mono-counters.h>
51 static void get_default_param_value_blobs (MonoMethod
*method
, char **blobs
, guint32
*types
);
52 static MonoType
* mono_reflection_get_type_with_rootimage (MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean
*type_resolve
, MonoError
*error
);
54 /* Class lazy loading functions */
55 static GENERATE_GET_CLASS_WITH_CACHE (mono_assembly
, System
.Reflection
, MonoAssembly
)
56 static GENERATE_GET_CLASS_WITH_CACHE (mono_module
, System
.Reflection
, MonoModule
)
57 static GENERATE_GET_CLASS_WITH_CACHE (mono_method
, System
.Reflection
, MonoMethod
);
58 static GENERATE_GET_CLASS_WITH_CACHE (mono_cmethod
, System
.Reflection
, MonoCMethod
);
59 static GENERATE_GET_CLASS_WITH_CACHE (mono_field
, System
.Reflection
, MonoField
);
60 static GENERATE_GET_CLASS_WITH_CACHE (mono_event
, System
.Reflection
, MonoEvent
);
61 static GENERATE_GET_CLASS_WITH_CACHE (mono_property
, System
.Reflection
, MonoProperty
);
62 static GENERATE_GET_CLASS_WITH_CACHE (mono_parameter_info
, System
.Reflection
, MonoParameterInfo
);
63 static GENERATE_GET_CLASS_WITH_CACHE (missing
, System
.Reflection
, Missing
);
64 static GENERATE_GET_CLASS_WITH_CACHE (method_body
, System
.Reflection
, MethodBody
);
65 static GENERATE_GET_CLASS_WITH_CACHE (local_variable_info
, System
.Reflection
, LocalVariableInfo
);
66 static GENERATE_GET_CLASS_WITH_CACHE (exception_handling_clause
, System
.Reflection
, ExceptionHandlingClause
);
67 static GENERATE_GET_CLASS_WITH_CACHE (type_builder
, System
.Reflection
.Emit
, TypeBuilder
);
68 static GENERATE_GET_CLASS_WITH_CACHE (dbnull
, System
, DBNull
);
71 static int class_ref_info_handle_count
;
74 mono_reflection_init (void)
76 mono_reflection_emit_init ();
78 mono_counters_register ("MonoClass::ref_info_handle count",
79 MONO_COUNTER_METADATA
| MONO_COUNTER_INT
, &class_ref_info_handle_count
);
84 * mono_class_get_ref_info:
86 * Return the type builder/generic param builder corresponding to KLASS, if it exists.
89 mono_class_get_ref_info (MonoClass
*klass
)
91 MONO_REQ_GC_UNSAFE_MODE
;
92 guint32 ref_info_handle
= mono_class_get_ref_info_handle (klass
);
94 if (ref_info_handle
== 0)
97 return mono_gchandle_get_target (ref_info_handle
);
101 mono_class_set_ref_info (MonoClass
*klass
, gpointer obj
)
103 MONO_REQ_GC_UNSAFE_MODE
;
105 guint32 candidate
= mono_gchandle_new ((MonoObject
*)obj
, FALSE
);
106 guint32 handle
= mono_class_set_ref_info_handle (klass
, candidate
);
107 ++class_ref_info_handle_count
;
109 if (handle
!= candidate
)
110 mono_gchandle_free (candidate
);
114 mono_class_free_ref_info (MonoClass
*klass
)
116 MONO_REQ_GC_NEUTRAL_MODE
;
117 guint32 handle
= mono_class_get_ref_info_handle (klass
);
120 mono_gchandle_free (handle
);
121 mono_class_set_ref_info_handle (klass
, 0);
127 mono_custom_attrs_free (MonoCustomAttrInfo
*ainfo
)
129 MONO_REQ_GC_NEUTRAL_MODE
;
131 if (ainfo
&& !ainfo
->cached
)
137 reflected_equal (gconstpointer a
, gconstpointer b
)
139 const ReflectedEntry
*ea
= (const ReflectedEntry
*)a
;
140 const ReflectedEntry
*eb
= (const ReflectedEntry
*)b
;
142 return (ea
->item
== eb
->item
) && (ea
->refclass
== eb
->refclass
);
146 reflected_hash (gconstpointer a
) {
147 const ReflectedEntry
*ea
= (const ReflectedEntry
*)a
;
148 return mono_aligned_addr_hash (ea
->item
);
153 clear_cached_object (MonoDomain
*domain
, gpointer o
, MonoClass
*klass
)
155 mono_domain_lock (domain
);
156 if (domain
->refobject_hash
) {
158 gpointer orig_pe
, orig_value
;
162 if (mono_g_hash_table_lookup_extended (domain
->refobject_hash
, &pe
, &orig_pe
, &orig_value
)) {
163 mono_g_hash_table_remove (domain
->refobject_hash
, &pe
);
164 FREE_REFENTRY (orig_pe
);
167 mono_domain_unlock (domain
);
170 #ifdef REFENTRY_REQUIRES_CLEANUP
172 cleanup_refobject_hash (gpointer key
, gpointer value
, gpointer user_data
)
179 mono_reflection_cleanup_domain (MonoDomain
*domain
)
181 if (domain
->refobject_hash
) {
182 /*let's avoid scanning the whole hashtable if not needed*/
183 #ifdef REFENTRY_REQUIRES_CLEANUP
184 mono_g_hash_table_foreach (domain
->refobject_hash
, cleanup_refobject_hash
, NULL
);
186 mono_g_hash_table_destroy (domain
->refobject_hash
);
187 domain
->refobject_hash
= NULL
;
193 * mono_assembly_get_object:
194 * @domain: an app domain
195 * @assembly: an assembly
197 * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
199 MonoReflectionAssembly
*
200 mono_assembly_get_object (MonoDomain
*domain
, MonoAssembly
*assembly
)
202 HANDLE_FUNCTION_ENTER ();
204 MonoReflectionAssemblyHandle result
= mono_assembly_get_object_handle (domain
, assembly
, &error
);
205 mono_error_cleanup (&error
); /* FIXME new API that doesn't swallow the error */
206 HANDLE_FUNCTION_RETURN_OBJ (result
);
209 static MonoReflectionAssemblyHandle
210 assembly_object_construct (MonoDomain
*domain
, MonoClass
*unused_klass
, MonoAssembly
*assembly
, gpointer user_data
, MonoError
*error
)
212 mono_error_init (error
);
213 MonoReflectionAssemblyHandle res
= MONO_HANDLE_NEW (MonoReflectionAssembly
, mono_object_new_checked (domain
, mono_class_get_mono_assembly_class (), error
));
214 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoReflectionAssembly
, NULL_HANDLE
));
215 MONO_HANDLE_SETVAL (res
, assembly
, MonoAssembly
*, assembly
);
220 * mono_assembly_get_object_handle:
221 * @domain: an app domain
222 * @assembly: an assembly
224 * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
226 MonoReflectionAssemblyHandle
227 mono_assembly_get_object_handle (MonoDomain
*domain
, MonoAssembly
*assembly
, MonoError
*error
)
229 mono_error_init (error
);
230 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionAssemblyHandle
, assembly
, NULL
, assembly_object_construct
, NULL
);
233 MonoReflectionModule
*
234 mono_module_get_object (MonoDomain
*domain
, MonoImage
*image
)
236 HANDLE_FUNCTION_ENTER ();
238 MonoReflectionModuleHandle result
= mono_module_get_object_handle (domain
, image
, &error
);
239 mono_error_cleanup (&error
);
240 HANDLE_FUNCTION_RETURN_OBJ (result
);
243 static MonoReflectionModuleHandle
244 module_object_construct (MonoDomain
*domain
, MonoClass
*unused_klass
, MonoImage
*image
, gpointer user_data
, MonoError
*error
)
248 mono_error_init (error
);
249 MonoReflectionModuleHandle res
= MONO_HANDLE_NEW (MonoReflectionModule
, mono_object_new_checked (domain
, mono_class_get_mono_module_class (), error
));
253 MONO_HANDLE_SETVAL (res
, image
, MonoImage
*, image
);
254 MonoReflectionAssemblyHandle assm_obj
= mono_assembly_get_object_handle (domain
, image
->assembly
, error
);
257 MONO_HANDLE_SET (res
, assembly
, assm_obj
);
259 MONO_HANDLE_SET (res
, fqname
, mono_string_new_handle (domain
, image
->name
, error
));
262 basename
= g_path_get_basename (image
->name
);
263 MONO_HANDLE_SET (res
, name
, mono_string_new_handle (domain
, basename
, error
));
266 MONO_HANDLE_SET (res
, scopename
, mono_string_new_handle (domain
, image
->module_name
, error
));
273 if (image
->assembly
->image
== image
) {
274 token
= mono_metadata_make_token (MONO_TABLE_MODULE
, 1);
277 if (image
->assembly
->image
->modules
) {
278 for (i
= 0; i
< image
->assembly
->image
->module_count
; i
++) {
279 if (image
->assembly
->image
->modules
[i
] == image
)
280 token
= mono_metadata_make_token (MONO_TABLE_MODULEREF
, i
+ 1);
282 g_assert (token
!= 0);
285 MONO_HANDLE_SETVAL (res
, token
, guint32
, token
);
289 return MONO_HANDLE_CAST (MonoReflectionModule
, NULL_HANDLE
);
292 MonoReflectionModuleHandle
293 mono_module_get_object_handle (MonoDomain
*domain
, MonoImage
*image
, MonoError
*error
)
295 mono_error_init (error
);
296 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionModuleHandle
, image
, NULL
, module_object_construct
, NULL
);
299 MonoReflectionModule
*
300 mono_module_file_get_object (MonoDomain
*domain
, MonoImage
*image
, int table_index
)
302 HANDLE_FUNCTION_ENTER ();
304 MonoReflectionModuleHandle result
= mono_module_file_get_object_handle (domain
, image
, table_index
, &error
);
305 mono_error_cleanup (&error
);
306 HANDLE_FUNCTION_RETURN_OBJ (result
);
309 MonoReflectionModuleHandle
310 mono_module_file_get_object_handle (MonoDomain
*domain
, MonoImage
*image
, int table_index
, MonoError
*error
)
312 MonoTableInfo
*table
;
313 guint32 cols
[MONO_FILE_SIZE
];
318 mono_error_init (error
);
320 MonoReflectionModuleHandle res
= MONO_HANDLE_NEW (MonoReflectionModule
, mono_object_new_checked (domain
, mono_class_get_mono_module_class (), error
));
324 table
= &image
->tables
[MONO_TABLE_FILE
];
325 g_assert (table_index
< table
->rows
);
326 mono_metadata_decode_row (table
, table_index
, cols
, MONO_FILE_SIZE
);
328 MONO_HANDLE_SETVAL (res
, image
, MonoImage
*, NULL
);
329 MonoReflectionAssemblyHandle assm_obj
= mono_assembly_get_object_handle (domain
, image
->assembly
, error
);
332 MONO_HANDLE_SET (res
, assembly
, assm_obj
);
333 name
= mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]);
335 /* Check whenever the row has a corresponding row in the moduleref table */
336 table
= &image
->tables
[MONO_TABLE_MODULEREF
];
337 for (i
= 0; i
< table
->rows
; ++i
) {
338 name_idx
= mono_metadata_decode_row_col (table
, i
, MONO_MODULEREF_NAME
);
339 val
= mono_metadata_string_heap (image
, name_idx
);
340 if (strcmp (val
, name
) == 0)
341 MONO_HANDLE_SETVAL (res
, image
, MonoImage
*, image
->modules
[i
]);
344 MONO_HANDLE_SET (res
, fqname
, mono_string_new_handle (domain
, name
, error
));
347 MONO_HANDLE_SET (res
, name
, mono_string_new_handle (domain
, name
, error
));
350 MONO_HANDLE_SET (res
, scopename
, mono_string_new_handle (domain
, name
, error
));
353 MONO_HANDLE_SETVAL (res
, is_resource
, MonoBoolean
, cols
[MONO_FILE_FLAGS
] & FILE_CONTAINS_NO_METADATA
);
354 MONO_HANDLE_SETVAL (res
, token
, guint32
, mono_metadata_make_token (MONO_TABLE_FILE
, table_index
+ 1));
358 return MONO_HANDLE_CAST (MonoReflectionModule
, NULL_HANDLE
);
362 mono_type_normalize (MonoType
*type
)
365 MonoGenericClass
*gclass
;
366 MonoGenericInst
*ginst
;
368 MonoGenericContainer
*gcontainer
;
369 MonoType
**argv
= NULL
;
370 gboolean is_denorm_gtd
= TRUE
, requires_rebind
= FALSE
;
372 if (type
->type
!= MONO_TYPE_GENERICINST
)
375 gclass
= type
->data
.generic_class
;
376 ginst
= gclass
->context
.class_inst
;
380 gtd
= gclass
->container_class
;
381 gcontainer
= mono_class_get_generic_container (gtd
);
382 argv
= g_newa (MonoType
*, ginst
->type_argc
);
384 for (i
= 0; i
< ginst
->type_argc
; ++i
) {
385 MonoType
*t
= ginst
->type_argv
[i
], *norm
;
386 if (t
->type
!= MONO_TYPE_VAR
|| t
->data
.generic_param
->num
!= i
|| t
->data
.generic_param
->owner
!= gcontainer
)
387 is_denorm_gtd
= FALSE
;
388 norm
= mono_type_normalize (t
);
391 requires_rebind
= TRUE
;
395 return type
->byref
== gtd
->byval_arg
.byref
? >d
->byval_arg
: >d
->this_arg
;
397 if (requires_rebind
) {
398 MonoClass
*klass
= mono_class_bind_generic_parameters (gtd
, ginst
->type_argc
, argv
, gclass
->is_dynamic
);
399 return type
->byref
== klass
->byval_arg
.byref
? &klass
->byval_arg
: &klass
->this_arg
;
405 * mono_type_get_object:
406 * @domain: an app domain
409 * Return an System.MonoType object representing the type @type.
412 mono_type_get_object (MonoDomain
*domain
, MonoType
*type
)
415 MonoReflectionType
*ret
= mono_type_get_object_checked (domain
, type
, &error
);
416 mono_error_cleanup (&error
);
422 mono_type_get_object_checked (MonoDomain
*domain
, MonoType
*type
, MonoError
*error
)
425 MonoReflectionType
*res
;
428 mono_error_init (error
);
430 g_assert (type
!= NULL
);
431 klass
= mono_class_from_mono_type (type
);
433 /*we must avoid using @type as it might have come
434 * from a mono_metadata_type_dup and the caller
435 * expects that is can be freed.
436 * Using the right type from
438 type
= klass
->byval_arg
.byref
== type
->byref
? &klass
->byval_arg
: &klass
->this_arg
;
440 /* void is very common */
441 if (type
->type
== MONO_TYPE_VOID
&& domain
->typeof_void
)
442 return (MonoReflectionType
*)domain
->typeof_void
;
445 * If the vtable of the given class was already created, we can use
446 * the MonoType from there and avoid all locking and hash table lookups.
448 * We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects
449 * that the resulting object is different.
451 if (type
== &klass
->byval_arg
&& !image_is_dynamic (klass
->image
)) {
452 MonoVTable
*vtable
= mono_class_try_get_vtable (domain
, klass
);
453 if (vtable
&& vtable
->type
)
454 return (MonoReflectionType
*)vtable
->type
;
457 mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
458 mono_domain_lock (domain
);
459 if (!domain
->type_hash
)
460 domain
->type_hash
= mono_g_hash_table_new_type ((GHashFunc
)mono_metadata_type_hash
,
461 (GCompareFunc
)mono_metadata_type_equal
, MONO_HASH_VALUE_GC
, MONO_ROOT_SOURCE_DOMAIN
, "domain reflection types table");
462 if ((res
= (MonoReflectionType
*)mono_g_hash_table_lookup (domain
->type_hash
, type
))) {
463 mono_domain_unlock (domain
);
464 mono_loader_unlock ();
468 /*Types must be normalized so a generic instance of the GTD get's the same inner type.
469 * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
470 * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
471 * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
472 * artifact of how generics are encoded and should be transparent to managed code so we
473 * need to weed out this diference when retrieving managed System.Type objects.
475 norm_type
= mono_type_normalize (type
);
476 if (norm_type
!= type
) {
477 res
= mono_type_get_object_checked (domain
, norm_type
, error
);
478 if (!mono_error_ok (error
))
480 mono_g_hash_table_insert (domain
->type_hash
, type
, res
);
481 mono_domain_unlock (domain
);
482 mono_loader_unlock ();
486 if ((type
->type
== MONO_TYPE_GENERICINST
) && type
->data
.generic_class
->is_dynamic
&& !type
->data
.generic_class
->container_class
->wastypebuilder
) {
487 /* This can happen if a TypeBuilder for a generic class K<T,U>
488 * had reflection_create_generic_class) called on it, but not
489 * ves_icall_TypeBuilder_create_runtime_class. This can happen
490 * if the K`2 is refernced from a generic instantiation
491 * (e.g. K<int,string>) that appears as type argument
492 * (e.g. Dict<string,K<int,string>>), field (e.g. K<int,string>
493 * Foo) or method signature, parent class or any of the above
494 * in a nested class of some other TypeBuilder. Such an
495 * occurrence caused mono_reflection_type_get_handle to be
496 * called on the sre generic instance (K<int,string>) which
497 * required the container_class for the generic class K`2 to be
498 * set up, but the remainder of class construction for K`2 has
500 char * full_name
= mono_type_get_full_name (klass
);
501 /* I would have expected ReflectionTypeLoadException, but evidently .NET throws TLE in this case. */
502 mono_error_set_type_load_class (error
, klass
, "TypeBuilder.CreateType() not called for generic class %s", full_name
);
504 mono_domain_unlock (domain
);
505 mono_loader_unlock ();
509 if (mono_class_get_ref_info (klass
) && !klass
->wastypebuilder
&& !type
->byref
) {
510 mono_domain_unlock (domain
);
511 mono_loader_unlock ();
512 return (MonoReflectionType
*)mono_class_get_ref_info (klass
);
514 /* This is stored in vtables/JITted code so it has to be pinned */
515 res
= (MonoReflectionType
*)mono_object_new_pinned (domain
, mono_defaults
.runtimetype_class
, error
);
516 if (!mono_error_ok (error
))
520 mono_g_hash_table_insert (domain
->type_hash
, type
, res
);
522 if (type
->type
== MONO_TYPE_VOID
)
523 domain
->typeof_void
= (MonoObject
*)res
;
525 mono_domain_unlock (domain
);
526 mono_loader_unlock ();
530 MonoReflectionTypeHandle
531 mono_type_get_object_handle (MonoDomain
*domain
, MonoType
*type
, MonoError
*error
)
533 /* NOTE: We happen to know that mono_type_get_object_checked returns
534 * pinned objects, so we can just wrap its return value in a handle for
535 * uniformity. If it ever starts returning unpinned, objects, this
536 * implementation would need to change!
538 return MONO_HANDLE_NEW (MonoReflectionType
, mono_type_get_object_checked (domain
, type
, error
));
542 * mono_method_get_object:
543 * @domain: an app domain
545 * @refclass: the reflected type (can be NULL)
547 * Return an System.Reflection.MonoMethod object representing the method @method.
549 MonoReflectionMethod
*
550 mono_method_get_object (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
)
552 HANDLE_FUNCTION_ENTER ();
554 MonoReflectionMethodHandle ret
= mono_method_get_object_handle (domain
, method
, refclass
, &error
);
555 mono_error_cleanup (&error
);
556 HANDLE_FUNCTION_RETURN_OBJ (ret
);
559 static MonoReflectionMethodHandle
560 method_object_construct (MonoDomain
*domain
, MonoClass
*refclass
, MonoMethod
*method
, gpointer user_data
, MonoError
*error
)
562 mono_error_init (error
);
563 g_assert (refclass
!= NULL
);
565 * We use the same C representation for methods and constructors, but the type
566 * name in C# is different.
570 mono_error_init (error
);
572 if (*method
->name
== '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0)) {
573 klass
= mono_class_get_mono_cmethod_class ();
576 klass
= mono_class_get_mono_method_class ();
578 MonoReflectionMethodHandle ret
= MONO_HANDLE_NEW (MonoReflectionMethod
, mono_object_new_checked (domain
, klass
, error
));
579 if (!mono_error_ok (error
))
581 MONO_HANDLE_SETVAL (ret
, method
, MonoMethod
*, method
);
583 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &refclass
->byval_arg
, error
);
584 if (!mono_error_ok (error
))
587 MONO_HANDLE_SET (ret
, reftype
, rt
);
594 * mono_method_get_object_handle:
595 * @domain: an app domain
597 * @refclass: the reflected type (can be NULL)
598 * @error: set on error.
600 * Return an System.Reflection.MonoMethod object representing the method @method.
601 * Returns NULL and sets @error on error.
603 MonoReflectionMethodHandle
604 mono_method_get_object_handle (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
, MonoError
*error
)
606 mono_error_init (error
);
608 refclass
= method
->klass
;
610 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionMethodHandle
, method
, refclass
, method_object_construct
, NULL
);
613 * mono_method_get_object_checked:
614 * @domain: an app domain
616 * @refclass: the reflected type (can be NULL)
617 * @error: set on error.
619 * Return an System.Reflection.MonoMethod object representing the method @method.
620 * Returns NULL and sets @error on error.
622 MonoReflectionMethod
*
623 mono_method_get_object_checked (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
, MonoError
*error
)
625 HANDLE_FUNCTION_ENTER ();
626 mono_error_init (error
);
627 MonoReflectionMethodHandle result
= mono_method_get_object_handle (domain
, method
, refclass
, error
);
628 HANDLE_FUNCTION_RETURN_OBJ (result
);
632 * mono_method_clear_object:
634 * Clear the cached reflection objects for the dynamic method METHOD.
637 mono_method_clear_object (MonoDomain
*domain
, MonoMethod
*method
)
640 g_assert (method_is_dynamic (method
));
642 klass
= method
->klass
;
644 clear_cached_object (domain
, method
, klass
);
645 klass
= klass
->parent
;
647 /* Added by mono_param_get_objects () */
648 clear_cached_object (domain
, &(method
->signature
), NULL
);
649 klass
= method
->klass
;
651 clear_cached_object (domain
, &(method
->signature
), klass
);
652 klass
= klass
->parent
;
657 * mono_field_get_object:
658 * @domain: an app domain
662 * Return an System.Reflection.MonoField object representing the field @field
666 mono_field_get_object (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
)
669 MonoReflectionField
*result
;
670 result
= mono_field_get_object_checked (domain
, klass
, field
, &error
);
671 mono_error_cleanup (&error
);
675 static MonoReflectionField
*
676 field_object_construct (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
, gpointer user_data
, MonoError
*error
)
678 MonoReflectionType
*rt
;
679 MonoReflectionField
*res
;
681 mono_error_init (error
);
683 res
= (MonoReflectionField
*)mono_object_new_checked (domain
, mono_class_get_mono_field_class (), error
);
688 MONO_OBJECT_SETREF (res
, name
, mono_string_new (domain
, mono_field_get_name (field
)));
691 rt
= mono_type_get_object_checked (domain
, field
->type
, error
);
692 if (!mono_error_ok (error
))
695 MONO_OBJECT_SETREF (res
, type
, rt
);
697 res
->attrs
= mono_field_get_flags (field
);
702 * mono_field_get_object_checked:
703 * @domain: an app domain
706 * @error: set on error
708 * Return an System.Reflection.MonoField object representing the field @field
709 * in class @klass. On error, returns NULL and sets @error.
712 mono_field_get_object_checked (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
, MonoError
*error
)
714 mono_error_init (error
);
715 return CHECK_OR_CONSTRUCT (MonoReflectionField
*, field
, klass
, field_object_construct
, NULL
);
719 * mono_property_get_object:
720 * @domain: an app domain
722 * @property: a property
724 * Return an System.Reflection.MonoProperty object representing the property @property
727 MonoReflectionProperty
*
728 mono_property_get_object (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
)
731 MonoReflectionProperty
*result
;
732 result
= mono_property_get_object_checked (domain
, klass
, property
, &error
);
733 mono_error_cleanup (&error
);
737 static MonoReflectionProperty
*
738 property_object_construct (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
, gpointer user_data
, MonoError
*error
)
740 MonoReflectionProperty
*res
;
742 mono_error_init (error
);
744 res
= (MonoReflectionProperty
*)mono_object_new_checked (domain
, mono_class_get_mono_property_class (), error
);
748 res
->property
= property
;
753 * mono_property_get_object:
754 * @domain: an app domain
756 * @property: a property
757 * @error: set on error
759 * Return an System.Reflection.MonoProperty object representing the property @property
760 * in class @klass. On error returns NULL and sets @error.
762 MonoReflectionProperty
*
763 mono_property_get_object_checked (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
, MonoError
*error
)
765 mono_error_init (error
);
766 return CHECK_OR_CONSTRUCT (MonoReflectionProperty
*, property
, klass
, property_object_construct
, NULL
);
770 * mono_event_get_object:
771 * @domain: an app domain
775 * Return an System.Reflection.MonoEvent object representing the event @event
779 mono_event_get_object (MonoDomain
*domain
, MonoClass
*klass
, MonoEvent
*event
)
782 MonoReflectionEvent
*result
;
783 result
= mono_event_get_object_checked (domain
, klass
, event
, &error
);
784 mono_error_cleanup (&error
);
788 static MonoReflectionEvent
*
789 event_object_construct (MonoDomain
*domain
, MonoClass
*klass
, MonoEvent
*event
, gpointer user_data
, MonoError
*error
)
791 MonoReflectionMonoEvent
*mono_event
;
793 mono_error_init (error
);
794 mono_event
= (MonoReflectionMonoEvent
*)mono_object_new_checked (domain
, mono_class_get_mono_event_class (), error
);
797 mono_event
->klass
= klass
;
798 mono_event
->event
= event
;
799 return &mono_event
->object
;
803 * mono_event_get_object_checked:
804 * @domain: an app domain
807 * @error: set on error
809 * Return an System.Reflection.MonoEvent object representing the event @event
810 * in class @klass. On failure sets @error and returns NULL
813 mono_event_get_object_checked (MonoDomain
*domain
, MonoClass
*klass
, MonoEvent
*event
, MonoError
*error
)
815 mono_error_init (error
);
816 return CHECK_OR_CONSTRUCT (MonoReflectionEvent
*, event
, klass
, event_object_construct
, NULL
);
820 * mono_get_reflection_missing_object:
821 * @domain: Domain where the object lives
823 * Returns the System.Reflection.Missing.Value singleton object
824 * (of type System.Reflection.Missing).
826 * Used as the value for ParameterInfo.DefaultValue when Optional
830 mono_get_reflection_missing_object (MonoDomain
*domain
)
834 static MonoClassField
*missing_value_field
= NULL
;
836 if (!missing_value_field
) {
837 MonoClass
*missing_klass
;
838 missing_klass
= mono_class_get_missing_class ();
839 mono_class_init (missing_klass
);
840 missing_value_field
= mono_class_get_field_from_name (missing_klass
, "Value");
841 g_assert (missing_value_field
);
843 obj
= mono_field_get_value_object_checked (domain
, missing_value_field
, NULL
, &error
);
844 mono_error_assert_ok (&error
);
849 get_dbnull_object (MonoDomain
*domain
, MonoError
*error
)
852 static MonoClassField
*dbnull_value_field
= NULL
;
854 mono_error_init (error
);
856 if (!dbnull_value_field
) {
857 MonoClass
*dbnull_klass
;
858 dbnull_klass
= mono_class_get_dbnull_class ();
859 dbnull_value_field
= mono_class_get_field_from_name (dbnull_klass
, "Value");
860 g_assert (dbnull_value_field
);
862 obj
= mono_field_get_value_object_checked (domain
, dbnull_value_field
, NULL
, error
);
867 get_dbnull (MonoDomain
*domain
, MonoObject
**dbnull
, MonoError
*error
)
869 mono_error_init (error
);
871 *dbnull
= get_dbnull_object (domain
, error
);
876 get_reflection_missing (MonoDomain
*domain
, MonoObject
**reflection_missing
)
878 if (!*reflection_missing
)
879 *reflection_missing
= mono_get_reflection_missing_object (domain
);
880 return *reflection_missing
;
884 param_objects_construct (MonoDomain
*domain
, MonoClass
*refclass
, MonoMethodSignature
**addr_of_sig
, gpointer user_data
, MonoError
*error
)
886 static MonoClass
*System_Reflection_ParameterInfo
;
887 static MonoClass
*System_Reflection_ParameterInfo_array
;
889 MonoMethod
*method
= (MonoMethod
*)user_data
;
890 MonoMethodSignature
*sig
= *addr_of_sig
; /* see note in mono_param_get_objects_internal */
892 MonoArray
*res
= NULL
;
893 MonoReflectionMethod
*member
= NULL
;
894 MonoReflectionParameter
*param
= NULL
;
895 char **names
= NULL
, **blobs
= NULL
;
896 guint32
*types
= NULL
;
897 MonoType
*type
= NULL
;
898 MonoObject
*dbnull
= NULL
;
899 MonoObject
*missing
= NULL
;
900 MonoMarshalSpec
**mspecs
= NULL
;
901 MonoVTable
*pinfo_vtable
;
902 MonoReflectionType
*rt
;
905 mono_error_init (error
);
907 if (!System_Reflection_ParameterInfo_array
) {
909 klass
= mono_class_get_mono_parameter_info_class ();
910 System_Reflection_ParameterInfo
= klass
;
911 klass
= mono_array_class_get (klass
, 1);
912 System_Reflection_ParameterInfo_array
= klass
;
915 member
= mono_method_get_object_checked (domain
, method
, refclass
, error
);
918 names
= g_new (char *, sig
->param_count
);
919 mono_method_get_param_names (method
, (const char **) names
);
921 mspecs
= g_new (MonoMarshalSpec
*, sig
->param_count
+ 1);
922 mono_method_get_marshal_info (method
, mspecs
);
924 res
= mono_array_new_specific_checked (mono_class_vtable (domain
, System_Reflection_ParameterInfo_array
), sig
->param_count
, error
);
928 pinfo_vtable
= mono_class_vtable (domain
, System_Reflection_ParameterInfo
);
929 for (i
= 0; i
< sig
->param_count
; ++i
) {
930 param
= (MonoReflectionParameter
*) mono_object_new_specific_checked (pinfo_vtable
, error
);
934 rt
= mono_type_get_object_checked (domain
, sig
->params
[i
], error
);
938 MONO_OBJECT_SETREF (param
, ClassImpl
, rt
);
940 MONO_OBJECT_SETREF (param
, MemberImpl
, (MonoObject
*)member
);
942 MONO_OBJECT_SETREF (param
, NameImpl
, mono_string_new (domain
, names
[i
]));
944 param
->PositionImpl
= i
;
945 param
->AttrsImpl
= sig
->params
[i
]->attrs
;
947 if (!(param
->AttrsImpl
& PARAM_ATTRIBUTE_HAS_DEFAULT
)) {
948 if (param
->AttrsImpl
& PARAM_ATTRIBUTE_OPTIONAL
)
949 MONO_OBJECT_SETREF (param
, DefaultValueImpl
, get_reflection_missing (domain
, &missing
));
951 MONO_OBJECT_SETREF (param
, DefaultValueImpl
, get_dbnull (domain
, &dbnull
, error
));
957 blobs
= g_new0 (char *, sig
->param_count
);
958 types
= g_new0 (guint32
, sig
->param_count
);
959 get_default_param_value_blobs (method
, blobs
, types
);
962 /* Build MonoType for the type from the Constant Table */
964 type
= g_new0 (MonoType
, 1);
965 type
->type
= (MonoTypeEnum
)types
[i
];
966 type
->data
.klass
= NULL
;
967 if (types
[i
] == MONO_TYPE_CLASS
)
968 type
->data
.klass
= mono_defaults
.object_class
;
969 else if ((sig
->params
[i
]->type
== MONO_TYPE_VALUETYPE
) && sig
->params
[i
]->data
.klass
->enumtype
) {
970 /* For enums, types [i] contains the base type */
972 type
->type
= MONO_TYPE_VALUETYPE
;
973 type
->data
.klass
= mono_class_from_mono_type (sig
->params
[i
]);
975 type
->data
.klass
= mono_class_from_mono_type (type
);
977 MonoObject
*default_val_obj
= mono_get_object_from_blob (domain
, type
, blobs
[i
], error
);
980 MONO_OBJECT_SETREF (param
, DefaultValueImpl
, default_val_obj
);
982 /* Type in the Constant table is MONO_TYPE_CLASS for nulls */
983 if (types
[i
] != MONO_TYPE_CLASS
&& !param
->DefaultValueImpl
) {
984 if (param
->AttrsImpl
& PARAM_ATTRIBUTE_OPTIONAL
)
985 MONO_OBJECT_SETREF (param
, DefaultValueImpl
, get_reflection_missing (domain
, &missing
));
987 MONO_OBJECT_SETREF (param
, DefaultValueImpl
, get_dbnull (domain
, &dbnull
, error
));
993 if (mspecs
[i
+ 1]) {
994 MonoReflectionMarshalAsAttribute
* mobj
;
995 mobj
= mono_reflection_marshal_as_attribute_from_marshal_spec (domain
, method
->klass
, mspecs
[i
+ 1], error
);
998 MONO_OBJECT_SETREF (param
, MarshalAsImpl
, (MonoObject
*)mobj
);
1001 mono_array_setref (res
, i
, param
);
1011 for (i
= sig
->param_count
; i
>= 0; i
--) {
1013 mono_metadata_free_marshal_spec (mspecs
[i
]);
1025 * mono_param_get_objects:
1026 * @domain: an app domain
1029 * Return an System.Reflection.ParameterInfo array object representing the parameters
1030 * in the method @method.
1033 mono_param_get_objects_internal (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
, MonoError
*error
)
1035 mono_error_init (error
);
1037 MonoMethodSignature
*sig
= mono_method_signature_checked (method
, error
);
1038 if (!mono_error_ok (error
))
1041 if (!sig
->param_count
) {
1042 MonoArray
*res
= mono_array_new_checked (domain
, mono_class_get_mono_parameter_info_class (), 0, error
);
1049 /* Note: the cache is based on the address of the signature into the method
1050 * since we already cache MethodInfos with the method as keys.
1052 return CHECK_OR_CONSTRUCT (MonoArray
*, &method
->signature
, refclass
, param_objects_construct
, method
);
1058 mono_param_get_objects (MonoDomain
*domain
, MonoMethod
*method
)
1061 MonoArray
*result
= mono_param_get_objects_internal (domain
, method
, NULL
, &error
);
1062 mono_error_assert_ok (&error
);
1067 * mono_method_body_get_object:
1068 * @domain: an app domain
1071 * Return an System.Reflection.MethodBody object representing the method @method.
1073 MonoReflectionMethodBody
*
1074 mono_method_body_get_object (MonoDomain
*domain
, MonoMethod
*method
)
1077 MonoReflectionMethodBody
*result
= mono_method_body_get_object_checked (domain
, method
, &error
);
1078 mono_error_cleanup (&error
);
1082 static MonoReflectionMethodBody
*
1083 method_body_object_construct (MonoDomain
*domain
, MonoClass
*unused_class
, MonoMethod
*method
, gpointer user_data
, MonoError
*error
)
1085 MonoReflectionMethodBody
*ret
;
1086 MonoMethodHeader
*header
;
1088 MonoReflectionType
*rt
;
1089 guint32 method_rva
, local_var_sig_token
;
1091 unsigned char format
, flags
;
1094 mono_error_init (error
);
1096 /* for compatibility with .net */
1097 if (method_is_dynamic (method
)) {
1098 mono_error_set_generic_error (error
, "System", "InvalidOperationException", "");
1102 if ((method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
1103 (method
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) ||
1104 (method
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) ||
1105 (method
->klass
->image
->raw_data
&& method
->klass
->image
->raw_data
[1] != 'Z') ||
1106 (method
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
))
1109 image
= method
->klass
->image
;
1110 header
= mono_method_get_header_checked (method
, error
);
1111 return_val_if_nok (error
, NULL
);
1113 if (!image_is_dynamic (image
)) {
1114 /* Obtain local vars signature token */
1115 method_rva
= mono_metadata_decode_row_col (&image
->tables
[MONO_TABLE_METHOD
], mono_metadata_token_index (method
->token
) - 1, MONO_METHOD_RVA
);
1116 ptr
= mono_image_rva_map (image
, method_rva
);
1117 flags
= *(const unsigned char *) ptr
;
1118 format
= flags
& METHOD_HEADER_FORMAT_MASK
;
1120 case METHOD_HEADER_TINY_FORMAT
:
1121 local_var_sig_token
= 0;
1123 case METHOD_HEADER_FAT_FORMAT
:
1127 local_var_sig_token
= read32 (ptr
);
1130 g_assert_not_reached ();
1133 local_var_sig_token
= 0; //FIXME
1135 ret
= (MonoReflectionMethodBody
*)mono_object_new_checked (domain
, mono_class_get_method_body_class (), error
);
1139 ret
->init_locals
= header
->init_locals
;
1140 ret
->max_stack
= header
->max_stack
;
1141 ret
->local_var_sig_token
= local_var_sig_token
;
1142 MonoArray
*il_arr
= mono_array_new_cached (domain
, mono_defaults
.byte_class
, header
->code_size
, error
);
1145 MONO_OBJECT_SETREF (ret
, il
, il_arr
);
1146 memcpy (mono_array_addr (ret
->il
, guint8
, 0), header
->code
, header
->code_size
);
1149 MonoArray
*locals_arr
= mono_array_new_cached (domain
, mono_class_get_local_variable_info_class (), header
->num_locals
, error
);
1152 MONO_OBJECT_SETREF (ret
, locals
, locals_arr
);
1153 for (i
= 0; i
< header
->num_locals
; ++i
) {
1154 MonoReflectionLocalVariableInfo
*info
= (MonoReflectionLocalVariableInfo
*)mono_object_new_checked (domain
, mono_class_get_local_variable_info_class (), error
);
1158 rt
= mono_type_get_object_checked (domain
, header
->locals
[i
], error
);
1162 MONO_OBJECT_SETREF (info
, local_type
, rt
);
1164 info
->is_pinned
= header
->locals
[i
]->pinned
;
1165 info
->local_index
= i
;
1166 mono_array_setref (ret
->locals
, i
, info
);
1170 MonoArray
*exn_clauses
= mono_array_new_cached (domain
, mono_class_get_exception_handling_clause_class (), header
->num_clauses
, error
);
1173 MONO_OBJECT_SETREF (ret
, clauses
, exn_clauses
);
1174 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1175 MonoReflectionExceptionHandlingClause
*info
= (MonoReflectionExceptionHandlingClause
*)mono_object_new_checked (domain
, mono_class_get_exception_handling_clause_class (), error
);
1178 MonoExceptionClause
*clause
= &header
->clauses
[i
];
1180 info
->flags
= clause
->flags
;
1181 info
->try_offset
= clause
->try_offset
;
1182 info
->try_length
= clause
->try_len
;
1183 info
->handler_offset
= clause
->handler_offset
;
1184 info
->handler_length
= clause
->handler_len
;
1185 if (clause
->flags
== MONO_EXCEPTION_CLAUSE_FILTER
)
1186 info
->filter_offset
= clause
->data
.filter_offset
;
1187 else if (clause
->data
.catch_class
) {
1188 rt
= mono_type_get_object_checked (mono_domain_get (), &clause
->data
.catch_class
->byval_arg
, error
);
1192 MONO_OBJECT_SETREF (info
, catch_type
, rt
);
1195 mono_array_setref (ret
->clauses
, i
, info
);
1198 mono_metadata_free_mh (header
);
1201 mono_metadata_free_mh (header
);
1206 * mono_method_body_get_object_checked:
1207 * @domain: an app domain
1209 * @error: set on error
1211 * Return an System.Reflection.MethodBody object representing the
1212 * method @method. On failure, returns NULL and sets @error.
1214 MonoReflectionMethodBody
*
1215 mono_method_body_get_object_checked (MonoDomain
*domain
, MonoMethod
*method
, MonoError
*error
)
1217 mono_error_init (error
);
1218 return CHECK_OR_CONSTRUCT (MonoReflectionMethodBody
*, method
, NULL
, method_body_object_construct
, NULL
);
1222 * mono_get_dbnull_object:
1223 * @domain: Domain where the object lives
1225 * Returns the System.DBNull.Value singleton object
1227 * Used as the value for ParameterInfo.DefaultValue
1230 mono_get_dbnull_object (MonoDomain
*domain
)
1235 obj
= get_dbnull_object (domain
, &error
);
1236 mono_error_assert_ok (&error
);
1241 get_default_param_value_blobs (MonoMethod
*method
, char **blobs
, guint32
*types
)
1243 guint32 param_index
, i
, lastp
, crow
= 0;
1244 guint32 param_cols
[MONO_PARAM_SIZE
], const_cols
[MONO_CONSTANT_SIZE
];
1247 MonoClass
*klass
= method
->klass
;
1248 MonoImage
*image
= klass
->image
;
1249 MonoMethodSignature
*methodsig
= mono_method_signature (method
);
1251 MonoTableInfo
*constt
;
1252 MonoTableInfo
*methodt
;
1253 MonoTableInfo
*paramt
;
1255 if (!methodsig
->param_count
)
1258 mono_class_init (klass
);
1260 if (image_is_dynamic (klass
->image
)) {
1261 MonoReflectionMethodAux
*aux
;
1262 if (method
->is_inflated
)
1263 method
= ((MonoMethodInflated
*)method
)->declaring
;
1264 aux
= (MonoReflectionMethodAux
*)g_hash_table_lookup (((MonoDynamicImage
*)method
->klass
->image
)->method_aux_hash
, method
);
1265 if (aux
&& aux
->param_defaults
) {
1266 memcpy (blobs
, &(aux
->param_defaults
[1]), methodsig
->param_count
* sizeof (char*));
1267 memcpy (types
, &(aux
->param_default_types
[1]), methodsig
->param_count
* sizeof (guint32
));
1272 methodt
= &klass
->image
->tables
[MONO_TABLE_METHOD
];
1273 paramt
= &klass
->image
->tables
[MONO_TABLE_PARAM
];
1274 constt
= &image
->tables
[MONO_TABLE_CONSTANT
];
1276 idx
= mono_method_get_index (method
) - 1;
1277 g_assert (idx
!= -1);
1279 param_index
= mono_metadata_decode_row_col (methodt
, idx
, MONO_METHOD_PARAMLIST
);
1280 if (idx
+ 1 < methodt
->rows
)
1281 lastp
= mono_metadata_decode_row_col (methodt
, idx
+ 1, MONO_METHOD_PARAMLIST
);
1283 lastp
= paramt
->rows
+ 1;
1285 for (i
= param_index
; i
< lastp
; ++i
) {
1288 mono_metadata_decode_row (paramt
, i
- 1, param_cols
, MONO_PARAM_SIZE
);
1289 paramseq
= param_cols
[MONO_PARAM_SEQUENCE
];
1291 if (!(param_cols
[MONO_PARAM_FLAGS
] & PARAM_ATTRIBUTE_HAS_DEFAULT
))
1294 crow
= mono_metadata_get_constant_index (image
, MONO_TOKEN_PARAM_DEF
| i
, crow
+ 1);
1299 mono_metadata_decode_row (constt
, crow
- 1, const_cols
, MONO_CONSTANT_SIZE
);
1300 blobs
[paramseq
- 1] = (char *)mono_metadata_blob_heap (image
, const_cols
[MONO_CONSTANT_VALUE
]);
1301 types
[paramseq
- 1] = const_cols
[MONO_CONSTANT_TYPE
];
1308 mono_get_object_from_blob (MonoDomain
*domain
, MonoType
*type
, const char *blob
, MonoError
*error
)
1313 MonoType
*basetype
= type
;
1315 mono_error_init (error
);
1320 klass
= mono_class_from_mono_type (type
);
1321 if (klass
->valuetype
) {
1322 object
= mono_object_new_checked (domain
, klass
, error
);
1323 return_val_if_nok (error
, NULL
);
1324 retval
= ((gchar
*) object
+ sizeof (MonoObject
));
1325 if (klass
->enumtype
)
1326 basetype
= mono_class_enum_basetype (klass
);
1331 if (!mono_get_constant_value_from_blob (domain
, basetype
->type
, blob
, retval
, error
))
1338 assembly_name_to_aname (MonoAssemblyName
*assembly
, char *p
) {
1341 gboolean quoted
= FALSE
;
1343 memset (assembly
, 0, sizeof (MonoAssemblyName
));
1344 assembly
->culture
= "";
1345 memset (assembly
->public_key_token
, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH
);
1352 while (*p
&& (isalnum (*p
) || *p
== '.' || *p
== '-' || *p
== '_' || *p
== '$' || *p
== '@' || g_ascii_isspace (*p
)))
1363 /* Remove trailing whitespace */
1365 while (*s
&& g_ascii_isspace (*s
))
1368 while (g_ascii_isspace (*p
))
1371 if (*p
== 'V' && g_ascii_strncasecmp (p
, "Version=", 8) == 0) {
1373 assembly
->major
= strtoul (p
, &s
, 10);
1374 if (s
== p
|| *s
!= '.')
1377 assembly
->minor
= strtoul (p
, &s
, 10);
1378 if (s
== p
|| *s
!= '.')
1381 assembly
->build
= strtoul (p
, &s
, 10);
1382 if (s
== p
|| *s
!= '.')
1385 assembly
->revision
= strtoul (p
, &s
, 10);
1389 } else if (*p
== 'C' && g_ascii_strncasecmp (p
, "Culture=", 8) == 0) {
1391 if (g_ascii_strncasecmp (p
, "neutral", 7) == 0) {
1392 assembly
->culture
= "";
1395 assembly
->culture
= p
;
1396 while (*p
&& *p
!= ',') {
1400 } else if (*p
== 'P' && g_ascii_strncasecmp (p
, "PublicKeyToken=", 15) == 0) {
1402 if (strncmp (p
, "null", 4) == 0) {
1407 while (*p
&& *p
!= ',') {
1410 len
= (p
- start
+ 1);
1411 if (len
> MONO_PUBLIC_KEY_TOKEN_LENGTH
)
1412 len
= MONO_PUBLIC_KEY_TOKEN_LENGTH
;
1413 g_strlcpy ((char*)assembly
->public_key_token
, start
, len
);
1416 while (*p
&& *p
!= ',')
1420 while (g_ascii_isspace (*p
) || *p
== ',') {
1434 * mono_reflection_parse_type:
1437 * Parse a type name as accepted by the GetType () method and output the info
1438 * extracted in the info structure.
1439 * the name param will be mangled, so, make a copy before passing it to this function.
1440 * The fields in info will be valid until the memory pointed to by name is valid.
1442 * See also mono_type_get_name () below.
1444 * Returns: 0 on parse error.
1447 _mono_reflection_parse_type (char *name
, char **endptr
, gboolean is_recursed
,
1448 MonoTypeNameParse
*info
)
1450 char *start
, *p
, *w
, *last_point
, *startn
;
1451 int in_modifiers
= 0;
1452 int isbyref
= 0, rank
= 0, isptr
= 0;
1454 start
= p
= w
= name
;
1456 //FIXME could we just zero the whole struct? memset (&info, 0, sizeof (MonoTypeNameParse))
1457 memset (&info
->assembly
, 0, sizeof (MonoAssemblyName
));
1458 info
->name
= info
->name_space
= NULL
;
1459 info
->nested
= NULL
;
1460 info
->modifiers
= NULL
;
1461 info
->type_arguments
= NULL
;
1463 /* last_point separates the namespace from the name */
1466 while (*p
== ' ') p
++, start
++, w
++, name
++;
1471 *p
= 0; /* NULL terminate the name */
1473 info
->nested
= g_list_append (info
->nested
, startn
);
1474 /* we have parsed the nesting namespace + name */
1478 info
->name_space
= start
;
1480 info
->name
= last_point
+ 1;
1482 info
->name_space
= (char *)"";
1510 info
->name_space
= start
;
1512 info
->name
= last_point
+ 1;
1514 info
->name_space
= (char *)"";
1521 if (isbyref
) /* only one level allowed by the spec */
1525 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (0));
1529 if (isbyref
) /* pointer to ref not okay */
1531 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (-1));
1536 if (isbyref
) /* array of ref and generic ref are not okay */
1538 //Decide if it's an array of a generic argument list
1543 if (*p
== ',' || *p
== '*' || *p
== ']') { //array
1551 else if (*p
== '*') /* '*' means unknown lower bound */
1552 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (-2));
1559 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (rank
));
1561 if (rank
|| isptr
) /* generic args after array spec or ptr*/ //XXX test
1564 info
->type_arguments
= g_ptr_array_new ();
1566 MonoTypeNameParse
*subinfo
= g_new0 (MonoTypeNameParse
, 1);
1567 gboolean fqname
= FALSE
;
1569 g_ptr_array_add (info
->type_arguments
, subinfo
);
1571 while (*p
== ' ') p
++;
1577 if (!_mono_reflection_parse_type (p
, &p
, TRUE
, subinfo
))
1580 /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
1581 if (fqname
&& (*p
!= ']')) {
1589 while (*p
&& (*p
!= ']'))
1597 if (g_ascii_isspace (*aname
)) {
1604 !assembly_name_to_aname (&subinfo
->assembly
, aname
))
1606 } else if (fqname
&& (*p
== ']')) {
1628 if (g_ascii_isspace (*p
)) {
1635 return 0; /* missing assembly name */
1636 if (!assembly_name_to_aname (&info
->assembly
, p
))
1642 if (info
->assembly
.name
)
1645 // *w = 0; /* terminate class name */
1647 if (!info
->name
|| !*info
->name
)
1651 /* add other consistency checks */
1657 * mono_identifier_unescape_type_name_chars:
1658 * @identifier: the display name of a mono type
1661 * The name in internal form, that is without escaping backslashes.
1663 * The string is modified in place!
1666 mono_identifier_unescape_type_name_chars(char* identifier
)
1671 for (w
= r
= identifier
; *r
!= 0; r
++)
1689 mono_identifier_unescape_info (MonoTypeNameParse
* info
);
1692 unescape_each_type_argument(void* data
, void* user_data
)
1694 MonoTypeNameParse
* info
= (MonoTypeNameParse
*)data
;
1695 mono_identifier_unescape_info (info
);
1699 unescape_each_nested_name (void* data
, void* user_data
)
1701 char* nested_name
= (char*) data
;
1702 mono_identifier_unescape_type_name_chars(nested_name
);
1706 * mono_identifier_unescape_info:
1708 * @info: a parsed display form of an (optionally assembly qualified) full type name.
1712 * Destructively updates the info by unescaping the identifiers that
1713 * comprise the type namespace, name, nested types (if any) and
1714 * generic type arguments (if any).
1716 * The resulting info has the names in internal form.
1720 mono_identifier_unescape_info (MonoTypeNameParse
*info
)
1724 mono_identifier_unescape_type_name_chars(info
->name_space
);
1725 mono_identifier_unescape_type_name_chars(info
->name
);
1726 // but don't escape info->assembly
1727 if (info
->type_arguments
)
1728 g_ptr_array_foreach(info
->type_arguments
, &unescape_each_type_argument
, NULL
);
1730 g_list_foreach(info
->nested
, &unescape_each_nested_name
, NULL
);
1734 mono_reflection_parse_type (char *name
, MonoTypeNameParse
*info
)
1736 int ok
= _mono_reflection_parse_type (name
, NULL
, FALSE
, info
);
1738 mono_identifier_unescape_info (info
);
1744 _mono_reflection_get_type_from_info (MonoTypeNameParse
*info
, MonoImage
*image
, gboolean ignorecase
, MonoError
*error
)
1746 gboolean type_resolve
= FALSE
;
1748 MonoImage
*rootimage
= image
;
1750 mono_error_init (error
);
1752 if (info
->assembly
.name
) {
1753 MonoAssembly
*assembly
= mono_assembly_loaded (&info
->assembly
);
1754 if (!assembly
&& image
&& image
->assembly
&& mono_assembly_names_equal (&info
->assembly
, &image
->assembly
->aname
))
1756 * This could happen in the AOT compiler case when the search hook is not
1759 assembly
= image
->assembly
;
1761 /* then we must load the assembly ourselve - see #60439 */
1762 assembly
= mono_assembly_load (&info
->assembly
, image
->assembly
->basedir
, NULL
);
1766 image
= assembly
->image
;
1767 } else if (!image
) {
1768 image
= mono_defaults
.corlib
;
1771 type
= mono_reflection_get_type_with_rootimage (rootimage
, image
, info
, ignorecase
, &type_resolve
, error
);
1772 if (type
== NULL
&& !info
->assembly
.name
&& image
!= mono_defaults
.corlib
) {
1773 /* ignore the error and try again */
1774 mono_error_cleanup (error
);
1775 mono_error_init (error
);
1776 image
= mono_defaults
.corlib
;
1777 type
= mono_reflection_get_type_with_rootimage (rootimage
, image
, info
, ignorecase
, &type_resolve
, error
);
1784 * mono_reflection_get_type_internal:
1786 * Returns: may return NULL on success, sets error on failure.
1789 mono_reflection_get_type_internal (MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, MonoError
*error
)
1794 gboolean bounded
= FALSE
;
1796 mono_error_init (error
);
1798 image
= mono_defaults
.corlib
;
1801 rootimage
= mono_defaults
.corlib
;
1804 klass
= mono_class_from_name_case_checked (image
, info
->name_space
, info
->name
, error
);
1806 klass
= mono_class_from_name_checked (image
, info
->name_space
, info
->name
, error
);
1811 for (mod
= info
->nested
; mod
; mod
= mod
->next
) {
1812 gpointer iter
= NULL
;
1816 mono_class_init (parent
);
1818 while ((klass
= mono_class_get_nested_types (parent
, &iter
))) {
1820 char *nested_name
, *nested_nspace
;
1821 gboolean match
= TRUE
;
1823 lastp
= strrchr ((const char *)mod
->data
, '.');
1825 /* Nested classes can have namespaces */
1828 nested_name
= g_strdup (lastp
+ 1);
1829 nspace_len
= lastp
- (char*)mod
->data
;
1830 nested_nspace
= (char *)g_malloc (nspace_len
+ 1);
1831 memcpy (nested_nspace
, mod
->data
, nspace_len
);
1832 nested_nspace
[nspace_len
] = '\0';
1835 nested_name
= (char *)mod
->data
;
1836 nested_nspace
= NULL
;
1839 if (nested_nspace
) {
1841 if (!(klass
->name_space
&& mono_utf8_strcasecmp (klass
->name_space
, nested_nspace
) == 0))
1844 if (!(klass
->name_space
&& strcmp (klass
->name_space
, nested_nspace
) == 0))
1850 if (mono_utf8_strcasecmp (klass
->name
, nested_name
) != 0)
1853 if (strcmp (klass
->name
, nested_name
) != 0)
1858 g_free (nested_name
);
1859 g_free (nested_nspace
);
1871 if (info
->type_arguments
) {
1872 MonoType
**type_args
= g_new0 (MonoType
*, info
->type_arguments
->len
);
1873 MonoReflectionType
*the_type
;
1877 for (i
= 0; i
< info
->type_arguments
->len
; i
++) {
1878 MonoTypeNameParse
*subinfo
= (MonoTypeNameParse
*)g_ptr_array_index (info
->type_arguments
, i
);
1880 type_args
[i
] = _mono_reflection_get_type_from_info (subinfo
, rootimage
, ignorecase
, error
);
1881 if (!type_args
[i
]) {
1887 the_type
= mono_type_get_object_checked (mono_domain_get (), &klass
->byval_arg
, error
);
1891 instance
= mono_reflection_bind_generic_parameters (
1892 the_type
, info
->type_arguments
->len
, type_args
, error
);
1898 klass
= mono_class_from_mono_type (instance
);
1901 for (mod
= info
->modifiers
; mod
; mod
= mod
->next
) {
1902 modval
= GPOINTER_TO_UINT (mod
->data
);
1903 if (!modval
) { /* byref: must be last modifier */
1904 return &klass
->this_arg
;
1905 } else if (modval
== -1) {
1906 klass
= mono_ptr_class_get (&klass
->byval_arg
);
1907 } else if (modval
== -2) {
1909 } else { /* array rank */
1910 klass
= mono_bounded_array_class_get (klass
, modval
, bounded
);
1914 return &klass
->byval_arg
;
1918 * mono_reflection_get_type:
1919 * @image: a metadata context
1920 * @info: type description structure
1921 * @ignorecase: flag for case-insensitive string compares
1922 * @type_resolve: whenever type resolve was already tried
1924 * Build a MonoType from the type description in @info.
1929 mono_reflection_get_type (MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean
*type_resolve
) {
1931 MonoType
*result
= mono_reflection_get_type_with_rootimage (image
, image
, info
, ignorecase
, type_resolve
, &error
);
1932 mono_error_cleanup (&error
);
1937 * mono_reflection_get_type_checked:
1938 * @rootimage: the image of the currently active managed caller
1939 * @image: a metadata context
1940 * @info: type description structure
1941 * @ignorecase: flag for case-insensitive string compares
1942 * @type_resolve: whenever type resolve was already tried
1943 * @error: set on error.
1945 * Build a MonoType from the type description in @info. On failure returns NULL and sets @error.
1949 mono_reflection_get_type_checked (MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean
*type_resolve
, MonoError
*error
) {
1950 mono_error_init (error
);
1951 return mono_reflection_get_type_with_rootimage (rootimage
, image
, info
, ignorecase
, type_resolve
, error
);
1956 module_builder_array_get_type (MonoArrayHandle module_builders
, int i
, MonoImage
*rootimage
, MonoTypeNameParse
*info
, gboolean ignorecase
, MonoError
*error
)
1958 HANDLE_FUNCTION_ENTER ();
1959 mono_error_init (error
);
1960 MonoType
*type
= NULL
;
1961 MonoReflectionModuleBuilderHandle mb
= MONO_HANDLE_NEW (MonoReflectionModuleBuilder
, NULL
);
1962 MONO_HANDLE_ARRAY_GETREF (mb
, module_builders
, i
);
1963 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
1964 type
= mono_reflection_get_type_internal (rootimage
, &dynamic_image
->image
, info
, ignorecase
, error
);
1965 HANDLE_FUNCTION_RETURN_VAL (type
);
1969 module_array_get_type (MonoArrayHandle modules
, int i
, MonoImage
*rootimage
, MonoTypeNameParse
*info
, gboolean ignorecase
, MonoError
*error
)
1971 HANDLE_FUNCTION_ENTER ();
1972 mono_error_init (error
);
1973 MonoType
*type
= NULL
;
1974 MonoReflectionModuleHandle mod
= MONO_HANDLE_NEW (MonoReflectionModule
, NULL
);
1975 MONO_HANDLE_ARRAY_GETREF (mod
, modules
, i
);
1976 MonoImage
*image
= MONO_HANDLE_GETVAL (mod
, image
);
1977 type
= mono_reflection_get_type_internal (rootimage
, image
, info
, ignorecase
, error
);
1978 HANDLE_FUNCTION_RETURN_VAL (type
);
1982 mono_reflection_get_type_internal_dynamic (MonoImage
*rootimage
, MonoAssembly
*assembly
, MonoTypeNameParse
*info
, gboolean ignorecase
, MonoError
*error
)
1984 HANDLE_FUNCTION_ENTER ();
1985 MonoType
*type
= NULL
;
1988 mono_error_init (error
);
1989 g_assert (assembly_is_dynamic (assembly
));
1990 MonoReflectionAssemblyBuilderHandle abuilder
= MONO_HANDLE_CAST (MonoReflectionAssemblyBuilder
, mono_assembly_get_object_handle (((MonoDynamicAssembly
*)assembly
)->domain
, assembly
, error
));
1994 /* Enumerate all modules */
1996 MonoArrayHandle modules
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1997 MONO_HANDLE_GET (modules
, abuilder
, modules
);
1998 if (!MONO_HANDLE_IS_NULL (modules
)) {
1999 int n
= mono_array_handle_length (modules
);
2000 for (i
= 0; i
< n
; ++i
) {
2001 type
= module_builder_array_get_type (modules
, i
, rootimage
, info
, ignorecase
, error
);
2009 MonoArrayHandle loaded_modules
= MONO_HANDLE_NEW (MonoArray
, NULL
);
2010 MONO_HANDLE_GET (loaded_modules
, abuilder
, loaded_modules
);
2011 if (!type
&& !MONO_HANDLE_IS_NULL(loaded_modules
)) {
2012 int n
= mono_array_handle_length (loaded_modules
);
2013 for (i
= 0; i
< n
; ++i
) {
2014 type
= module_array_get_type (loaded_modules
, i
, rootimage
, info
, ignorecase
, error
);
2023 HANDLE_FUNCTION_RETURN_VAL (type
);
2027 mono_reflection_get_type_with_rootimage (MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean
*type_resolve
, MonoError
*error
)
2030 MonoReflectionAssembly
*assembly
;
2034 mono_error_init (error
);
2036 if (image
&& image_is_dynamic (image
))
2037 type
= mono_reflection_get_type_internal_dynamic (rootimage
, image
->assembly
, info
, ignorecase
, error
);
2039 type
= mono_reflection_get_type_internal (rootimage
, image
, info
, ignorecase
, error
);
2041 return_val_if_nok (error
, NULL
);
2045 if (!mono_domain_has_type_resolve (mono_domain_get ()))
2052 *type_resolve
= TRUE
;
2055 /* Reconstruct the type name */
2056 fullName
= g_string_new ("");
2057 if (info
->name_space
&& (info
->name_space
[0] != '\0'))
2058 g_string_printf (fullName
, "%s.%s", info
->name_space
, info
->name
);
2060 g_string_printf (fullName
, "%s", info
->name
);
2061 for (mod
= info
->nested
; mod
; mod
= mod
->next
)
2062 g_string_append_printf (fullName
, "+%s", (char*)mod
->data
);
2064 assembly
= mono_domain_try_type_resolve_checked ( mono_domain_get (), fullName
->str
, NULL
, error
);
2065 if (!is_ok (error
)) {
2066 g_string_free (fullName
, TRUE
);
2071 if (assembly_is_dynamic (assembly
->assembly
))
2072 type
= mono_reflection_get_type_internal_dynamic (rootimage
, assembly
->assembly
,
2073 info
, ignorecase
, error
);
2075 type
= mono_reflection_get_type_internal (rootimage
, assembly
->assembly
->image
,
2076 info
, ignorecase
, error
);
2078 g_string_free (fullName
, TRUE
);
2079 return_val_if_nok (error
, NULL
);
2084 mono_reflection_free_type_info (MonoTypeNameParse
*info
)
2086 g_list_free (info
->modifiers
);
2087 g_list_free (info
->nested
);
2089 if (info
->type_arguments
) {
2092 for (i
= 0; i
< info
->type_arguments
->len
; i
++) {
2093 MonoTypeNameParse
*subinfo
= (MonoTypeNameParse
*)g_ptr_array_index (info
->type_arguments
, i
);
2095 mono_reflection_free_type_info (subinfo
);
2096 /*We free the subinfo since it is allocated by _mono_reflection_parse_type*/
2100 g_ptr_array_free (info
->type_arguments
, TRUE
);
2105 * mono_reflection_type_from_name:
2107 * @image: a metadata context (can be NULL).
2109 * Retrieves a MonoType from its @name. If the name is not fully qualified,
2110 * it defaults to get the type from @image or, if @image is NULL or loading
2111 * from it fails, uses corlib.
2115 mono_reflection_type_from_name (char *name
, MonoImage
*image
)
2118 MonoType
*result
= mono_reflection_type_from_name_checked (name
, image
, &error
);
2119 mono_error_cleanup (&error
);
2124 * mono_reflection_type_from_name_checked:
2126 * @image: a metadata context (can be NULL).
2127 * @error: set on errror.
2129 * Retrieves a MonoType from its @name. If the name is not fully qualified,
2130 * it defaults to get the type from @image or, if @image is NULL or loading
2131 * from it fails, uses corlib. On failure returns NULL and sets @error.
2135 mono_reflection_type_from_name_checked (char *name
, MonoImage
*image
, MonoError
*error
)
2137 MonoType
*type
= NULL
;
2138 MonoTypeNameParse info
;
2141 mono_error_init (error
);
2142 /* Make a copy since parse_type modifies its argument */
2143 tmp
= g_strdup (name
);
2145 /*g_print ("requested type %s\n", str);*/
2146 if (mono_reflection_parse_type (tmp
, &info
)) {
2147 type
= _mono_reflection_get_type_from_info (&info
, image
, FALSE
, error
);
2148 if (!is_ok (error
)) {
2150 mono_reflection_free_type_info (&info
);
2156 mono_reflection_free_type_info (&info
);
2161 * mono_reflection_get_token:
2163 * Return the metadata token of OBJ which should be an object
2164 * representing a metadata element.
2167 mono_reflection_get_token (MonoObject
*obj
)
2170 guint32 result
= mono_reflection_get_token_checked (obj
, &error
);
2171 mono_error_assert_ok (&error
);
2176 * mono_reflection_get_token_checked:
2178 * @error: set on error
2180 * Return the metadata token of @obj which should be an object
2181 * representing a metadata element. On failure sets @error.
2184 mono_reflection_get_token_checked (MonoObject
*obj
, MonoError
*error
)
2189 mono_error_init (error
);
2191 klass
= obj
->vtable
->klass
;
2193 if (strcmp (klass
->name
, "MethodBuilder") == 0) {
2194 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)obj
;
2196 token
= mb
->table_idx
| MONO_TOKEN_METHOD_DEF
;
2197 } else if (strcmp (klass
->name
, "ConstructorBuilder") == 0) {
2198 MonoReflectionCtorBuilder
*mb
= (MonoReflectionCtorBuilder
*)obj
;
2200 token
= mb
->table_idx
| MONO_TOKEN_METHOD_DEF
;
2201 } else if (strcmp (klass
->name
, "FieldBuilder") == 0) {
2202 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)obj
;
2204 token
= fb
->table_idx
| MONO_TOKEN_FIELD_DEF
;
2205 } else if (strcmp (klass
->name
, "TypeBuilder") == 0) {
2206 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)obj
;
2207 token
= tb
->table_idx
| MONO_TOKEN_TYPE_DEF
;
2208 } else if (strcmp (klass
->name
, "RuntimeType") == 0) {
2209 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
2210 return_val_if_nok (error
, 0);
2211 MonoClass
*mc
= mono_class_from_mono_type (type
);
2212 if (!mono_class_init (mc
)) {
2213 mono_error_set_for_class_failure (error
, mc
);
2217 token
= mc
->type_token
;
2218 } else if (strcmp (klass
->name
, "MonoCMethod") == 0 ||
2219 strcmp (klass
->name
, "MonoMethod") == 0) {
2220 MonoReflectionMethod
*m
= (MonoReflectionMethod
*)obj
;
2221 if (m
->method
->is_inflated
) {
2222 MonoMethodInflated
*inflated
= (MonoMethodInflated
*) m
->method
;
2223 return inflated
->declaring
->token
;
2225 token
= m
->method
->token
;
2227 } else if (strcmp (klass
->name
, "MonoField") == 0) {
2228 MonoReflectionField
*f
= (MonoReflectionField
*)obj
;
2230 token
= mono_class_get_field_token (f
->field
);
2231 } else if (strcmp (klass
->name
, "MonoProperty") == 0) {
2232 MonoReflectionProperty
*p
= (MonoReflectionProperty
*)obj
;
2234 token
= mono_class_get_property_token (p
->property
);
2235 } else if (strcmp (klass
->name
, "MonoEvent") == 0) {
2236 MonoReflectionMonoEvent
*p
= (MonoReflectionMonoEvent
*)obj
;
2238 token
= mono_class_get_event_token (p
->event
);
2239 } else if (strcmp (klass
->name
, "ParameterInfo") == 0 || strcmp (klass
->name
, "MonoParameterInfo") == 0) {
2240 MonoReflectionParameter
*p
= (MonoReflectionParameter
*)obj
;
2241 MonoClass
*member_class
= mono_object_class (p
->MemberImpl
);
2242 g_assert (mono_class_is_reflection_method_or_constructor (member_class
));
2244 token
= mono_method_get_param_token (((MonoReflectionMethod
*)p
->MemberImpl
)->method
, p
->PositionImpl
);
2245 } else if (strcmp (klass
->name
, "Module") == 0 || strcmp (klass
->name
, "MonoModule") == 0) {
2246 MonoReflectionModule
*m
= (MonoReflectionModule
*)obj
;
2249 } else if (strcmp (klass
->name
, "Assembly") == 0 || strcmp (klass
->name
, "MonoAssembly") == 0) {
2250 token
= mono_metadata_make_token (MONO_TABLE_ASSEMBLY
, 1);
2252 mono_error_set_not_implemented (error
, "MetadataToken is not supported for type '%s.%s'",
2253 klass
->name_space
, klass
->name
);
2262 mono_reflection_is_usertype (MonoReflectionType
*ref
)
2264 MonoClass
*klass
= mono_object_class (ref
);
2265 return klass
->image
!= mono_defaults
.corlib
|| strcmp ("TypeDelegator", klass
->name
) == 0;
2269 * mono_reflection_bind_generic_parameters:
2270 * @type: a managed type object (which should be some kind of generic (instance? definition?))
2271 * @type_args: the number of type arguments to bind
2272 * @types: array of type arguments
2273 * @error: set on error
2275 * Given a managed type object for a generic type instance, binds each of its arguments to the specified types.
2276 * Returns the MonoType* for the resulting type instantiation. On failure returns NULL and sets @error.
2279 mono_reflection_bind_generic_parameters (MonoReflectionType
*type
, int type_argc
, MonoType
**types
, MonoError
*error
)
2282 gboolean is_dynamic
= FALSE
;
2285 mono_error_init (error
);
2287 mono_loader_lock ();
2289 if (mono_is_sre_type_builder (mono_object_class (type
))) {
2291 } else if (mono_is_sre_generic_instance (mono_object_class (type
))) {
2292 /* Does this ever make sense? what does instantiating a generic instance even mean? */
2293 g_assert_not_reached ();
2294 MonoReflectionGenericClass
*rgi
= (MonoReflectionGenericClass
*) type
;
2295 MonoReflectionType
*gtd
= rgi
->generic_type
;
2297 if (mono_is_sre_type_builder (mono_object_class (gtd
)))
2301 MonoType
*t
= mono_reflection_type_get_handle (type
, error
);
2302 if (!is_ok (error
)) {
2303 mono_loader_unlock ();
2307 klass
= mono_class_from_mono_type (t
);
2308 if (!mono_class_is_gtd (klass
)) {
2309 mono_loader_unlock ();
2310 mono_error_set_type_load_class (error
, klass
, "Cannot bind generic parameters of a non-generic type");
2314 guint gtd_type_argc
= mono_class_get_generic_container (klass
)->type_argc
;
2315 if (gtd_type_argc
!= type_argc
) {
2316 mono_loader_unlock ();
2317 mono_error_set_argument (error
, "types", "The generic type definition needs %d type arguments, but was instantiated with %d ", gtd_type_argc
, type_argc
);
2322 if (klass
->wastypebuilder
)
2325 mono_loader_unlock ();
2327 geninst
= mono_class_bind_generic_parameters (klass
, type_argc
, types
, is_dynamic
);
2329 return &geninst
->byval_arg
;
2333 mono_class_bind_generic_parameters (MonoClass
*klass
, int type_argc
, MonoType
**types
, gboolean is_dynamic
)
2335 MonoGenericClass
*gclass
;
2336 MonoGenericInst
*inst
;
2338 g_assert (mono_class_is_gtd (klass
));
2340 inst
= mono_metadata_get_generic_inst (type_argc
, types
);
2341 gclass
= mono_metadata_lookup_generic_class (klass
, inst
, is_dynamic
);
2343 return mono_generic_class_get_class (gclass
);
2346 static MonoReflectionMethod
*
2347 reflection_bind_generic_method_parameters (MonoReflectionMethod
*rmethod
, MonoArray
*types
, MonoError
*error
)
2350 MonoMethod
*method
, *inflated
;
2351 MonoMethodInflated
*imethod
;
2352 MonoGenericContext tmp_context
;
2353 MonoGenericInst
*ginst
;
2354 MonoType
**type_argv
;
2357 mono_error_init (error
);
2359 g_assert (strcmp (rmethod
->object
.vtable
->klass
->name
, "MethodBuilder"));
2361 method
= rmethod
->method
;
2363 klass
= method
->klass
;
2365 if (method
->is_inflated
)
2366 method
= ((MonoMethodInflated
*) method
)->declaring
;
2368 count
= mono_method_signature (method
)->generic_param_count
;
2369 if (count
!= mono_array_length (types
))
2372 type_argv
= g_new0 (MonoType
*, count
);
2373 for (i
= 0; i
< count
; i
++) {
2374 MonoReflectionType
*garg
= (MonoReflectionType
*)mono_array_get (types
, gpointer
, i
);
2375 type_argv
[i
] = mono_reflection_type_get_handle (garg
, error
);
2376 if (!is_ok (error
)) {
2381 ginst
= mono_metadata_get_generic_inst (count
, type_argv
);
2384 tmp_context
.class_inst
= mono_class_is_ginst (klass
) ? mono_class_get_generic_class (klass
)->context
.class_inst
: NULL
;
2385 tmp_context
.method_inst
= ginst
;
2387 inflated
= mono_class_inflate_generic_method_checked (method
, &tmp_context
, error
);
2388 mono_error_assert_ok (error
);
2389 imethod
= (MonoMethodInflated
*) inflated
;
2391 /*FIXME but I think this is no longer necessary*/
2392 if (image_is_dynamic (method
->klass
->image
)) {
2393 MonoDynamicImage
*image
= (MonoDynamicImage
*)method
->klass
->image
;
2395 * This table maps metadata structures representing inflated methods/fields
2396 * to the reflection objects representing their generic definitions.
2398 mono_image_lock ((MonoImage
*)image
);
2399 mono_g_hash_table_insert (image
->generic_def_objects
, imethod
, rmethod
);
2400 mono_image_unlock ((MonoImage
*)image
);
2403 if (!mono_verifier_is_method_valid_generic_instantiation (inflated
)) {
2404 mono_error_set_argument (error
, "typeArguments", "Invalid generic arguments");
2408 return mono_method_get_object_checked (mono_object_domain (rmethod
), inflated
, NULL
, error
);
2411 MonoReflectionMethod
*
2412 ves_icall_MonoMethod_MakeGenericMethod_impl (MonoReflectionMethod
*rmethod
, MonoArray
*types
)
2415 MonoReflectionMethod
*result
= reflection_bind_generic_method_parameters (rmethod
, types
, &error
);
2416 mono_error_set_pending_exception (&error
);
2421 /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
2422 const static guint32 declsec_flags_map
[] = {
2423 0x00000000, /* empty */
2424 MONO_DECLSEC_FLAG_REQUEST
, /* SECURITY_ACTION_REQUEST (x01) */
2425 MONO_DECLSEC_FLAG_DEMAND
, /* SECURITY_ACTION_DEMAND (x02) */
2426 MONO_DECLSEC_FLAG_ASSERT
, /* SECURITY_ACTION_ASSERT (x03) */
2427 MONO_DECLSEC_FLAG_DENY
, /* SECURITY_ACTION_DENY (x04) */
2428 MONO_DECLSEC_FLAG_PERMITONLY
, /* SECURITY_ACTION_PERMITONLY (x05) */
2429 MONO_DECLSEC_FLAG_LINKDEMAND
, /* SECURITY_ACTION_LINKDEMAND (x06) */
2430 MONO_DECLSEC_FLAG_INHERITANCEDEMAND
, /* SECURITY_ACTION_INHERITANCEDEMAND (x07) */
2431 MONO_DECLSEC_FLAG_REQUEST_MINIMUM
, /* SECURITY_ACTION_REQUEST_MINIMUM (x08) */
2432 MONO_DECLSEC_FLAG_REQUEST_OPTIONAL
, /* SECURITY_ACTION_REQUEST_OPTIONAL (x09) */
2433 MONO_DECLSEC_FLAG_REQUEST_REFUSE
, /* SECURITY_ACTION_REQUEST_REFUSE (x0A) */
2434 MONO_DECLSEC_FLAG_PREJIT_GRANT
, /* SECURITY_ACTION_PREJIT_GRANT (x0B) */
2435 MONO_DECLSEC_FLAG_PREJIT_DENY
, /* SECURITY_ACTION_PREJIT_DENY (x0C) */
2436 MONO_DECLSEC_FLAG_NONCAS_DEMAND
, /* SECURITY_ACTION_NONCAS_DEMAND (x0D) */
2437 MONO_DECLSEC_FLAG_NONCAS_LINKDEMAND
, /* SECURITY_ACTION_NONCAS_LINKDEMAND (x0E) */
2438 MONO_DECLSEC_FLAG_NONCAS_INHERITANCEDEMAND
, /* SECURITY_ACTION_NONCAS_INHERITANCEDEMAND (x0F) */
2439 MONO_DECLSEC_FLAG_LINKDEMAND_CHOICE
, /* SECURITY_ACTION_LINKDEMAND_CHOICE (x10) */
2440 MONO_DECLSEC_FLAG_INHERITANCEDEMAND_CHOICE
, /* SECURITY_ACTION_INHERITANCEDEMAND_CHOICE (x11) */
2441 MONO_DECLSEC_FLAG_DEMAND_CHOICE
, /* SECURITY_ACTION_DEMAND_CHOICE (x12) */
2445 * Returns flags that includes all available security action associated to the handle.
2446 * @token: metadata token (either for a class or a method)
2447 * @image: image where resides the metadata.
2450 mono_declsec_get_flags (MonoImage
*image
, guint32 token
)
2452 int index
= mono_metadata_declsec_from_index (image
, token
);
2453 MonoTableInfo
*t
= &image
->tables
[MONO_TABLE_DECLSECURITY
];
2458 /* HasSecurity can be present for other, not specially encoded, attributes,
2459 e.g. SuppressUnmanagedCodeSecurityAttribute */
2463 for (i
= index
; i
< t
->rows
; i
++) {
2464 guint32 cols
[MONO_DECL_SECURITY_SIZE
];
2466 mono_metadata_decode_row (t
, i
, cols
, MONO_DECL_SECURITY_SIZE
);
2467 if (cols
[MONO_DECL_SECURITY_PARENT
] != token
)
2470 action
= cols
[MONO_DECL_SECURITY_ACTION
];
2471 if ((action
>= MONO_DECLSEC_ACTION_MIN
) && (action
<= MONO_DECLSEC_ACTION_MAX
)) {
2472 result
|= declsec_flags_map
[action
];
2474 g_assert_not_reached ();
2481 * Get the security actions (in the form of flags) associated with the specified method.
2483 * @method: The method for which we want the declarative security flags.
2484 * Return the declarative security flags for the method (only).
2486 * Note: To keep MonoMethod size down we do not cache the declarative security flags
2487 * (except for the stack modifiers which are kept in the MonoJitInfo structure)
2490 mono_declsec_flags_from_method (MonoMethod
*method
)
2492 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2493 /* FIXME: No cache (for the moment) */
2494 guint32 idx
= mono_method_get_index (method
);
2495 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2496 idx
|= MONO_HAS_DECL_SECURITY_METHODDEF
;
2497 return mono_declsec_get_flags (method
->klass
->image
, idx
);
2503 * Get the security actions (in the form of flags) associated with the specified class.
2505 * @klass: The class for which we want the declarative security flags.
2506 * Return the declarative security flags for the class.
2508 * Note: We cache the flags inside the MonoClass structure as this will get
2509 * called very often (at least for each method).
2512 mono_declsec_flags_from_class (MonoClass
*klass
)
2514 if (mono_class_get_flags (klass
) & TYPE_ATTRIBUTE_HAS_SECURITY
) {
2515 guint32 flags
= mono_class_get_declsec_flags (klass
);
2520 idx
= mono_metadata_token_index (klass
->type_token
);
2521 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2522 idx
|= MONO_HAS_DECL_SECURITY_TYPEDEF
;
2523 flags
= mono_declsec_get_flags (klass
->image
, idx
);
2524 /* we cache the flags on classes */
2525 mono_class_set_declsec_flags (klass
, flags
);
2533 * Get the security actions (in the form of flags) associated with the specified assembly.
2535 * @assembly: The assembly for which we want the declarative security flags.
2536 * Return the declarative security flags for the assembly.
2539 mono_declsec_flags_from_assembly (MonoAssembly
*assembly
)
2541 guint32 idx
= 1; /* there is only one assembly */
2542 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2543 idx
|= MONO_HAS_DECL_SECURITY_ASSEMBLY
;
2544 return mono_declsec_get_flags (assembly
->image
, idx
);
2549 * Fill actions for the specific index (which may either be an encoded class token or
2550 * an encoded method token) from the metadata image.
2551 * Returns TRUE if some actions requiring code generation are present, FALSE otherwise.
2554 fill_actions_from_index (MonoImage
*image
, guint32 token
, MonoDeclSecurityActions
* actions
,
2555 guint32 id_std
, guint32 id_noncas
, guint32 id_choice
)
2557 MonoBoolean result
= FALSE
;
2559 guint32 cols
[MONO_DECL_SECURITY_SIZE
];
2560 int index
= mono_metadata_declsec_from_index (image
, token
);
2563 t
= &image
->tables
[MONO_TABLE_DECLSECURITY
];
2564 for (i
= index
; i
< t
->rows
; i
++) {
2565 mono_metadata_decode_row (t
, i
, cols
, MONO_DECL_SECURITY_SIZE
);
2567 if (cols
[MONO_DECL_SECURITY_PARENT
] != token
)
2570 /* if present only replace (class) permissions with method permissions */
2571 /* if empty accept either class or method permissions */
2572 if (cols
[MONO_DECL_SECURITY_ACTION
] == id_std
) {
2573 if (!actions
->demand
.blob
) {
2574 const char *blob
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2575 actions
->demand
.index
= cols
[MONO_DECL_SECURITY_PERMISSIONSET
];
2576 actions
->demand
.blob
= (char*) (blob
+ 2);
2577 actions
->demand
.size
= mono_metadata_decode_blob_size (blob
, &blob
);
2580 } else if (cols
[MONO_DECL_SECURITY_ACTION
] == id_noncas
) {
2581 if (!actions
->noncasdemand
.blob
) {
2582 const char *blob
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2583 actions
->noncasdemand
.index
= cols
[MONO_DECL_SECURITY_PERMISSIONSET
];
2584 actions
->noncasdemand
.blob
= (char*) (blob
+ 2);
2585 actions
->noncasdemand
.size
= mono_metadata_decode_blob_size (blob
, &blob
);
2588 } else if (cols
[MONO_DECL_SECURITY_ACTION
] == id_choice
) {
2589 if (!actions
->demandchoice
.blob
) {
2590 const char *blob
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2591 actions
->demandchoice
.index
= cols
[MONO_DECL_SECURITY_PERMISSIONSET
];
2592 actions
->demandchoice
.blob
= (char*) (blob
+ 2);
2593 actions
->demandchoice
.size
= mono_metadata_decode_blob_size (blob
, &blob
);
2603 mono_declsec_get_class_demands_params (MonoClass
*klass
, MonoDeclSecurityActions
* demands
,
2604 guint32 id_std
, guint32 id_noncas
, guint32 id_choice
)
2606 guint32 idx
= mono_metadata_token_index (klass
->type_token
);
2607 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2608 idx
|= MONO_HAS_DECL_SECURITY_TYPEDEF
;
2609 return fill_actions_from_index (klass
->image
, idx
, demands
, id_std
, id_noncas
, id_choice
);
2613 mono_declsec_get_method_demands_params (MonoMethod
*method
, MonoDeclSecurityActions
* demands
,
2614 guint32 id_std
, guint32 id_noncas
, guint32 id_choice
)
2616 guint32 idx
= mono_method_get_index (method
);
2617 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2618 idx
|= MONO_HAS_DECL_SECURITY_METHODDEF
;
2619 return fill_actions_from_index (method
->klass
->image
, idx
, demands
, id_std
, id_noncas
, id_choice
);
2623 * Collect all actions (that requires to generate code in mini) assigned for
2624 * the specified method.
2625 * Note: Don't use the content of actions if the function return FALSE.
2628 mono_declsec_get_demands (MonoMethod
*method
, MonoDeclSecurityActions
* demands
)
2630 guint32 mask
= MONO_DECLSEC_FLAG_DEMAND
| MONO_DECLSEC_FLAG_NONCAS_DEMAND
|
2631 MONO_DECLSEC_FLAG_DEMAND_CHOICE
;
2632 MonoBoolean result
= FALSE
;
2635 /* quick exit if no declarative security is present in the metadata */
2636 if (!method
->klass
->image
->tables
[MONO_TABLE_DECLSECURITY
].rows
)
2639 /* we want the original as the wrapper is "free" of the security informations */
2640 if (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_MANAGED
) {
2641 method
= mono_marshal_method_from_wrapper (method
);
2646 /* First we look for method-level attributes */
2647 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2648 mono_class_init (method
->klass
);
2649 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
2651 result
= mono_declsec_get_method_demands_params (method
, demands
,
2652 SECURITY_ACTION_DEMAND
, SECURITY_ACTION_NONCASDEMAND
, SECURITY_ACTION_DEMANDCHOICE
);
2655 /* Here we use (or create) the class declarative cache to look for demands */
2656 flags
= mono_declsec_flags_from_class (method
->klass
);
2659 mono_class_init (method
->klass
);
2660 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
2662 result
|= mono_declsec_get_class_demands_params (method
->klass
, demands
,
2663 SECURITY_ACTION_DEMAND
, SECURITY_ACTION_NONCASDEMAND
, SECURITY_ACTION_DEMANDCHOICE
);
2666 /* The boolean return value is used as a shortcut in case nothing needs to
2667 be generated (e.g. LinkDemand[Choice] and InheritanceDemand[Choice]) */
2673 * Collect all Link actions: LinkDemand, NonCasLinkDemand and LinkDemandChoice (2.0).
2675 * Note: Don't use the content of actions if the function return FALSE.
2678 mono_declsec_get_linkdemands (MonoMethod
*method
, MonoDeclSecurityActions
* klass
, MonoDeclSecurityActions
*cmethod
)
2680 MonoBoolean result
= FALSE
;
2683 /* quick exit if no declarative security is present in the metadata */
2684 if (!method
->klass
->image
->tables
[MONO_TABLE_DECLSECURITY
].rows
)
2687 /* we want the original as the wrapper is "free" of the security informations */
2688 if (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_MANAGED
) {
2689 method
= mono_marshal_method_from_wrapper (method
);
2694 /* results are independant - zeroize both */
2695 memset (cmethod
, 0, sizeof (MonoDeclSecurityActions
));
2696 memset (klass
, 0, sizeof (MonoDeclSecurityActions
));
2698 /* First we look for method-level attributes */
2699 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2700 mono_class_init (method
->klass
);
2702 result
= mono_declsec_get_method_demands_params (method
, cmethod
,
2703 SECURITY_ACTION_LINKDEMAND
, SECURITY_ACTION_NONCASLINKDEMAND
, SECURITY_ACTION_LINKDEMANDCHOICE
);
2706 /* Here we use (or create) the class declarative cache to look for demands */
2707 flags
= mono_declsec_flags_from_class (method
->klass
);
2708 if (flags
& (MONO_DECLSEC_FLAG_LINKDEMAND
| MONO_DECLSEC_FLAG_NONCAS_LINKDEMAND
| MONO_DECLSEC_FLAG_LINKDEMAND_CHOICE
)) {
2709 mono_class_init (method
->klass
);
2711 result
|= mono_declsec_get_class_demands_params (method
->klass
, klass
,
2712 SECURITY_ACTION_LINKDEMAND
, SECURITY_ACTION_NONCASLINKDEMAND
, SECURITY_ACTION_LINKDEMANDCHOICE
);
2719 * Collect all Inherit actions: InheritanceDemand, NonCasInheritanceDemand and InheritanceDemandChoice (2.0).
2721 * @klass The inherited class - this is the class that provides the security check (attributes)
2723 * return TRUE if inheritance demands (any kind) are present, FALSE otherwise.
2725 * Note: Don't use the content of actions if the function return FALSE.
2728 mono_declsec_get_inheritdemands_class (MonoClass
*klass
, MonoDeclSecurityActions
* demands
)
2730 MonoBoolean result
= FALSE
;
2733 /* quick exit if no declarative security is present in the metadata */
2734 if (!klass
->image
->tables
[MONO_TABLE_DECLSECURITY
].rows
)
2737 /* Here we use (or create) the class declarative cache to look for demands */
2738 flags
= mono_declsec_flags_from_class (klass
);
2739 if (flags
& (MONO_DECLSEC_FLAG_INHERITANCEDEMAND
| MONO_DECLSEC_FLAG_NONCAS_INHERITANCEDEMAND
| MONO_DECLSEC_FLAG_INHERITANCEDEMAND_CHOICE
)) {
2740 mono_class_init (klass
);
2741 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
2743 result
|= mono_declsec_get_class_demands_params (klass
, demands
,
2744 SECURITY_ACTION_INHERITDEMAND
, SECURITY_ACTION_NONCASINHERITANCE
, SECURITY_ACTION_INHERITDEMANDCHOICE
);
2751 * Collect all Inherit actions: InheritanceDemand, NonCasInheritanceDemand and InheritanceDemandChoice (2.0).
2753 * Note: Don't use the content of actions if the function return FALSE.
2756 mono_declsec_get_inheritdemands_method (MonoMethod
*method
, MonoDeclSecurityActions
* demands
)
2758 /* quick exit if no declarative security is present in the metadata */
2759 if (!method
->klass
->image
->tables
[MONO_TABLE_DECLSECURITY
].rows
)
2762 /* we want the original as the wrapper is "free" of the security informations */
2763 if (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_MANAGED
) {
2764 method
= mono_marshal_method_from_wrapper (method
);
2769 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2770 mono_class_init (method
->klass
);
2771 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
2773 return mono_declsec_get_method_demands_params (method
, demands
,
2774 SECURITY_ACTION_INHERITDEMAND
, SECURITY_ACTION_NONCASINHERITANCE
, SECURITY_ACTION_INHERITDEMANDCHOICE
);
2781 get_declsec_action (MonoImage
*image
, guint32 token
, guint32 action
, MonoDeclSecurityEntry
*entry
)
2783 guint32 cols
[MONO_DECL_SECURITY_SIZE
];
2787 int index
= mono_metadata_declsec_from_index (image
, token
);
2791 t
= &image
->tables
[MONO_TABLE_DECLSECURITY
];
2792 for (i
= index
; i
< t
->rows
; i
++) {
2793 mono_metadata_decode_row (t
, i
, cols
, MONO_DECL_SECURITY_SIZE
);
2795 /* shortcut - index are ordered */
2796 if (token
!= cols
[MONO_DECL_SECURITY_PARENT
])
2799 if (cols
[MONO_DECL_SECURITY_ACTION
] == action
) {
2800 const char *metadata
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2801 entry
->blob
= (char*) (metadata
+ 2);
2802 entry
->size
= mono_metadata_decode_blob_size (metadata
, &metadata
);
2811 mono_declsec_get_method_action (MonoMethod
*method
, guint32 action
, MonoDeclSecurityEntry
*entry
)
2813 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2814 guint32 idx
= mono_method_get_index (method
);
2815 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2816 idx
|= MONO_HAS_DECL_SECURITY_METHODDEF
;
2817 return get_declsec_action (method
->klass
->image
, idx
, action
, entry
);
2823 mono_declsec_get_class_action (MonoClass
*klass
, guint32 action
, MonoDeclSecurityEntry
*entry
)
2826 guint32 flags
= mono_declsec_flags_from_class (klass
);
2827 if (declsec_flags_map
[action
] & flags
) {
2828 guint32 idx
= mono_metadata_token_index (klass
->type_token
);
2829 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2830 idx
|= MONO_HAS_DECL_SECURITY_TYPEDEF
;
2831 return get_declsec_action (klass
->image
, idx
, action
, entry
);
2837 mono_declsec_get_assembly_action (MonoAssembly
*assembly
, guint32 action
, MonoDeclSecurityEntry
*entry
)
2839 guint32 idx
= 1; /* there is only one assembly */
2840 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2841 idx
|= MONO_HAS_DECL_SECURITY_ASSEMBLY
;
2843 return get_declsec_action (assembly
->image
, idx
, action
, entry
);
2847 mono_reflection_call_is_assignable_to (MonoClass
*klass
, MonoClass
*oklass
, MonoError
*error
)
2849 MonoObject
*res
, *exc
;
2851 static MonoMethod
*method
= NULL
;
2853 mono_error_init (error
);
2855 if (method
== NULL
) {
2856 method
= mono_class_get_method_from_name (mono_class_get_type_builder_class (), "IsAssignableTo", 1);
2861 * The result of mono_type_get_object_checked () might be a System.MonoType but we
2862 * need a TypeBuilder so use mono_class_get_ref_info (klass).
2864 g_assert (mono_class_get_ref_info (klass
));
2865 g_assert (!strcmp (((MonoObject
*)(mono_class_get_ref_info (klass
)))->vtable
->klass
->name
, "TypeBuilder"));
2867 params
[0] = mono_type_get_object_checked (mono_domain_get (), &oklass
->byval_arg
, error
);
2868 return_val_if_nok (error
, FALSE
);
2870 MonoError inner_error
;
2871 res
= mono_runtime_try_invoke (method
, (MonoObject
*)(mono_class_get_ref_info (klass
)), params
, &exc
, &inner_error
);
2873 if (exc
|| !is_ok (&inner_error
)) {
2874 mono_error_cleanup (&inner_error
);
2877 return *(MonoBoolean
*)mono_object_unbox (res
);
2881 * mono_reflection_type_get_type:
2882 * @reftype: the System.Type object
2884 * Returns the MonoType* associated with the C# System.Type object @reftype.
2887 mono_reflection_type_get_type (MonoReflectionType
*reftype
)
2892 MonoType
*result
= mono_reflection_type_get_handle (reftype
, &error
);
2893 mono_error_assert_ok (&error
);
2898 * mono_reflection_assembly_get_assembly:
2899 * @refassembly: the System.Reflection.Assembly object
2901 * Returns the MonoAssembly* associated with the C# System.Reflection.Assembly object @refassembly.
2904 mono_reflection_assembly_get_assembly (MonoReflectionAssembly
*refassembly
)
2906 g_assert (refassembly
);
2908 return refassembly
->assembly
;
2912 * mono_class_from_mono_type_handle:
2913 * @reftype: the System.Type handle
2915 * Returns the MonoClass* corresponding to the given type.
2918 mono_class_from_mono_type_handle (MonoReflectionTypeHandle reftype
)
2920 return mono_class_from_mono_type (MONO_HANDLE_RAW (reftype
)->type
);