3 * System.Type icalls and related reflection queries.
6 * Paolo Molaro (lupus@ximian.com)
8 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
9 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
10 * Copyright 2011 Rodrigo Kumpera
11 * Copyright 2016 Microsoft
13 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
16 #include "mono/utils/mono-membar.h"
17 #include "mono/metadata/assembly-internals.h"
18 #include "mono/metadata/reflection-internals.h"
19 #include "mono/metadata/tabledefs.h"
20 #include "mono/metadata/metadata-internals.h"
21 #include <mono/metadata/profiler-private.h>
22 #include "mono/metadata/class-internals.h"
23 #include "mono/metadata/class-init.h"
24 #include "mono/metadata/gc-internals.h"
25 #include "mono/metadata/domain-internals.h"
26 #include "mono/metadata/opcodes.h"
27 #include "mono/metadata/assembly.h"
28 #include "mono/metadata/object-internals.h"
29 #include <mono/metadata/exception.h>
30 #include <mono/metadata/marshal.h>
31 #include <mono/metadata/security-manager.h>
32 #include <mono/metadata/reflection-cache.h>
33 #include <mono/metadata/sre-internals.h>
42 #include "mono-endian.h"
43 #include <mono/metadata/gc-internals.h>
44 #include <mono/metadata/mempool-internals.h>
45 #include <mono/metadata/security-core-clr.h>
46 #include <mono/metadata/debug-helpers.h>
47 #include <mono/metadata/verify-internals.h>
48 #include <mono/metadata/mono-ptr-array.h>
49 #include <mono/metadata/mono-hash-internals.h>
50 #include <mono/utils/mono-string.h>
51 #include <mono/utils/mono-error-internals.h>
52 #include <mono/utils/checked-build.h>
53 #include <mono/utils/mono-counters.h>
54 #include "icall-decl.h"
56 static void get_default_param_value_blobs (MonoMethod
*method
, char **blobs
, guint32
*types
);
57 static MonoType
* mono_reflection_get_type_with_rootimage (MonoAssemblyLoadContext
*alc
, MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, gboolean
*type_resolve
, MonoError
*error
);
59 /* Class lazy loading functions */
60 static GENERATE_GET_CLASS_WITH_CACHE (mono_assembly
, "System.Reflection", "RuntimeAssembly")
61 static GENERATE_GET_CLASS_WITH_CACHE (mono_module
, "System.Reflection", "RuntimeModule")
62 static GENERATE_GET_CLASS_WITH_CACHE (mono_method
, "System.Reflection", "RuntimeMethodInfo");
63 static GENERATE_GET_CLASS_WITH_CACHE (mono_cmethod
, "System.Reflection", "RuntimeConstructorInfo");
64 static GENERATE_GET_CLASS_WITH_CACHE (mono_field
, "System.Reflection", "RuntimeFieldInfo");
65 static GENERATE_GET_CLASS_WITH_CACHE (mono_event
, "System.Reflection", "RuntimeEventInfo");
66 static GENERATE_GET_CLASS_WITH_CACHE (mono_property
, "System.Reflection", "RuntimePropertyInfo");
67 static GENERATE_GET_CLASS_WITH_CACHE (mono_parameter_info
, "System.Reflection", "RuntimeParameterInfo");
68 static GENERATE_GET_CLASS_WITH_CACHE (missing
, "System.Reflection", "Missing");
70 static GENERATE_GET_CLASS_WITH_CACHE (method_body
, "System.Reflection", "RuntimeMethodBody");
71 static GENERATE_GET_CLASS_WITH_CACHE (local_variable_info
, "System.Reflection", "RuntimeLocalVariableInfo");
72 static GENERATE_GET_CLASS_WITH_CACHE (exception_handling_clause
, "System.Reflection", "RuntimeExceptionHandlingClause");
74 static GENERATE_GET_CLASS_WITH_CACHE (method_body
, "System.Reflection", "MethodBody");
75 static GENERATE_GET_CLASS_WITH_CACHE (local_variable_info
, "System.Reflection", "LocalVariableInfo");
76 static GENERATE_GET_CLASS_WITH_CACHE (exception_handling_clause
, "System.Reflection", "ExceptionHandlingClause");
78 static GENERATE_GET_CLASS_WITH_CACHE (type_builder
, "System.Reflection.Emit", "TypeBuilder");
79 static GENERATE_GET_CLASS_WITH_CACHE (dbnull
, "System", "DBNull");
82 static int class_ref_info_handle_count
;
85 mono_reflection_init (void)
87 mono_reflection_emit_init ();
89 mono_counters_register ("MonoClass::ref_info_handle count",
90 MONO_COUNTER_METADATA
| MONO_COUNTER_INT
, &class_ref_info_handle_count
);
95 * mono_class_get_ref_info:
97 * Return the type builder corresponding to KLASS, if it exists.
99 MonoReflectionTypeBuilderHandle
100 mono_class_get_ref_info (MonoClass
*klass
)
102 MONO_REQ_GC_UNSAFE_MODE
;
103 guint32 ref_info_handle
= mono_class_get_ref_info_handle (klass
);
105 if (ref_info_handle
== 0)
106 return MONO_HANDLE_NEW (MonoReflectionTypeBuilder
, NULL
);
107 return MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, mono_gchandle_get_target_handle (ref_info_handle
));
111 mono_class_has_ref_info (MonoClass
*klass
)
113 MONO_REQ_GC_UNSAFE_MODE
;
114 return 0 != mono_class_get_ref_info_handle (klass
);
117 MonoReflectionTypeBuilder
*
118 mono_class_get_ref_info_raw (MonoClass
*klass
)
120 /* FIXME callers of mono_class_get_ref_info_raw should use handles */
121 MONO_REQ_GC_UNSAFE_MODE
;
122 guint32 ref_info_handle
= mono_class_get_ref_info_handle (klass
);
124 if (ref_info_handle
== 0)
126 return (MonoReflectionTypeBuilder
*)mono_gchandle_get_target_internal (ref_info_handle
);
130 mono_class_set_ref_info (MonoClass
*klass
, MonoObjectHandle obj
)
132 MONO_REQ_GC_UNSAFE_MODE
;
134 guint32 candidate
= mono_gchandle_from_handle (obj
, FALSE
);
135 guint32 handle
= mono_class_set_ref_info_handle (klass
, candidate
);
136 ++class_ref_info_handle_count
;
138 if (handle
!= candidate
)
139 mono_gchandle_free_internal (candidate
);
143 mono_class_free_ref_info (MonoClass
*klass
)
145 MONO_REQ_GC_NEUTRAL_MODE
;
146 guint32 handle
= mono_class_get_ref_info_handle (klass
);
149 mono_gchandle_free_internal (handle
);
150 mono_class_set_ref_info_handle (klass
, 0);
155 * mono_custom_attrs_free:
158 mono_custom_attrs_free (MonoCustomAttrInfo
*ainfo
)
160 MONO_REQ_GC_NEUTRAL_MODE
;
162 if (ainfo
&& !ainfo
->cached
)
167 mono_reflected_equal (gconstpointer a
, gconstpointer b
)
169 const ReflectedEntry
*ea
= (const ReflectedEntry
*)a
;
170 const ReflectedEntry
*eb
= (const ReflectedEntry
*)b
;
172 return (ea
->item
== eb
->item
) && (ea
->refclass
== eb
->refclass
);
176 mono_reflected_hash (gconstpointer a
) {
177 const ReflectedEntry
*ea
= (const ReflectedEntry
*)a
;
178 /* Combine hashes for item and refclass. Identical to boost's hash_combine */
179 guint seed
= mono_aligned_addr_hash (ea
->item
) + 0x9e3779b9;
180 seed
^= mono_aligned_addr_hash (ea
->refclass
) + 0x9e3779b9 + (seed
<< 6) + (seed
>> 2);
185 clear_cached_object (MonoDomain
*domain
, gpointer o
, MonoClass
*klass
)
187 mono_domain_lock (domain
);
188 if (domain
->refobject_hash
) {
190 gpointer orig_pe
, orig_value
;
195 if (mono_conc_g_hash_table_lookup_extended (domain
->refobject_hash
, &pe
, &orig_pe
, &orig_value
)) {
196 mono_conc_g_hash_table_remove (domain
->refobject_hash
, &pe
);
197 free_reflected_entry ((ReflectedEntry
*)orig_pe
);
200 mono_domain_unlock (domain
);
204 cleanup_refobject_hash (gpointer key
, gpointer value
, gpointer user_data
)
206 free_reflected_entry ((ReflectedEntry
*)key
);
210 mono_reflection_cleanup_domain (MonoDomain
*domain
)
212 if (domain
->refobject_hash
) {
213 mono_conc_g_hash_table_foreach (domain
->refobject_hash
, cleanup_refobject_hash
, NULL
);
214 mono_conc_g_hash_table_destroy (domain
->refobject_hash
);
215 domain
->refobject_hash
= NULL
;
220 * mono_assembly_get_object:
221 * \param domain an app domain
222 * \param assembly an assembly
223 * \returns a \c System.Reflection.Assembly object representing the \c MonoAssembly \p assembly.
225 MonoReflectionAssembly
*
226 mono_assembly_get_object (MonoDomain
*domain
, MonoAssembly
*assembly
)
228 HANDLE_FUNCTION_ENTER ();
229 MonoReflectionAssemblyHandle result
;
230 MONO_ENTER_GC_UNSAFE
;
232 result
= mono_assembly_get_object_handle (domain
, assembly
, error
);
233 mono_error_cleanup (error
); /* FIXME new API that doesn't swallow the error */
235 HANDLE_FUNCTION_RETURN_OBJ (result
);
238 static MonoReflectionAssemblyHandle
239 assembly_object_construct (MonoDomain
*domain
, MonoClass
*unused_klass
, MonoAssembly
*assembly
, gpointer user_data
, MonoError
*error
)
242 MonoReflectionAssemblyHandle res
= MONO_HANDLE_CAST (MonoReflectionAssembly
, mono_object_new_handle (domain
, mono_class_get_mono_assembly_class (), error
));
243 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoReflectionAssembly
, NULL_HANDLE
));
244 MONO_HANDLE_SETVAL (res
, assembly
, MonoAssembly
*, assembly
);
249 * mono_assembly_get_object_handle:
250 * @domain: an app domain
251 * @assembly: an assembly
253 * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
255 MonoReflectionAssemblyHandle
256 mono_assembly_get_object_handle (MonoDomain
*domain
, MonoAssembly
*assembly
, MonoError
*error
)
259 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionAssembly
, assembly
, NULL
, assembly_object_construct
, NULL
);
263 * mono_module_get_object:
265 MonoReflectionModule
*
266 mono_module_get_object (MonoDomain
*domain
, MonoImage
*image
)
268 HANDLE_FUNCTION_ENTER ();
270 MonoReflectionModuleHandle result
= mono_module_get_object_handle (domain
, image
, error
);
271 mono_error_cleanup (error
);
272 HANDLE_FUNCTION_RETURN_OBJ (result
);
275 static MonoReflectionModuleHandle
276 module_object_construct (MonoDomain
*domain
, MonoClass
*unused_klass
, MonoImage
*image
, gpointer user_data
, MonoError
*error
)
281 MonoReflectionModuleHandle res
= MONO_HANDLE_CAST (MonoReflectionModule
, mono_object_new_handle (domain
, mono_class_get_mono_module_class (), error
));
282 goto_if_nok (error
, fail
);
284 MONO_HANDLE_SETVAL (res
, image
, MonoImage
*, image
);
285 MonoReflectionAssemblyHandle assm_obj
;
286 assm_obj
= mono_assembly_get_object_handle (domain
, image
->assembly
, error
);
287 goto_if_nok (error
, fail
);
288 MONO_HANDLE_SET (res
, assembly
, assm_obj
);
290 MONO_HANDLE_SET (res
, fqname
, mono_string_new_handle (domain
, image
->name
, error
));
291 goto_if_nok (error
, fail
);
292 basename
= g_path_get_basename (image
->name
);
293 MONO_HANDLE_SET (res
, name
, mono_string_new_handle (domain
, basename
, error
));
294 goto_if_nok (error
, fail
);
295 MONO_HANDLE_SET (res
, scopename
, mono_string_new_handle (domain
, image
->module_name
, error
));
296 goto_if_nok (error
, fail
);
302 if (image
->assembly
->image
== image
) {
303 token
= mono_metadata_make_token (MONO_TABLE_MODULE
, 1);
306 if (image
->assembly
->image
->modules
) {
307 for (i
= 0; i
< image
->assembly
->image
->module_count
; i
++) {
308 if (image
->assembly
->image
->modules
[i
] == image
)
309 token
= mono_metadata_make_token (MONO_TABLE_MODULEREF
, i
+ 1);
311 g_assert (token
!= 0);
314 MONO_HANDLE_SETVAL (res
, token
, guint32
, token
);
318 return MONO_HANDLE_CAST (MonoReflectionModule
, NULL_HANDLE
);
321 MonoReflectionModuleHandle
322 mono_module_get_object_handle (MonoDomain
*domain
, MonoImage
*image
, MonoError
*error
)
325 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionModule
, image
, NULL
, module_object_construct
, NULL
);
329 * mono_module_file_get_object:
331 MonoReflectionModule
*
332 mono_module_file_get_object (MonoDomain
*domain
, MonoImage
*image
, int table_index
)
334 HANDLE_FUNCTION_ENTER ();
336 MonoReflectionModuleHandle result
= mono_module_file_get_object_handle (domain
, image
, table_index
, error
);
337 mono_error_cleanup (error
);
338 HANDLE_FUNCTION_RETURN_OBJ (result
);
341 MonoReflectionModuleHandle
342 mono_module_file_get_object_handle (MonoDomain
*domain
, MonoImage
*image
, int table_index
, MonoError
*error
)
344 MonoTableInfo
*table
;
345 guint32 cols
[MONO_FILE_SIZE
];
352 MonoReflectionModuleHandle res
= MONO_HANDLE_CAST (MonoReflectionModule
, mono_object_new_handle (domain
, mono_class_get_mono_module_class (), error
));
353 goto_if_nok (error
, fail
);
355 table
= &image
->tables
[MONO_TABLE_FILE
];
356 g_assert (table_index
< table
->rows
);
357 mono_metadata_decode_row (table
, table_index
, cols
, MONO_FILE_SIZE
);
359 MONO_HANDLE_SETVAL (res
, image
, MonoImage
*, NULL
);
360 MonoReflectionAssemblyHandle assm_obj
;
361 assm_obj
= mono_assembly_get_object_handle (domain
, image
->assembly
, error
);
362 goto_if_nok (error
, fail
);
363 MONO_HANDLE_SET (res
, assembly
, assm_obj
);
364 name
= mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]);
366 /* Check whenever the row has a corresponding row in the moduleref table */
367 table
= &image
->tables
[MONO_TABLE_MODULEREF
];
368 for (i
= 0; i
< table
->rows
; ++i
) {
369 name_idx
= mono_metadata_decode_row_col (table
, i
, MONO_MODULEREF_NAME
);
370 val
= mono_metadata_string_heap (image
, name_idx
);
371 if (strcmp (val
, name
) == 0)
372 MONO_HANDLE_SETVAL (res
, image
, MonoImage
*, image
->modules
[i
]);
375 MONO_HANDLE_SET (res
, fqname
, mono_string_new_handle (domain
, name
, error
));
376 goto_if_nok (error
, fail
);
377 MONO_HANDLE_SET (res
, name
, mono_string_new_handle (domain
, name
, error
));
378 goto_if_nok (error
, fail
);
379 MONO_HANDLE_SET (res
, scopename
, mono_string_new_handle (domain
, name
, error
));
380 goto_if_nok (error
, fail
);
381 MONO_HANDLE_SETVAL (res
, is_resource
, MonoBoolean
, cols
[MONO_FILE_FLAGS
] & FILE_CONTAINS_NO_METADATA
);
382 MONO_HANDLE_SETVAL (res
, token
, guint32
, mono_metadata_make_token (MONO_TABLE_FILE
, table_index
+ 1));
386 return MONO_HANDLE_CAST (MonoReflectionModule
, NULL_HANDLE
);
390 mono_type_normalize (MonoType
*type
)
393 MonoGenericClass
*gclass
;
394 MonoGenericInst
*ginst
;
396 MonoGenericContainer
*gcontainer
;
397 MonoType
**argv
= NULL
;
398 gboolean is_denorm_gtd
= TRUE
, requires_rebind
= FALSE
;
400 if (type
->type
!= MONO_TYPE_GENERICINST
)
403 gclass
= type
->data
.generic_class
;
404 ginst
= gclass
->context
.class_inst
;
408 gtd
= gclass
->container_class
;
409 gcontainer
= mono_class_get_generic_container (gtd
);
410 argv
= g_newa (MonoType
*, ginst
->type_argc
);
412 for (i
= 0; i
< ginst
->type_argc
; ++i
) {
413 MonoType
*t
= ginst
->type_argv
[i
], *norm
;
414 if (t
->type
!= MONO_TYPE_VAR
|| t
->data
.generic_param
->num
!= i
|| t
->data
.generic_param
->owner
!= gcontainer
)
415 is_denorm_gtd
= FALSE
;
416 norm
= mono_type_normalize (t
);
419 requires_rebind
= TRUE
;
423 return type
->byref
== m_class_get_byval_arg (gtd
)->byref
? m_class_get_byval_arg (gtd
) : m_class_get_this_arg (gtd
);
425 if (requires_rebind
) {
426 MonoClass
*klass
= mono_class_bind_generic_parameters (gtd
, ginst
->type_argc
, argv
, gclass
->is_dynamic
);
427 return type
->byref
== m_class_get_byval_arg (klass
)->byref
? m_class_get_byval_arg (klass
) : m_class_get_this_arg (klass
);
434 * mono_type_get_object:
435 * \param domain an app domain
437 * \returns A \c System.MonoType object representing the type \p type.
440 mono_type_get_object (MonoDomain
*domain
, MonoType
*type
)
442 MonoReflectionType
*ret
;
443 MONO_ENTER_GC_UNSAFE
;
445 ret
= mono_type_get_object_checked (domain
, type
, error
);
446 mono_error_cleanup (error
);
452 mono_type_get_object_checked (MonoDomain
*domain
, MonoType
*type
, MonoError
*error
)
455 MonoReflectionType
*res
;
460 g_assert (type
!= NULL
);
461 klass
= mono_class_from_mono_type_internal (type
);
463 /*we must avoid using @type as it might have come
464 * from a mono_metadata_type_dup and the caller
465 * expects that is can be freed.
466 * Using the right type from
468 type
= m_class_get_byval_arg (klass
)->byref
== type
->byref
? m_class_get_byval_arg (klass
) : m_class_get_this_arg (klass
);
470 /* We don't want to return types with custom modifiers to the managed
471 * world since they're hard to distinguish from plain types using the
472 * reflection APIs, but they are not ReferenceEqual to the unadorned
475 * If we ever see cmods here, it's a bug: MonoClass:byval_arg and
476 * MonoClass:this_arg shouldn't have cmods by construction.
478 g_assert (!type
->has_cmods
);
480 /* void is very common */
481 #ifdef ENABLE_NETCORE
482 if (!type
->byref
&& type
->type
== MONO_TYPE_VOID
&& domain
->typeof_void
)
483 return (MonoReflectionType
*)domain
->typeof_void
;
485 if (type
->type
== MONO_TYPE_VOID
&& domain
->typeof_void
)
486 return (MonoReflectionType
*)domain
->typeof_void
;
490 * If the vtable of the given class was already created, we can use
491 * the MonoType from there and avoid all locking and hash table lookups.
493 * We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects
494 * that the resulting object is different.
496 if (type
== m_class_get_byval_arg (klass
) && !image_is_dynamic (m_class_get_image (klass
))) {
497 MonoVTable
*vtable
= mono_class_try_get_vtable (domain
, klass
);
498 if (vtable
&& vtable
->type
)
499 return (MonoReflectionType
*)vtable
->type
;
502 mono_loader_lock (); /*FIXME mono_class_init_internal and mono_class_vtable acquire it*/
503 mono_domain_lock (domain
);
504 if (!domain
->type_hash
)
505 domain
->type_hash
= mono_g_hash_table_new_type_internal ((GHashFunc
)mono_metadata_type_hash
,
506 (GCompareFunc
)mono_metadata_type_equal
, MONO_HASH_VALUE_GC
, MONO_ROOT_SOURCE_DOMAIN
, domain
, "Domain Reflection Type Table");
507 if ((res
= (MonoReflectionType
*)mono_g_hash_table_lookup (domain
->type_hash
, type
))) {
508 mono_domain_unlock (domain
);
509 mono_loader_unlock ();
513 /*Types must be normalized so a generic instance of the GTD get's the same inner type.
514 * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
515 * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
516 * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
517 * artifact of how generics are encoded and should be transparent to managed code so we
518 * need to weed out this diference when retrieving managed System.Type objects.
520 norm_type
= mono_type_normalize (type
);
521 if (norm_type
!= type
) {
522 res
= mono_type_get_object_checked (domain
, norm_type
, error
);
523 if (!is_ok (error
)) {
524 mono_domain_unlock (domain
);
525 mono_loader_unlock ();
528 mono_g_hash_table_insert_internal (domain
->type_hash
, type
, res
);
529 mono_domain_unlock (domain
);
530 mono_loader_unlock ();
534 if ((type
->type
== MONO_TYPE_GENERICINST
) && type
->data
.generic_class
->is_dynamic
&& !m_class_was_typebuilder (type
->data
.generic_class
->container_class
)) {
535 /* This can happen if a TypeBuilder for a generic class K<T,U>
536 * had reflection_create_generic_class) called on it, but not
537 * ves_icall_TypeBuilder_create_runtime_class. This can happen
538 * if the K`2 is refernced from a generic instantiation
539 * (e.g. K<int,string>) that appears as type argument
540 * (e.g. Dict<string,K<int,string>>), field (e.g. K<int,string>
541 * Foo) or method signature, parent class or any of the above
542 * in a nested class of some other TypeBuilder. Such an
543 * occurrence caused mono_reflection_type_get_handle to be
544 * called on the sre generic instance (K<int,string>) which
545 * required the container_class for the generic class K`2 to be
546 * set up, but the remainder of class construction for K`2 has
548 char * full_name
= mono_type_get_full_name (klass
);
549 /* I would have expected ReflectionTypeLoadException, but evidently .NET throws TLE in this case. */
550 mono_error_set_type_load_class (error
, klass
, "TypeBuilder.CreateType() not called for generic class %s", full_name
);
552 mono_domain_unlock (domain
);
553 mono_loader_unlock ();
557 if (mono_class_has_ref_info (klass
) && !m_class_was_typebuilder (klass
) && !type
->byref
) {
558 mono_domain_unlock (domain
);
559 mono_loader_unlock ();
560 return &mono_class_get_ref_info_raw (klass
)->type
; /* FIXME use handles */
562 /* This is stored in vtables/JITted code so it has to be pinned */
563 res
= (MonoReflectionType
*)mono_object_new_pinned (domain
, mono_defaults
.runtimetype_class
, error
);
564 if (!is_ok (error
)) {
565 mono_domain_unlock (domain
);
566 mono_loader_unlock ();
571 mono_g_hash_table_insert_internal (domain
->type_hash
, type
, res
);
573 if (type
->type
== MONO_TYPE_VOID
)
574 domain
->typeof_void
= (MonoObject
*)res
;
576 mono_domain_unlock (domain
);
577 mono_loader_unlock ();
581 MonoReflectionTypeHandle
582 mono_type_get_object_handle (MonoDomain
*domain
, MonoType
*type
, MonoError
*error
)
584 /* NOTE: We happen to know that mono_type_get_object_checked returns
585 * pinned objects, so we can just wrap its return value in a handle for
586 * uniformity. If it ever starts returning unpinned, objects, this
587 * implementation would need to change!
589 return MONO_HANDLE_NEW (MonoReflectionType
, mono_type_get_object_checked (domain
, type
, error
));
593 * mono_method_get_object:
594 * \param domain an app domain
595 * \param method a method
596 * \param refclass the reflected type (can be NULL)
597 * \returns A \c System.Reflection.MonoMethod object representing the method \p method.
599 MonoReflectionMethod
*
600 mono_method_get_object (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
)
602 HANDLE_FUNCTION_ENTER ();
603 MonoReflectionMethodHandle ret
;
604 MONO_ENTER_GC_UNSAFE
;
606 ret
= mono_method_get_object_handle (domain
, method
, refclass
, error
);
607 mono_error_cleanup (error
);
609 HANDLE_FUNCTION_RETURN_OBJ (ret
);
612 static MonoReflectionMethodHandle
613 method_object_construct (MonoDomain
*domain
, MonoClass
*refclass
, MonoMethod
*method
, gpointer user_data
, MonoError
*error
)
616 g_assert (refclass
!= NULL
);
618 * We use the same C representation for methods and constructors, but the type
619 * name in C# is different.
625 if (*method
->name
== '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0)) {
626 klass
= mono_class_get_mono_cmethod_class ();
629 klass
= mono_class_get_mono_method_class ();
631 MonoReflectionMethodHandle ret
= MONO_HANDLE_CAST (MonoReflectionMethod
, mono_object_new_handle (domain
, klass
, error
));
632 goto_if_nok (error
, fail
);
633 MONO_HANDLE_SETVAL (ret
, method
, MonoMethod
*, method
);
635 MonoReflectionTypeHandle rt
;
636 rt
= mono_type_get_object_handle (domain
, m_class_get_byval_arg (refclass
), error
);
637 goto_if_nok (error
, fail
);
639 MONO_HANDLE_SET (ret
, reftype
, rt
);
644 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
648 * mono_method_get_object_handle:
649 * @domain: an app domain
651 * @refclass: the reflected type (can be NULL)
652 * @error: set on error.
654 * Return an System.Reflection.MonoMethod object representing the method @method.
655 * Returns NULL and sets @error on error.
657 MonoReflectionMethodHandle
658 mono_method_get_object_handle (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
, MonoError
*error
)
662 refclass
= method
->klass
;
664 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionMethod
, method
, refclass
, method_object_construct
, NULL
);
667 * mono_method_get_object_checked:
668 * @domain: an app domain
670 * @refclass: the reflected type (can be NULL)
671 * @error: set on error.
673 * Return an System.Reflection.MonoMethod object representing the method @method.
674 * Returns NULL and sets @error on error.
676 MonoReflectionMethod
*
677 mono_method_get_object_checked (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
, MonoError
*error
)
679 HANDLE_FUNCTION_ENTER ();
680 MonoReflectionMethodHandle result
= mono_method_get_object_handle (domain
, method
, refclass
, error
);
681 HANDLE_FUNCTION_RETURN_OBJ (result
);
685 * mono_method_clear_object:
687 * Clear the cached reflection objects for the dynamic method METHOD.
690 mono_method_clear_object (MonoDomain
*domain
, MonoMethod
*method
)
693 g_assert (method_is_dynamic (method
));
695 klass
= method
->klass
;
697 clear_cached_object (domain
, method
, klass
);
698 klass
= m_class_get_parent (klass
);
700 /* Added by mono_param_get_objects () */
701 clear_cached_object (domain
, &(method
->signature
), NULL
);
702 klass
= method
->klass
;
704 clear_cached_object (domain
, &(method
->signature
), klass
);
705 klass
= m_class_get_parent (klass
);
710 * mono_field_get_object:
711 * \param domain an app domain
712 * \param klass a type
713 * \param field a field
714 * \returns A \c System.Reflection.MonoField object representing the field \p field
718 mono_field_get_object (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
)
720 HANDLE_FUNCTION_ENTER ();
722 MonoReflectionFieldHandle result
= mono_field_get_object_handle (domain
, klass
, field
, error
);
723 mono_error_cleanup (error
);
724 HANDLE_FUNCTION_RETURN_OBJ (result
);
727 static MonoReflectionFieldHandle
728 field_object_construct (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
, gpointer user_data
, MonoError
*error
)
732 MonoReflectionFieldHandle res
= MONO_HANDLE_CAST (MonoReflectionField
, mono_object_new_handle (domain
, mono_class_get_mono_field_class (), error
));
733 goto_if_nok (error
, fail
);
734 MONO_HANDLE_SETVAL (res
, klass
, MonoClass
*, klass
);
735 MONO_HANDLE_SETVAL (res
, field
, MonoClassField
*, field
);
736 MonoStringHandle name
;
737 name
= mono_string_new_handle (domain
, mono_field_get_name (field
), error
);
738 goto_if_nok (error
, fail
);
739 MONO_HANDLE_SET (res
, name
, name
);
742 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, field
->type
, error
);
743 goto_if_nok (error
, fail
);
745 MONO_HANDLE_SET (res
, type
, rt
);
747 MONO_HANDLE_SETVAL (res
, attrs
, guint32
, mono_field_get_flags (field
));
750 return MONO_HANDLE_CAST (MonoReflectionField
, NULL_HANDLE
);
754 * mono_field_get_object_handle:
755 * @domain: an app domain
758 * @error: set on error
760 * Return an System.Reflection.MonoField object representing the field @field
761 * in class @klass. On error, returns NULL and sets @error.
763 MonoReflectionFieldHandle
764 mono_field_get_object_handle (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
, MonoError
*error
)
767 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionField
, field
, klass
, field_object_construct
, NULL
);
772 * mono_field_get_object_checked:
773 * @domain: an app domain
776 * @error: set on error
778 * Return an System.Reflection.MonoField object representing the field @field
779 * in class @klass. On error, returns NULL and sets @error.
782 mono_field_get_object_checked (MonoDomain
*domain
, MonoClass
*klass
, MonoClassField
*field
, MonoError
*error
)
784 HANDLE_FUNCTION_ENTER ();
785 MonoReflectionFieldHandle result
= mono_field_get_object_handle (domain
, klass
, field
, error
);
786 HANDLE_FUNCTION_RETURN_OBJ (result
);
790 * mono_property_get_object:
791 * @domain: an app domain
793 * @property: a property
795 * Return an System.Reflection.MonoProperty object representing the property @property
798 MonoReflectionProperty
*
799 mono_property_get_object (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
)
801 HANDLE_FUNCTION_ENTER ();
803 MonoReflectionPropertyHandle result
= mono_property_get_object_handle (domain
, klass
, property
, error
);
804 mono_error_cleanup (error
);
805 HANDLE_FUNCTION_RETURN_OBJ (result
);
808 static MonoReflectionPropertyHandle
809 property_object_construct (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
, gpointer user_data
, MonoError
*error
)
813 MonoReflectionPropertyHandle res
= MONO_HANDLE_CAST (MonoReflectionProperty
, mono_object_new_handle (domain
, mono_class_get_mono_property_class (), error
));
814 goto_if_nok (error
, fail
);
815 MONO_HANDLE_SETVAL (res
, klass
, MonoClass
*, klass
);
816 MONO_HANDLE_SETVAL (res
, property
, MonoProperty
*, property
);
819 return MONO_HANDLE_CAST (MonoReflectionProperty
, NULL_HANDLE
);
823 * mono_property_get_object_handle:
824 * \param domain an app domain
825 * \param klass a type
826 * \param property a property
827 * \param error set on error
829 * \returns A \c System.Reflection.MonoProperty object representing the property \p property
830 * in class \p klass. On error returns NULL and sets \p error.
832 MonoReflectionPropertyHandle
833 mono_property_get_object_handle (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
, MonoError
*error
)
835 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionProperty
, property
, klass
, property_object_construct
, NULL
);
839 * mono_property_get_object:
840 * \param domain an app domain
841 * \param klass a type
842 * \param property a property
843 * \param error set on error
844 * \returns a \c System.Reflection.MonoProperty object representing the property \p property
845 * in class \p klass. On error returns NULL and sets \p error.
847 MonoReflectionProperty
*
848 mono_property_get_object_checked (MonoDomain
*domain
, MonoClass
*klass
, MonoProperty
*property
, MonoError
*error
)
850 HANDLE_FUNCTION_ENTER ();
851 MonoReflectionPropertyHandle res
= mono_property_get_object_handle (domain
, klass
, property
, error
);
852 HANDLE_FUNCTION_RETURN_OBJ (res
);
856 * mono_event_get_object:
857 * \param domain an app domain
858 * \param klass a type
859 * \param event a event
860 * \returns A \c System.Reflection.MonoEvent object representing the event \p event
864 mono_event_get_object (MonoDomain
*domain
, MonoClass
*klass
, MonoEvent
*event
)
866 HANDLE_FUNCTION_ENTER ();
868 MonoReflectionEventHandle result
= mono_event_get_object_handle (domain
, klass
, event
, error
);
869 mono_error_cleanup (error
);
870 HANDLE_FUNCTION_RETURN_OBJ (result
);
873 static MonoReflectionEventHandle
874 event_object_construct (MonoDomain
*domain
, MonoClass
*klass
, MonoEvent
*event
, gpointer user_data
, MonoError
*error
)
878 MonoReflectionMonoEventHandle mono_event
= MONO_HANDLE_CAST (MonoReflectionMonoEvent
, mono_object_new_handle (domain
, mono_class_get_mono_event_class (), error
));
880 return MONO_HANDLE_CAST (MonoReflectionEvent
, NULL_HANDLE
);
881 MONO_HANDLE_SETVAL (mono_event
, klass
, MonoClass
* , klass
);
882 MONO_HANDLE_SETVAL (mono_event
, event
, MonoEvent
* , event
);
883 return MONO_HANDLE_CAST (MonoReflectionEvent
, mono_event
);
887 * mono_event_get_object_handle:
888 * \param domain an app domain
889 * \param klass a type
890 * \param event a event
891 * \param error set on error
892 * \returns a \c System.Reflection.MonoEvent object representing the event \p event
893 * in class \p klass. On failure sets \p error and returns NULL
895 MonoReflectionEventHandle
896 mono_event_get_object_handle (MonoDomain
*domain
, MonoClass
*klass
, MonoEvent
*event
, MonoError
*error
)
899 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionEvent
, event
, klass
, event_object_construct
, NULL
);
904 * mono_get_reflection_missing_object:
905 * \param domain Domain where the object lives
907 * \returns the \c System.Reflection.Missing.Value singleton object
908 * (of type \c System.Reflection.Missing).
910 * Used as the value for \c ParameterInfo.DefaultValue when Optional
913 static MonoObjectHandle
914 mono_get_reflection_missing_object (MonoDomain
*domain
)
918 MONO_STATIC_POINTER_INIT (MonoClassField
, missing_value_field
)
920 MonoClass
*missing_klass
= mono_class_get_missing_class ();
921 mono_class_init_internal (missing_klass
);
922 missing_value_field
= mono_class_get_field_from_name_full (missing_klass
, "Value", NULL
);
923 g_assert (missing_value_field
);
925 MONO_STATIC_POINTER_INIT_END (MonoClassField
, missing_value_field
)
927 /* FIXME change mono_field_get_value_object_checked to return a handle */
928 MonoObjectHandle obj
= MONO_HANDLE_NEW (MonoObject
, mono_field_get_value_object_checked (domain
, missing_value_field
, NULL
, error
));
929 mono_error_assert_ok (error
);
933 static MonoObjectHandle
934 get_dbnull_object (MonoDomain
*domain
, MonoError
*error
)
938 MONO_STATIC_POINTER_INIT (MonoClassField
, dbnull_value_field
)
940 MonoClass
*dbnull_klass
= mono_class_get_dbnull_class ();
941 dbnull_value_field
= mono_class_get_field_from_name_full (dbnull_klass
, "Value", NULL
);
942 g_assert (dbnull_value_field
);
944 MONO_STATIC_POINTER_INIT_END (MonoClassField
, dbnull_value_field
)
946 /* FIXME change mono_field_get_value_object_checked to return a handle */
947 MonoObjectHandle obj
= MONO_HANDLE_NEW (MonoObject
, mono_field_get_value_object_checked (domain
, dbnull_value_field
, NULL
, error
));
951 static MonoObjectHandle
952 get_dbnull (MonoDomain
*domain
, MonoObjectHandle dbnull
, MonoError
*error
)
955 if (MONO_HANDLE_IS_NULL (dbnull
))
956 MONO_HANDLE_ASSIGN (dbnull
, get_dbnull_object (domain
, error
));
960 static MonoObjectHandle
961 get_reflection_missing (MonoDomain
*domain
, MonoObjectHandleOut reflection_missing
)
963 if (MONO_HANDLE_IS_NULL (reflection_missing
))
964 MONO_HANDLE_ASSIGN (reflection_missing
, mono_get_reflection_missing_object (domain
));
965 return reflection_missing
;
969 add_parameter_object_to_array (MonoDomain
*domain
, MonoMethod
*method
, MonoObjectHandle member
, int idx
, const char *name
, MonoType
*sig_param
, guint32 blob_type_enum
, const char *blob
, MonoMarshalSpec
*mspec
, MonoObjectHandle missing
, MonoObjectHandle dbnull
, MonoArrayHandle dest
, MonoError
*error
)
971 HANDLE_FUNCTION_ENTER ();
974 MonoReflectionParameterHandle param
= MONO_HANDLE_CAST (MonoReflectionParameter
, mono_object_new_handle (domain
, mono_class_get_mono_parameter_info_class (), error
));
975 goto_if_nok (error
, leave
);
977 static MonoMethod
*ctor
;
979 MonoMethod
*m
= mono_class_get_method_from_name_checked (mono_class_get_mono_parameter_info_class (), ".ctor", 7, 0, error
);
981 mono_memory_barrier ();
985 MonoReflectionTypeHandle rt
;
986 rt
= mono_type_get_object_handle (domain
, sig_param
, error
);
987 goto_if_nok (error
, leave
);
989 MonoStringHandle name_str
;
990 name_str
= mono_string_new_handle (domain
, name
, error
);
991 goto_if_nok (error
, leave
);
993 MonoObjectHandle def_value
;
995 if (!(sig_param
->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
)) {
996 if (sig_param
->attrs
& PARAM_ATTRIBUTE_OPTIONAL
)
997 def_value
= get_reflection_missing (domain
, missing
);
999 def_value
= get_dbnull (domain
, dbnull
, error
);
1000 goto_if_nok (error
, leave
);
1004 blob_type
.type
= (MonoTypeEnum
)blob_type_enum
;
1005 blob_type
.data
.klass
= NULL
;
1006 if (blob_type_enum
== MONO_TYPE_CLASS
)
1007 blob_type
.data
.klass
= mono_defaults
.object_class
;
1008 else if ((sig_param
->type
== MONO_TYPE_VALUETYPE
) && m_class_is_enumtype (sig_param
->data
.klass
)) {
1009 /* For enums, types [i] contains the base type */
1011 blob_type
.type
= MONO_TYPE_VALUETYPE
;
1012 blob_type
.data
.klass
= mono_class_from_mono_type_internal (sig_param
);
1014 blob_type
.data
.klass
= mono_class_from_mono_type_internal (&blob_type
);
1016 def_value
= mono_get_object_from_blob (domain
, &blob_type
, blob
, MONO_HANDLE_NEW (MonoString
, NULL
), error
);
1017 goto_if_nok (error
, leave
);
1019 /* Type in the Constant table is MONO_TYPE_CLASS for nulls */
1020 if (blob_type_enum
!= MONO_TYPE_CLASS
&& MONO_HANDLE_IS_NULL(def_value
)) {
1021 if (sig_param
->attrs
& PARAM_ATTRIBUTE_OPTIONAL
)
1022 def_value
= get_reflection_missing (domain
, missing
);
1024 def_value
= get_dbnull (domain
, dbnull
, error
);
1025 goto_if_nok (error
, leave
);
1029 MonoReflectionMarshalAsAttributeHandle mobj
;
1030 mobj
= MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, NULL
);
1032 mobj
= mono_reflection_marshal_as_attribute_from_marshal_spec (domain
, method
->klass
, mspec
, error
);
1033 goto_if_nok (error
, leave
);
1036 /* internal RuntimeParameterInfo (string name, Type type, int position, int attrs, object defaultValue, MemberInfo member, MarshalAsAttribute marshalAs) */
1038 int attrs
= sig_param
->attrs
;
1041 MONO_HANDLE_RAW (name_str
),
1042 MONO_HANDLE_RAW (rt
),
1045 MONO_HANDLE_RAW (def_value
),
1046 MONO_HANDLE_RAW (member
),
1047 MONO_HANDLE_RAW (mobj
)
1050 mono_runtime_invoke_handle_void (ctor
, MONO_HANDLE_CAST (MonoObject
, param
), args
, error
);
1052 goto_if_nok (error
, leave
);
1054 MONO_HANDLE_ARRAY_SETREF (dest
, idx
, param
);
1057 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
1060 static MonoArrayHandle
1061 param_objects_construct (MonoDomain
*domain
, MonoClass
*refclass
, MonoMethodSignature
**addr_of_sig
, gpointer user_data
, MonoError
*error
)
1063 MonoMethod
*method
= (MonoMethod
*)user_data
;
1064 MonoMethodSignature
*sig
= *addr_of_sig
; /* see note in mono_param_get_objects_internal */
1066 MonoArrayHandle res
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1067 char **names
= NULL
, **blobs
= NULL
;
1068 guint32
*types
= NULL
;
1069 MonoMarshalSpec
**mspecs
= NULL
;
1074 MonoReflectionMethodHandle member
= mono_method_get_object_handle (domain
, method
, refclass
, error
);
1075 goto_if_nok (error
, leave
);
1076 names
= g_new (char *, sig
->param_count
);
1077 mono_method_get_param_names (method
, (const char **) names
);
1079 mspecs
= g_new (MonoMarshalSpec
*, sig
->param_count
+ 1);
1080 mono_method_get_marshal_info (method
, mspecs
);
1082 res
= mono_array_new_handle (domain
, mono_class_get_mono_parameter_info_class (), sig
->param_count
, error
);
1083 if (MONO_HANDLE_IS_NULL (res
))
1086 gboolean any_default_value
;
1087 any_default_value
= FALSE
;
1088 for (i
= 0; i
< sig
->param_count
; ++i
) {
1089 if ((sig
->params
[i
]->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
) != 0) {
1090 any_default_value
= TRUE
;
1094 if (any_default_value
) {
1095 blobs
= g_new0 (char *, sig
->param_count
);
1096 types
= g_new0 (guint32
, sig
->param_count
);
1097 get_default_param_value_blobs (method
, blobs
, types
);
1100 /* Handles missing and dbnull are assigned in add_parameter_object_to_array when needed */
1101 MonoObjectHandle missing
;
1102 missing
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1103 MonoObjectHandle dbnull
;
1104 dbnull
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1105 for (i
= 0; i
< sig
->param_count
; ++i
) {
1106 if (!add_parameter_object_to_array (domain
, method
, MONO_HANDLE_CAST(MonoObject
, member
), i
, names
[i
], sig
->params
[i
], types
? types
[i
] : 0, blobs
? blobs
[i
] : NULL
, mspecs
[i
+ 1], missing
, dbnull
, res
, error
))
1115 if (sig
&& mspecs
) {
1116 for (i
= sig
->param_count
; i
>= 0; i
--) {
1118 mono_metadata_free_marshal_spec (mspecs
[i
]);
1124 return NULL_HANDLE_ARRAY
;
1130 * mono_param_get_objects:
1131 * @domain: an app domain
1134 * Return an System.Reflection.ParameterInfo array object representing the parameters
1135 * in the method @method.
1138 mono_param_get_objects_internal (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*refclass
, MonoError
*error
)
1142 /* side-effect: sets method->signature non-NULL on success */
1143 MonoMethodSignature
*sig
= mono_method_signature_checked (method
, error
);
1144 goto_if_nok (error
, fail
);
1146 if (!sig
->param_count
) {
1147 MonoArrayHandle res
= mono_array_new_handle (domain
, mono_class_get_mono_parameter_info_class (), 0, error
);
1148 goto_if_nok (error
, fail
);
1153 /* Note: the cache is based on the address of the signature into the method
1154 * since we already cache MethodInfos with the method as keys.
1156 return CHECK_OR_CONSTRUCT_HANDLE (MonoArray
, &method
->signature
, refclass
, param_objects_construct
, method
);
1158 return MONO_HANDLE_NEW (MonoArray
, NULL
);
1162 * mono_param_get_objects:
1165 mono_param_get_objects (MonoDomain
*domain
, MonoMethod
*method
)
1167 HANDLE_FUNCTION_ENTER ();
1169 MonoArrayHandle result
= mono_param_get_objects_internal (domain
, method
, NULL
, error
);
1170 mono_error_assert_ok (error
);
1171 HANDLE_FUNCTION_RETURN_OBJ (result
);
1175 add_local_var_info_to_array (MonoDomain
*domain
, MonoMethodHeader
*header
, int idx
, MonoArrayHandle dest
, MonoError
*error
)
1177 HANDLE_FUNCTION_ENTER ();
1179 MonoReflectionLocalVariableInfoHandle info
= MONO_HANDLE_CAST (MonoReflectionLocalVariableInfo
, mono_object_new_handle (domain
, mono_class_get_local_variable_info_class (), error
));
1180 goto_if_nok (error
, leave
);
1182 MonoReflectionTypeHandle rt
;
1183 rt
= mono_type_get_object_handle (domain
, header
->locals
[idx
], error
);
1184 goto_if_nok (error
, leave
);
1186 MONO_HANDLE_SET (info
, local_type
, rt
);
1188 MONO_HANDLE_SETVAL (info
, is_pinned
, MonoBoolean
, header
->locals
[idx
]->pinned
);
1189 MONO_HANDLE_SETVAL (info
, local_index
, guint16
, idx
);
1191 MONO_HANDLE_ARRAY_SETREF (dest
, idx
, info
);
1194 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
1198 add_exception_handling_clause_to_array (MonoDomain
*domain
, MonoMethodHeader
*header
, int idx
, MonoArrayHandle dest
, MonoError
*error
)
1200 HANDLE_FUNCTION_ENTER ();
1202 MonoReflectionExceptionHandlingClauseHandle info
= MONO_HANDLE_CAST (MonoReflectionExceptionHandlingClause
, mono_object_new_handle (domain
, mono_class_get_exception_handling_clause_class (), error
));
1203 goto_if_nok (error
, leave
);
1204 MonoExceptionClause
*clause
;
1205 clause
= &header
->clauses
[idx
];
1207 MONO_HANDLE_SETVAL (info
, flags
, gint32
, clause
->flags
);
1208 MONO_HANDLE_SETVAL (info
, try_offset
, gint32
, clause
->try_offset
);
1209 MONO_HANDLE_SETVAL (info
, try_length
, gint32
, clause
->try_len
);
1210 MONO_HANDLE_SETVAL (info
, handler_offset
, gint32
, clause
->handler_offset
);
1211 MONO_HANDLE_SETVAL (info
, handler_length
, gint32
, clause
->handler_len
);
1212 if (clause
->flags
== MONO_EXCEPTION_CLAUSE_FILTER
)
1213 MONO_HANDLE_SETVAL (info
, filter_offset
, gint32
, clause
->data
.filter_offset
);
1214 else if (clause
->data
.catch_class
) {
1215 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (mono_domain_get (), m_class_get_byval_arg (clause
->data
.catch_class
), error
);
1216 goto_if_nok (error
, leave
);
1218 MONO_HANDLE_SET (info
, catch_type
, rt
);
1221 MONO_HANDLE_ARRAY_SETREF (dest
, idx
, info
);
1223 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
1227 * mono_method_body_get_object:
1228 * \param domain an app domain
1229 * \param method a method
1230 * \return A \c System.Reflection.MethodBody/RuntimeMethodBody object representing the method \p method.
1232 MonoReflectionMethodBody
*
1233 mono_method_body_get_object (MonoDomain
*domain
, MonoMethod
*method
)
1235 HANDLE_FUNCTION_ENTER ();
1237 MonoReflectionMethodBodyHandle result
= mono_method_body_get_object_handle (domain
, method
, error
);
1238 mono_error_cleanup (error
);
1239 HANDLE_FUNCTION_RETURN_OBJ (result
);
1242 /* WARNING: This method can return NULL on success */
1243 static MonoReflectionMethodBodyHandle
1244 method_body_object_construct (MonoDomain
*domain
, MonoClass
*unused_class
, MonoMethod
*method
, gpointer user_data
, MonoError
*error
)
1246 MonoMethodHeader
*header
= NULL
;
1248 guint32 method_rva
, local_var_sig_token
;
1250 unsigned char format
, flags
;
1252 gpointer params
[6];
1253 MonoBoolean init_locals_param
;
1254 gint32 sig_token_param
;
1255 gint32 max_stack_param
;
1259 /* for compatibility with .net */
1260 if (method_is_dynamic (method
)) {
1261 mono_error_set_generic_error (error
, "System", "InvalidOperationException", "");
1265 image
= m_class_get_image (method
->klass
);
1266 if ((method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
1267 (method
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) ||
1268 (method
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) ||
1269 (image
->raw_data
&& image
->raw_data
[1] != 'Z') ||
1270 (method
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
))
1271 return MONO_HANDLE_CAST (MonoReflectionMethodBody
, NULL_HANDLE
);
1273 header
= mono_method_get_header_checked (method
, error
);
1274 goto_if_nok (error
, fail
);
1276 if (!image_is_dynamic (image
)) {
1277 /* Obtain local vars signature token */
1278 method_rva
= mono_metadata_decode_row_col (&image
->tables
[MONO_TABLE_METHOD
], mono_metadata_token_index (method
->token
) - 1, MONO_METHOD_RVA
);
1279 ptr
= mono_image_rva_map (image
, method_rva
);
1280 flags
= *(const unsigned char *) ptr
;
1281 format
= flags
& METHOD_HEADER_FORMAT_MASK
;
1283 case METHOD_HEADER_TINY_FORMAT
:
1284 local_var_sig_token
= 0;
1286 case METHOD_HEADER_FAT_FORMAT
:
1290 local_var_sig_token
= read32 (ptr
);
1293 g_assert_not_reached ();
1296 local_var_sig_token
= 0; //FIXME
1298 static MonoMethod
*ctor
;
1300 MonoMethod
*tmp
= mono_class_get_method_from_name_checked (mono_class_get_method_body_class (), ".ctor", 6, 0, error
);
1301 mono_error_assert_ok (error
);
1304 mono_memory_barrier ();
1308 MonoReflectionMethodBodyHandle ret
;
1309 ret
= MONO_HANDLE_CAST (MonoReflectionMethodBody
, mono_object_new_handle (domain
, mono_class_get_method_body_class (), error
));
1310 goto_if_nok (error
, fail
);
1312 MonoArrayHandle il_arr
;
1313 il_arr
= mono_array_new_handle (domain
, mono_defaults
.byte_class
, header
->code_size
, error
);
1314 goto_if_nok (error
, fail
);
1315 uint32_t il_gchandle
;
1317 il_data
= MONO_ARRAY_HANDLE_PIN (il_arr
, guint8
, 0, &il_gchandle
);
1318 memcpy (il_data
, header
->code
, header
->code_size
);
1319 mono_gchandle_free_internal (il_gchandle
);
1322 MonoArrayHandle locals_arr
;
1323 locals_arr
= mono_array_new_handle (domain
, mono_class_get_local_variable_info_class (), header
->num_locals
, error
);
1324 goto_if_nok (error
, fail
);
1325 for (i
= 0; i
< header
->num_locals
; ++i
) {
1326 if (!add_local_var_info_to_array (domain
, header
, i
, locals_arr
, error
))
1331 MonoArrayHandle exn_clauses
;
1332 exn_clauses
= mono_array_new_handle (domain
, mono_class_get_exception_handling_clause_class (), header
->num_clauses
, error
);
1333 goto_if_nok (error
, fail
);
1334 for (i
= 0; i
< header
->num_clauses
; ++i
) {
1335 if (!add_exception_handling_clause_to_array (domain
, header
, i
, exn_clauses
, error
))
1340 MethodBody (ExceptionHandlingClause[] clauses, LocalVariableInfo[] locals,
1341 byte[] il, bool init_locals, int sig_token, int max_stack)
1343 init_locals_param
= header
->init_locals
;
1344 sig_token_param
= local_var_sig_token
;
1345 max_stack_param
= header
->max_stack
;
1346 mono_metadata_free_mh (header
);
1349 params
[0] = MONO_HANDLE_RAW (exn_clauses
);
1350 params
[1] = MONO_HANDLE_RAW (locals_arr
);
1351 params
[2] = MONO_HANDLE_RAW (il_arr
);
1352 params
[3] = &init_locals_param
;
1353 params
[4] = &sig_token_param
;
1354 params
[5] = &max_stack_param
;
1355 mono_runtime_invoke_handle_void (ctor
, MONO_HANDLE_CAST (MonoObject
, ret
), params
, error
);
1356 mono_error_assert_ok (error
);
1361 mono_metadata_free_mh (header
);
1362 return MONO_HANDLE_CAST (MonoReflectionMethodBody
, NULL_HANDLE
);
1366 * mono_method_body_get_object_handle:
1367 * \param domain an app domain
1368 * \param method a method
1369 * \param error set on error
1370 * \returns a \c System.Reflection.MethodBody object representing the
1371 * method \p method. On failure, returns NULL and sets \p error.
1373 MonoReflectionMethodBodyHandle
1374 mono_method_body_get_object_handle (MonoDomain
*domain
, MonoMethod
*method
, MonoError
*error
)
1377 return CHECK_OR_CONSTRUCT_HANDLE (MonoReflectionMethodBody
, method
, NULL
, method_body_object_construct
, NULL
);
1382 * mono_get_dbnull_object:
1383 * \param domain Domain where the object lives
1384 * Used as the value for \c ParameterInfo.DefaultValue
1385 * \returns the \c System.DBNull.Value singleton object
1388 mono_get_dbnull_object (MonoDomain
*domain
)
1390 HANDLE_FUNCTION_ENTER ();
1392 MonoObjectHandle obj
= get_dbnull_object (domain
, error
);
1393 mono_error_assert_ok (error
);
1394 HANDLE_FUNCTION_RETURN_OBJ (obj
);
1398 get_default_param_value_blobs (MonoMethod
*method
, char **blobs
, guint32
*types
)
1400 guint32 param_index
, i
, lastp
, crow
= 0;
1401 guint32 param_cols
[MONO_PARAM_SIZE
], const_cols
[MONO_CONSTANT_SIZE
];
1404 MonoClass
*klass
= method
->klass
;
1405 MonoImage
*image
= m_class_get_image (klass
);
1406 MonoMethodSignature
*methodsig
= mono_method_signature_internal (method
);
1408 MonoTableInfo
*constt
;
1409 MonoTableInfo
*methodt
;
1410 MonoTableInfo
*paramt
;
1412 if (!methodsig
->param_count
)
1415 mono_class_init_internal (klass
);
1417 if (image_is_dynamic (image
)) {
1418 MonoReflectionMethodAux
*aux
;
1419 if (method
->is_inflated
)
1420 method
= ((MonoMethodInflated
*)method
)->declaring
;
1421 aux
= (MonoReflectionMethodAux
*)g_hash_table_lookup (((MonoDynamicImage
*)m_class_get_image (method
->klass
))->method_aux_hash
, method
);
1422 if (aux
&& aux
->param_defaults
) {
1423 memcpy (blobs
, &(aux
->param_defaults
[1]), methodsig
->param_count
* sizeof (char*));
1424 memcpy (types
, &(aux
->param_default_types
[1]), methodsig
->param_count
* sizeof (guint32
));
1429 methodt
= &image
->tables
[MONO_TABLE_METHOD
];
1430 paramt
= &image
->tables
[MONO_TABLE_PARAM
];
1431 constt
= &image
->tables
[MONO_TABLE_CONSTANT
];
1433 idx
= mono_method_get_index (method
) - 1;
1434 g_assert (idx
!= -1);
1436 param_index
= mono_metadata_decode_row_col (methodt
, idx
, MONO_METHOD_PARAMLIST
);
1437 if (idx
+ 1 < methodt
->rows
)
1438 lastp
= mono_metadata_decode_row_col (methodt
, idx
+ 1, MONO_METHOD_PARAMLIST
);
1440 lastp
= paramt
->rows
+ 1;
1442 for (i
= param_index
; i
< lastp
; ++i
) {
1445 mono_metadata_decode_row (paramt
, i
- 1, param_cols
, MONO_PARAM_SIZE
);
1446 paramseq
= param_cols
[MONO_PARAM_SEQUENCE
];
1448 if (!(param_cols
[MONO_PARAM_FLAGS
] & PARAM_ATTRIBUTE_HAS_DEFAULT
))
1451 crow
= mono_metadata_get_constant_index (image
, MONO_TOKEN_PARAM_DEF
| i
, crow
+ 1);
1456 mono_metadata_decode_row (constt
, crow
- 1, const_cols
, MONO_CONSTANT_SIZE
);
1457 blobs
[paramseq
- 1] = (char *)mono_metadata_blob_heap (image
, const_cols
[MONO_CONSTANT_VALUE
]);
1458 types
[paramseq
- 1] = const_cols
[MONO_CONSTANT_TYPE
];
1465 mono_get_object_from_blob (MonoDomain
*domain
, MonoType
*type
, const char *blob
, MonoStringHandleOut string_handle
, MonoError
*error
)
1472 HANDLE_FUNCTION_ENTER ();
1475 void *retval
= &object
;
1476 MonoType
*basetype
= type
;
1478 MonoObjectHandle object_handle
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1480 MonoClass
* const klass
= mono_class_from_mono_type_internal (type
);
1482 if (m_class_is_valuetype (klass
)) {
1483 object
= mono_object_new_checked (domain
, klass
, error
);
1484 MONO_HANDLE_ASSIGN_RAW (object_handle
, object
);
1485 return_val_if_nok (error
, NULL_HANDLE
);
1486 retval
= mono_object_get_data (object
);
1487 if (m_class_is_enumtype (klass
))
1488 basetype
= mono_class_enum_basetype_internal (klass
);
1491 if (mono_get_constant_value_from_blob (domain
, basetype
->type
, blob
, retval
, string_handle
, error
))
1492 MONO_HANDLE_ASSIGN_RAW (object_handle
, object
);
1494 object_handle
= NULL_HANDLE
;
1496 HANDLE_FUNCTION_RETURN_REF (MonoObject
, object_handle
);
1500 assembly_name_to_aname (MonoAssemblyName
*assembly
, char *p
) {
1503 gboolean quoted
= FALSE
;
1505 memset (assembly
, 0, sizeof (MonoAssemblyName
));
1506 assembly
->culture
= "";
1507 memset (assembly
->public_key_token
, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH
);
1514 while (*p
&& (isalnum (*p
) || *p
== '.' || *p
== '-' || *p
== '_' || *p
== '$' || *p
== '@' || g_ascii_isspace (*p
)))
1525 /* Remove trailing whitespace */
1527 while (*s
&& g_ascii_isspace (*s
))
1530 while (g_ascii_isspace (*p
))
1533 if ((*p
== 'V' || *p
== 'v') && g_ascii_strncasecmp (p
, "Version=", 8) == 0) {
1535 assembly
->major
= strtoul (p
, &s
, 10);
1536 if (s
== p
|| *s
!= '.')
1539 assembly
->minor
= strtoul (p
, &s
, 10);
1540 if (s
== p
|| *s
!= '.')
1543 assembly
->build
= strtoul (p
, &s
, 10);
1544 if (s
== p
|| *s
!= '.')
1547 assembly
->revision
= strtoul (p
, &s
, 10);
1551 } else if ((*p
== 'C' || *p
== 'c') && g_ascii_strncasecmp (p
, "Culture=", 8) == 0) {
1553 if (g_ascii_strncasecmp (p
, "neutral", 7) == 0) {
1554 assembly
->culture
= "";
1557 assembly
->culture
= p
;
1558 while (*p
&& *p
!= ',') {
1562 } else if ((*p
== 'P' || *p
== 'p') && g_ascii_strncasecmp (p
, "PublicKeyToken=", 15) == 0) {
1564 if (strncmp (p
, "null", 4) == 0) {
1569 while (*p
&& *p
!= ',') {
1572 len
= (p
- start
+ 1);
1573 if (len
> MONO_PUBLIC_KEY_TOKEN_LENGTH
)
1574 len
= MONO_PUBLIC_KEY_TOKEN_LENGTH
;
1575 char* pkt_lower
= g_ascii_strdown (start
, len
);
1576 g_strlcpy ((char*) assembly
->public_key_token
, pkt_lower
, len
);
1580 while (*p
&& *p
!= ',')
1584 while (g_ascii_isspace (*p
) || *p
== ',') {
1598 * mono_reflection_parse_type:
1601 * Parse a type name as accepted by the GetType () method and output the info
1602 * extracted in the info structure.
1603 * the name param will be mangled, so, make a copy before passing it to this function.
1604 * The fields in info will be valid until the memory pointed to by name is valid.
1606 * See also mono_type_get_name () below.
1608 * Returns: 0 on parse error.
1611 _mono_reflection_parse_type (char *name
, char **endptr
, gboolean is_recursed
,
1612 MonoTypeNameParse
*info
)
1614 char *start
, *p
, *w
, *last_point
, *startn
;
1615 int in_modifiers
= 0;
1616 int isbyref
= 0, rank
= 0, isptr
= 0;
1618 start
= p
= w
= name
;
1620 memset (info
, 0, sizeof (MonoTypeNameParse
));
1622 /* last_point separates the namespace from the name */
1625 while (*p
== ' ') p
++, start
++, w
++, name
++;
1630 *p
= 0; /* NULL terminate the name */
1632 info
->nested
= g_list_append (info
->nested
, startn
);
1633 /* we have parsed the nesting namespace + name */
1637 info
->name_space
= start
;
1639 info
->name
= last_point
+ 1;
1641 info
->name_space
= (char *)"";
1669 info
->name_space
= start
;
1672 info
->name
= last_point
+ 1;
1674 info
->name_space
= (char *)"";
1681 if (isbyref
) /* only one level allowed by the spec */
1685 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (0));
1689 if (isbyref
) /* pointer to ref not okay */
1691 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (-1));
1696 if (isbyref
) /* array of ref and generic ref are not okay */
1698 //Decide if it's an array of a generic argument list
1703 if (*p
== ',' || *p
== '*' || *p
== ']') { //array
1704 gboolean bounded
= FALSE
;
1712 else if (*p
== '*') /* '*' means unknown lower bound */
1720 /* bounded only allowed when rank == 1 */
1721 if (bounded
&& rank
> 1)
1723 /* n.b. bounded needs both modifiers: -2 == bounded, 1 == rank 1 array */
1725 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (-2));
1726 info
->modifiers
= g_list_append (info
->modifiers
, GUINT_TO_POINTER (rank
));
1728 if (rank
|| isptr
) /* generic args after array spec or ptr*/ //XXX test
1731 info
->type_arguments
= g_ptr_array_new ();
1733 MonoTypeNameParse
*subinfo
= g_new0 (MonoTypeNameParse
, 1);
1734 gboolean fqname
= FALSE
;
1736 g_ptr_array_add (info
->type_arguments
, subinfo
);
1738 while (*p
== ' ') p
++;
1744 if (!_mono_reflection_parse_type (p
, &p
, TRUE
, subinfo
))
1747 /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
1748 if (fqname
&& (*p
!= ']')) {
1756 while (*p
&& (*p
!= ']'))
1764 if (g_ascii_isspace (*aname
)) {
1771 !assembly_name_to_aname (&subinfo
->assembly
, aname
))
1773 } else if (fqname
&& (*p
== ']')) {
1795 if (g_ascii_isspace (*p
)) {
1802 return 0; /* missing assembly name */
1803 if (!assembly_name_to_aname (&info
->assembly
, p
))
1809 if (info
->assembly
.name
)
1812 // *w = 0; /* terminate class name */
1814 if (!info
->name
|| !*info
->name
)
1818 /* add other consistency checks */
1824 * mono_identifier_unescape_type_name_chars:
1825 * \param identifier the display name of a mono type
1827 * \returns The name in internal form, that is without escaping backslashes.
1829 * The string is modified in place!
1832 mono_identifier_unescape_type_name_chars(char* identifier
)
1837 for (w
= r
= identifier
; *r
!= 0; r
++)
1855 mono_identifier_unescape_info (MonoTypeNameParse
* info
);
1858 unescape_each_type_argument(void* data
, void* user_data
)
1860 MonoTypeNameParse
* info
= (MonoTypeNameParse
*)data
;
1861 mono_identifier_unescape_info (info
);
1865 unescape_each_nested_name (void* data
, void* user_data
)
1867 char* nested_name
= (char*) data
;
1868 mono_identifier_unescape_type_name_chars(nested_name
);
1872 * mono_identifier_unescape_info:
1874 * \param info a parsed display form of an (optionally assembly qualified) full type name.
1876 * Destructively updates the info by unescaping the identifiers that
1877 * comprise the type namespace, name, nested types (if any) and
1878 * generic type arguments (if any).
1880 * The resulting info has the names in internal form.
1884 mono_identifier_unescape_info (MonoTypeNameParse
*info
)
1888 mono_identifier_unescape_type_name_chars(info
->name_space
);
1889 mono_identifier_unescape_type_name_chars(info
->name
);
1890 // but don't escape info->assembly
1891 if (info
->type_arguments
)
1892 g_ptr_array_foreach(info
->type_arguments
, &unescape_each_type_argument
, NULL
);
1894 g_list_foreach(info
->nested
, &unescape_each_nested_name
, NULL
);
1898 * mono_reflection_parse_type:
1901 mono_reflection_parse_type (char *name
, MonoTypeNameParse
*info
)
1904 gboolean result
= mono_reflection_parse_type_checked (name
, info
, error
);
1905 mono_error_cleanup (error
);
1906 return result
? 1 : 0;
1910 * mono_reflection_parse_type_checked:
1911 * \param name the string to parse
1912 * \param info the parsed name components
1913 * \param error set on error
1915 * Parse the given \p name and write the results to \p info, setting \p error
1916 * on error. The string \p name is modified in place and \p info points into
1917 * its memory and into allocated memory.
1919 * \returns TRUE if parsing succeeded, otherwise returns FALSE and sets \p error.
1923 mono_reflection_parse_type_checked (char *name
, MonoTypeNameParse
*info
, MonoError
*error
)
1926 int ok
= _mono_reflection_parse_type (name
, NULL
, FALSE
, info
);
1928 mono_identifier_unescape_info (info
);
1931 mono_error_set_argument_format (error
, "typeName@0", "failed parse: %s", name
);
1933 mono_error_set_argument_format (error
, "typeName", "failed parse: %s", name
);
1940 _mono_reflection_get_type_from_info (MonoAssemblyLoadContext
*alc
, MonoTypeNameParse
*info
, MonoImage
*image
, gboolean ignorecase
, gboolean search_mscorlib
, MonoError
*error
)
1942 gboolean type_resolve
= FALSE
;
1944 MonoImage
*rootimage
= image
;
1948 if (info
->assembly
.name
) {
1949 MonoAssembly
*assembly
= mono_assembly_loaded_internal (alc
, &info
->assembly
, FALSE
);
1950 if (!assembly
&& image
&& image
->assembly
&& mono_assembly_check_name_match (&info
->assembly
, &image
->assembly
->aname
))
1952 * This could happen in the AOT compiler case when the search hook is not
1955 assembly
= image
->assembly
;
1957 /* then we must load the assembly ourselve - see #60439 */
1958 MonoAssemblyByNameRequest req
;
1959 mono_assembly_request_prepare_byname (&req
, MONO_ASMCTX_DEFAULT
, alc
);
1960 req
.requesting_assembly
= NULL
;
1961 req
.basedir
= image
? image
->assembly
->basedir
: NULL
;
1962 assembly
= mono_assembly_request_byname (&info
->assembly
, &req
, NULL
);
1966 image
= assembly
->image
;
1967 } else if (!image
&& search_mscorlib
) {
1968 image
= mono_defaults
.corlib
;
1971 type
= mono_reflection_get_type_with_rootimage (alc
, rootimage
, image
, info
, ignorecase
, search_mscorlib
, &type_resolve
, error
);
1972 if (type
== NULL
&& !info
->assembly
.name
&& image
!= mono_defaults
.corlib
&& search_mscorlib
) {
1973 /* ignore the error and try again */
1974 mono_error_cleanup (error
);
1976 image
= mono_defaults
.corlib
;
1977 type
= mono_reflection_get_type_with_rootimage (alc
, rootimage
, image
, info
, ignorecase
, search_mscorlib
, &type_resolve
, error
);
1984 * mono_reflection_get_type_internal:
1986 * Returns: may return NULL on success, sets error on failure.
1989 mono_reflection_get_type_internal (MonoAssemblyLoadContext
*alc
, MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, MonoError
*error
)
1991 HANDLE_FUNCTION_ENTER ();
1995 gboolean bounded
= FALSE
;
1996 MonoType
* type
= NULL
;
2000 image
= mono_defaults
.corlib
;
2003 rootimage
= mono_defaults
.corlib
;
2006 klass
= mono_class_from_name_case_checked (image
, info
->name_space
, info
->name
, error
);
2008 klass
= mono_class_from_name_checked (image
, info
->name_space
, info
->name
, error
);
2013 for (mod
= info
->nested
; mod
; mod
= mod
->next
) {
2014 gpointer iter
= NULL
;
2018 mono_class_init_internal (parent
);
2020 while ((klass
= mono_class_get_nested_types (parent
, &iter
))) {
2022 char *nested_name
, *nested_nspace
;
2023 gboolean match
= TRUE
;
2025 lastp
= strrchr ((const char *)mod
->data
, '.');
2027 /* Nested classes can have namespaces */
2030 nested_name
= g_strdup (lastp
+ 1);
2031 nspace_len
= lastp
- (char*)mod
->data
;
2032 nested_nspace
= (char *)g_malloc (nspace_len
+ 1);
2033 memcpy (nested_nspace
, mod
->data
, nspace_len
);
2034 nested_nspace
[nspace_len
] = '\0';
2037 nested_name
= (char *)mod
->data
;
2038 nested_nspace
= NULL
;
2041 if (nested_nspace
) {
2042 const char *klass_name_space
= m_class_get_name_space (klass
);
2044 if (!(klass_name_space
&& mono_utf8_strcasecmp (klass_name_space
, nested_nspace
) == 0))
2047 if (!(klass_name_space
&& strcmp (klass_name_space
, nested_nspace
) == 0))
2052 const char *klass_name
= m_class_get_name (klass
);
2054 if (mono_utf8_strcasecmp (klass_name
, nested_name
) != 0)
2057 if (strcmp (klass_name
, nested_name
) != 0)
2062 g_free (nested_name
);
2063 g_free (nested_nspace
);
2075 if (info
->type_arguments
) {
2076 MonoType
**type_args
= g_new0 (MonoType
*, info
->type_arguments
->len
);
2077 MonoReflectionTypeHandle the_type
;
2081 for (i
= 0; i
< info
->type_arguments
->len
; i
++) {
2082 MonoTypeNameParse
*subinfo
= (MonoTypeNameParse
*)g_ptr_array_index (info
->type_arguments
, i
);
2084 type_args
[i
] = _mono_reflection_get_type_from_info (alc
, subinfo
, rootimage
, ignorecase
, search_mscorlib
, error
);
2085 if (!type_args
[i
]) {
2091 the_type
= mono_type_get_object_handle (mono_domain_get (), m_class_get_byval_arg (klass
), error
);
2092 if (!is_ok (error
) || MONO_HANDLE_IS_NULL (the_type
))
2095 instance
= mono_reflection_bind_generic_parameters (
2096 the_type
, info
->type_arguments
->len
, type_args
, error
);
2102 klass
= mono_class_from_mono_type_internal (instance
);
2105 for (mod
= info
->modifiers
; mod
; mod
= mod
->next
) {
2106 modval
= GPOINTER_TO_UINT (mod
->data
);
2107 if (!modval
) { /* byref: must be last modifier */
2108 type
= m_class_get_this_arg (klass
);
2110 } else if (modval
== -1) {
2111 klass
= mono_class_create_ptr (m_class_get_byval_arg (klass
));
2112 } else if (modval
== -2) {
2114 } else { /* array rank */
2115 klass
= mono_class_create_bounded_array (klass
, modval
, bounded
);
2119 type
= m_class_get_byval_arg (klass
);
2122 HANDLE_FUNCTION_RETURN_VAL (type
);
2126 * mono_reflection_get_type:
2127 * \param image a metadata context
2128 * \param info type description structure
2129 * \param ignorecase flag for case-insensitive string compares
2130 * \param type_resolve whenever type resolve was already tried
2132 * Build a MonoType from the type description in \p info.
2136 mono_reflection_get_type (MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean
*type_resolve
) {
2138 MonoDomain
*domain
= mono_domain_get ();
2139 MonoType
*result
= mono_reflection_get_type_with_rootimage (mono_domain_default_alc (domain
), image
, image
, info
, ignorecase
, TRUE
, type_resolve
, error
);
2140 mono_error_cleanup (error
);
2145 * mono_reflection_get_type_checked:
2146 * \param alc the AssemblyLoadContext to check/load into
2147 * \param rootimage the image of the currently active managed caller
2148 * \param image a metadata context
2149 * \param info type description structure
2150 * \param ignorecase flag for case-insensitive string compares
2151 * \param type_resolve whenever type resolve was already tried
2153 * \param error set on error.
2154 * Build a \c MonoType from the type description in \p info. On failure returns NULL and sets \p error.
2157 mono_reflection_get_type_checked (MonoAssemblyLoadContext
*alc
, MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, gboolean
*type_resolve
, MonoError
*error
) {
2159 return mono_reflection_get_type_with_rootimage (alc
, rootimage
, image
, info
, ignorecase
, search_mscorlib
, type_resolve
, error
);
2164 module_builder_array_get_type (MonoAssemblyLoadContext
*alc
, MonoArrayHandle module_builders
, int i
, MonoImage
*rootimage
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, MonoError
*error
)
2166 HANDLE_FUNCTION_ENTER ();
2168 MonoType
*type
= NULL
;
2169 MonoReflectionModuleBuilderHandle mb
= MONO_HANDLE_NEW (MonoReflectionModuleBuilder
, NULL
);
2170 MONO_HANDLE_ARRAY_GETREF (mb
, module_builders
, i
);
2171 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
2172 type
= mono_reflection_get_type_internal (alc
, rootimage
, &dynamic_image
->image
, info
, ignorecase
, search_mscorlib
, error
);
2173 HANDLE_FUNCTION_RETURN_VAL (type
);
2177 module_array_get_type (MonoAssemblyLoadContext
*alc
, MonoArrayHandle modules
, int i
, MonoImage
*rootimage
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, MonoError
*error
)
2179 HANDLE_FUNCTION_ENTER ();
2181 MonoType
*type
= NULL
;
2182 MonoReflectionModuleHandle mod
= MONO_HANDLE_NEW (MonoReflectionModule
, NULL
);
2183 MONO_HANDLE_ARRAY_GETREF (mod
, modules
, i
);
2184 MonoImage
*image
= MONO_HANDLE_GETVAL (mod
, image
);
2185 type
= mono_reflection_get_type_internal (alc
, rootimage
, image
, info
, ignorecase
, search_mscorlib
, error
);
2186 HANDLE_FUNCTION_RETURN_VAL (type
);
2190 mono_reflection_get_type_internal_dynamic (MonoAssemblyLoadContext
*alc
, MonoImage
*rootimage
, MonoAssembly
*assembly
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, MonoError
*error
)
2192 HANDLE_FUNCTION_ENTER ();
2193 MonoType
*type
= NULL
;
2197 g_assert (assembly_is_dynamic (assembly
));
2198 MonoReflectionAssemblyBuilderHandle abuilder
= MONO_HANDLE_CAST (MonoReflectionAssemblyBuilder
, mono_assembly_get_object_handle (((MonoDynamicAssembly
*)assembly
)->domain
, assembly
, error
));
2199 goto_if_nok (error
, leave
);
2201 /* Enumerate all modules */
2203 MonoArrayHandle modules
;
2204 modules
= MONO_HANDLE_NEW (MonoArray
, NULL
);
2205 MONO_HANDLE_GET (modules
, abuilder
, modules
);
2206 if (!MONO_HANDLE_IS_NULL (modules
)) {
2207 int n
= mono_array_handle_length (modules
);
2208 for (i
= 0; i
< n
; ++i
) {
2209 type
= module_builder_array_get_type (alc
, modules
, i
, rootimage
, info
, ignorecase
, search_mscorlib
, error
);
2212 goto_if_nok (error
, leave
);
2216 MonoArrayHandle loaded_modules
;
2217 loaded_modules
= MONO_HANDLE_NEW (MonoArray
, NULL
);
2218 MONO_HANDLE_GET (loaded_modules
, abuilder
, loaded_modules
);
2219 if (!type
&& !MONO_HANDLE_IS_NULL(loaded_modules
)) {
2220 int n
= mono_array_handle_length (loaded_modules
);
2221 for (i
= 0; i
< n
; ++i
) {
2222 type
= module_array_get_type (alc
, loaded_modules
, i
, rootimage
, info
, ignorecase
, search_mscorlib
, error
);
2225 goto_if_nok (error
, leave
);
2230 HANDLE_FUNCTION_RETURN_VAL (type
);
2234 mono_reflection_get_type_with_rootimage (MonoAssemblyLoadContext
*alc
, MonoImage
*rootimage
, MonoImage
* image
, MonoTypeNameParse
*info
, gboolean ignorecase
, gboolean search_mscorlib
, gboolean
*type_resolve
, MonoError
*error
)
2236 HANDLE_FUNCTION_ENTER ();
2239 MonoReflectionAssemblyHandle reflection_assembly
;
2240 MonoDomain
*domain
= mono_alc_domain (alc
);
2241 GString
*fullName
= NULL
;
2246 if (image
&& image_is_dynamic (image
))
2247 type
= mono_reflection_get_type_internal_dynamic (alc
, rootimage
, image
->assembly
, info
, ignorecase
, search_mscorlib
, error
);
2249 type
= mono_reflection_get_type_internal (alc
, rootimage
, image
, info
, ignorecase
, search_mscorlib
, error
);
2250 goto_if_nok (error
, return_null
);
2254 if (!mono_domain_has_type_resolve (domain
))
2260 *type_resolve
= TRUE
;
2263 /* Reconstruct the type name */
2264 fullName
= g_string_new ("");
2265 if (info
->name_space
&& (info
->name_space
[0] != '\0'))
2266 g_string_printf (fullName
, "%s.%s", info
->name_space
, info
->name
);
2268 g_string_printf (fullName
, "%s", info
->name
);
2269 for (mod
= info
->nested
; mod
; mod
= mod
->next
)
2270 g_string_append_printf (fullName
, "+%s", (char*)mod
->data
);
2272 MonoStringHandle name_handle
;
2273 name_handle
= mono_string_new_handle (mono_domain_get (), fullName
->str
, error
);
2274 goto_if_nok (error
, return_null
);
2276 reflection_assembly
= mono_domain_try_type_resolve_name (domain
, image
->assembly
, name_handle
, error
);
2277 goto_if_nok (error
, return_null
);
2279 if (MONO_HANDLE_BOOL (reflection_assembly
)) {
2280 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (reflection_assembly
, assembly
);
2281 if (assembly_is_dynamic (assembly
))
2282 type
= mono_reflection_get_type_internal_dynamic (alc
, rootimage
, assembly
,
2283 info
, ignorecase
, search_mscorlib
, error
);
2285 type
= mono_reflection_get_type_internal (alc
, rootimage
, assembly
->image
,
2286 info
, ignorecase
, search_mscorlib
, error
);
2288 goto_if_nok (error
, return_null
);
2297 g_string_free (fullName
, TRUE
);
2298 HANDLE_FUNCTION_RETURN_VAL (type
);
2302 * mono_reflection_free_type_info:
2305 mono_reflection_free_type_info (MonoTypeNameParse
*info
)
2307 g_list_free (info
->modifiers
);
2308 g_list_free (info
->nested
);
2310 if (info
->type_arguments
) {
2313 for (i
= 0; i
< info
->type_arguments
->len
; i
++) {
2314 MonoTypeNameParse
*subinfo
= (MonoTypeNameParse
*)g_ptr_array_index (info
->type_arguments
, i
);
2316 mono_reflection_free_type_info (subinfo
);
2317 /*We free the subinfo since it is allocated by _mono_reflection_parse_type*/
2321 g_ptr_array_free (info
->type_arguments
, TRUE
);
2326 * mono_reflection_type_from_name:
2327 * \param name type name.
2328 * \param image a metadata context (can be NULL).
2330 * Retrieves a \c MonoType from its \p name. If the name is not fully qualified,
2331 * it defaults to get the type from \p image or, if \p image is NULL or loading
2332 * from it fails, uses corlib.
2336 mono_reflection_type_from_name (char *name
, MonoImage
*image
)
2341 MonoAssemblyLoadContext
*alc
= mono_domain_default_alc (mono_domain_get ());
2343 MonoType
* const result
= mono_reflection_type_from_name_checked (name
, alc
, image
, error
);
2345 mono_error_cleanup (error
);
2350 * mono_reflection_type_from_name_checked:
2351 * \param name type name.
2352 * \param alc the AssemblyLoadContext to check/load into
2353 * \param image a metadata context (can be NULL).
2354 * \param error set on errror.
2355 * Retrieves a MonoType from its \p name. If the name is not fully qualified,
2356 * it defaults to get the type from \p image or, if \p image is NULL or loading
2357 * from it fails, uses corlib. On failure returns NULL and sets \p error.
2360 mono_reflection_type_from_name_checked (char *name
, MonoAssemblyLoadContext
*alc
, MonoImage
*image
, MonoError
*error
)
2362 MonoType
*type
= NULL
;
2363 MonoTypeNameParse info
;
2367 /* Make a copy since parse_type modifies its argument */
2368 tmp
= g_strdup (name
);
2370 /*g_print ("requested type %s\n", str);*/
2371 ERROR_DECL (parse_error
);
2372 if (!mono_reflection_parse_type_checked (tmp
, &info
, parse_error
)) {
2373 mono_error_cleanup (parse_error
);
2376 type
= _mono_reflection_get_type_from_info (alc
, &info
, image
, FALSE
, TRUE
, error
);
2379 mono_reflection_free_type_info (&info
);
2384 * mono_reflection_get_token:
2385 * \returns the metadata token of \p obj which should be an object
2386 * representing a metadata element.
2389 mono_reflection_get_token (MonoObject
*obj_raw
)
2391 HANDLE_FUNCTION_ENTER ();
2392 MONO_HANDLE_DCL (MonoObject
, obj
);
2394 guint32 result
= mono_reflection_get_token_checked (obj
, error
);
2395 mono_error_assert_ok (error
);
2396 HANDLE_FUNCTION_RETURN_VAL (result
);
2400 * mono_reflection_get_param_info_member_and_pos:
2402 * Return the MemberImpl and PositionImpl fields of P.
2405 mono_reflection_get_param_info_member_and_pos (MonoReflectionParameterHandle p
, MonoObjectHandle member_impl
, int *out_position
)
2407 MonoClass
*klass
= mono_class_get_mono_parameter_info_class ();
2409 /* These two fields are part of ParameterInfo instead of RuntimeParameterInfo, and they cannot be moved */
2411 static MonoClassField
*member_field
;
2412 if (!member_field
) {
2413 MonoClassField
*f
= mono_class_get_field_from_name_full (klass
, "MemberImpl", NULL
);
2418 mono_field_get_value_internal (MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject
, p
)), member_field
, &member
);
2419 MONO_HANDLE_ASSIGN_RAW (member_impl
, member
);
2421 static MonoClassField
*pos_field
;
2423 MonoClassField
*f
= mono_class_get_field_from_name_full (klass
, "PositionImpl", NULL
);
2427 mono_field_get_value_internal (MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject
, p
)), pos_field
, out_position
);
2431 * mono_reflection_get_token_checked:
2432 * \param obj the object
2433 * \param error set on error
2434 * \returns the metadata token of \p obj which should be an object
2435 * representing a metadata element. On failure sets \p error.
2438 mono_reflection_get_token_checked (MonoObjectHandle obj
, MonoError
*error
)
2444 MonoClass
*klass
= mono_handle_class (obj
);
2446 const char *klass_name
= m_class_get_name (klass
);
2447 if (strcmp (klass_name
, "MethodBuilder") == 0) {
2448 MonoReflectionMethodBuilderHandle mb
= MONO_HANDLE_CAST (MonoReflectionMethodBuilder
, obj
);
2450 token
= MONO_HANDLE_GETVAL (mb
, table_idx
) | MONO_TOKEN_METHOD_DEF
;
2451 } else if (strcmp (klass_name
, "ConstructorBuilder") == 0) {
2452 MonoReflectionCtorBuilderHandle mb
= MONO_HANDLE_CAST (MonoReflectionCtorBuilder
, obj
);
2454 token
= MONO_HANDLE_GETVAL (mb
, table_idx
) | MONO_TOKEN_METHOD_DEF
;
2455 } else if (strcmp (klass_name
, "FieldBuilder") == 0) {
2456 g_assert_not_reached ();
2457 } else if (strcmp (klass_name
, "TypeBuilder") == 0) {
2458 MonoReflectionTypeBuilderHandle tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, obj
);
2459 token
= MONO_HANDLE_GETVAL (tb
, table_idx
) | MONO_TOKEN_TYPE_DEF
;
2460 } else if (strcmp (klass_name
, "RuntimeType") == 0) {
2461 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, obj
), error
);
2462 return_val_if_nok (error
, 0);
2463 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
2464 if (!mono_class_init_internal (mc
)) {
2465 mono_error_set_for_class_failure (error
, mc
);
2469 token
= m_class_get_type_token (mc
);
2470 } else if (strcmp (klass_name
, "RuntimeMethodInfo") == 0 ||
2471 strcmp (klass_name
, "RuntimeConstructorInfo") == 0) {
2472 MonoReflectionMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
2473 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
2474 if (method
->is_inflated
) {
2475 MonoMethodInflated
*inflated
= (MonoMethodInflated
*) method
;
2476 return inflated
->declaring
->token
;
2478 token
= method
->token
;
2480 } else if (strcmp (klass_name
, "RuntimeFieldInfo") == 0) {
2481 MonoReflectionFieldHandle f
= MONO_HANDLE_CAST (MonoReflectionField
, obj
);
2483 token
= mono_class_get_field_token (MONO_HANDLE_GETVAL (f
, field
));
2484 } else if (strcmp (klass_name
, "RuntimePropertyInfo") == 0) {
2485 MonoReflectionPropertyHandle p
= MONO_HANDLE_CAST (MonoReflectionProperty
, obj
);
2487 token
= mono_class_get_property_token (MONO_HANDLE_GETVAL (p
, property
));
2488 } else if (strcmp (klass_name
, "RuntimeEventInfo") == 0) {
2489 MonoReflectionMonoEventHandle p
= MONO_HANDLE_CAST (MonoReflectionMonoEvent
, obj
);
2491 token
= mono_class_get_event_token (MONO_HANDLE_GETVAL (p
, event
));
2492 } else if (strcmp (klass_name
, "ParameterInfo") == 0 || strcmp (klass_name
, "RuntimeParameterInfo") == 0) {
2493 MonoReflectionParameterHandle p
= MONO_HANDLE_CAST (MonoReflectionParameter
, obj
);
2495 MonoObjectHandle member_impl
= MONO_HANDLE_NEW (MonoObject
, NULL
);
2497 mono_reflection_get_param_info_member_and_pos (p
, member_impl
, &position
);
2499 MonoClass
*member_class
= mono_handle_class (member_impl
);
2500 g_assert (mono_class_is_reflection_method_or_constructor (member_class
));
2501 MonoMethod
*method
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionMethod
, member_impl
), method
);
2503 token
= mono_method_get_param_token (method
, position
);
2504 } else if (strcmp (klass_name
, "RuntimeModule") == 0 || strcmp (klass_name
, "ModuleBuilder") == 0) {
2505 MonoReflectionModuleHandle m
= MONO_HANDLE_CAST (MonoReflectionModule
, obj
);
2507 token
= MONO_HANDLE_GETVAL (m
, token
);
2508 } else if (strcmp (klass_name
, "RuntimeAssembly") == 0) {
2509 token
= mono_metadata_make_token (MONO_TABLE_ASSEMBLY
, 1);
2511 mono_error_set_not_implemented (error
, "MetadataToken is not supported for type '%s.%s'",
2512 m_class_get_name_space (klass
), klass_name
);
2521 mono_reflection_is_usertype (MonoReflectionTypeHandle ref
)
2523 MonoClass
*klass
= mono_handle_class (ref
);
2524 return m_class_get_image (klass
) != mono_defaults
.corlib
|| strcmp ("TypeDelegator", m_class_get_name (klass
)) == 0;
2528 * mono_reflection_bind_generic_parameters:
2529 * \param type a managed type object (which should be some kind of generic (instance? definition?))
2530 * \param type_args the number of type arguments to bind
2531 * \param types array of type arguments
2532 * \param error set on error
2533 * Given a managed type object for a generic type instance, binds each of its arguments to the specified types.
2534 * \returns the \c MonoType* for the resulting type instantiation. On failure returns NULL and sets \p error.
2537 mono_reflection_bind_generic_parameters (MonoReflectionTypeHandle reftype
, int type_argc
, MonoType
**types
, MonoError
*error
)
2539 gboolean is_dynamic
= FALSE
;
2544 mono_loader_lock ();
2546 MonoClass
*klass
= mono_handle_class (reftype
);
2547 if (mono_is_sre_type_builder (klass
)) {
2549 } else if (mono_is_sre_generic_instance (klass
)) {
2550 /* Does this ever make sense? what does instantiating a generic instance even mean? */
2551 g_assert_not_reached ();
2552 MonoReflectionGenericClassHandle rgi
= MONO_HANDLE_CAST (MonoReflectionGenericClass
, reftype
);
2553 MonoReflectionTypeHandle gtd
= MONO_HANDLE_NEW_GET (MonoReflectionType
, rgi
, generic_type
);
2555 if (mono_is_sre_type_builder (mono_handle_class (gtd
)))
2559 MonoType
*t
= mono_reflection_type_handle_mono_type (reftype
, error
);
2560 if (!is_ok (error
)) {
2561 mono_loader_unlock ();
2565 klass
= mono_class_from_mono_type_internal (t
);
2566 if (!mono_class_is_gtd (klass
)) {
2567 mono_loader_unlock ();
2568 mono_error_set_type_load_class (error
, klass
, "Cannot bind generic parameters of a non-generic type");
2572 guint gtd_type_argc
= mono_class_get_generic_container (klass
)->type_argc
;
2573 if (gtd_type_argc
!= type_argc
) {
2574 mono_loader_unlock ();
2575 mono_error_set_argument_format (error
, "types", "The generic type definition needs %d type arguments, but was instantiated with %d ", gtd_type_argc
, type_argc
);
2580 if (m_class_was_typebuilder (klass
))
2583 mono_loader_unlock ();
2585 geninst
= mono_class_bind_generic_parameters (klass
, type_argc
, types
, is_dynamic
);
2587 return m_class_get_byval_arg (geninst
);
2591 mono_class_bind_generic_parameters (MonoClass
*klass
, int type_argc
, MonoType
**types
, gboolean is_dynamic
)
2593 MonoGenericClass
*gclass
;
2594 MonoGenericInst
*inst
;
2596 g_assert (mono_class_is_gtd (klass
));
2598 inst
= mono_metadata_get_generic_inst (type_argc
, types
);
2599 gclass
= mono_metadata_lookup_generic_class (klass
, inst
, is_dynamic
);
2601 return mono_class_create_generic_inst (gclass
);
2604 static MonoGenericInst
*
2605 generic_inst_from_type_array_handle (MonoArrayHandle types
, MonoError
*error
)
2607 HANDLE_FUNCTION_ENTER ();
2609 MonoGenericInst
*ginst
= NULL
;
2610 int count
= mono_array_handle_length (types
);
2611 MonoType
**type_argv
= g_new0 (MonoType
*, count
);
2612 MonoReflectionTypeHandle garg
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
2613 for (int i
= 0; i
< count
; i
++) {
2614 MONO_HANDLE_ARRAY_GETREF (garg
, types
, i
);
2615 type_argv
[i
] = mono_reflection_type_handle_mono_type (garg
, error
);
2616 goto_if_nok (error
, leave
);
2619 ginst
= mono_metadata_get_generic_inst (count
, type_argv
);
2622 HANDLE_FUNCTION_RETURN_VAL (ginst
);
2626 reflection_bind_generic_method_parameters (MonoMethod
*method
, MonoArrayHandle types
, MonoError
*error
)
2629 MonoMethod
*inflated
;
2630 MonoGenericContext tmp_context
;
2634 klass
= method
->klass
;
2636 if (method
->is_inflated
)
2637 method
= ((MonoMethodInflated
*) method
)->declaring
;
2639 int count
= mono_method_signature_internal (method
)->generic_param_count
;
2640 if (count
!= mono_array_handle_length (types
)) {
2641 mono_error_set_argument (error
, "typeArguments", "Incorrect number of generic arguments");
2645 MonoGenericInst
*ginst
= generic_inst_from_type_array_handle (types
, error
);
2646 return_val_if_nok (error
, NULL
);
2648 tmp_context
.class_inst
= mono_class_is_ginst (klass
) ? mono_class_get_generic_class (klass
)->context
.class_inst
: NULL
;
2649 tmp_context
.method_inst
= ginst
;
2651 inflated
= mono_class_inflate_generic_method_checked (method
, &tmp_context
, error
);
2652 mono_error_assert_ok (error
);
2654 if (!mono_verifier_is_method_valid_generic_instantiation (inflated
)) {
2656 mono_error_set_argument (error
, NULL
, "Invalid generic arguments");
2658 mono_error_set_argument (error
, "typeArguments", "Invalid generic arguments");
2666 MonoReflectionMethodHandle
2667 ves_icall_RuntimeMethodInfo_MakeGenericMethod_impl (MonoReflectionMethodHandle rmethod
, MonoArrayHandle types
, MonoError
*error
)
2670 g_assert (0 != strcmp (m_class_get_name (mono_handle_class (rmethod
)), "MethodBuilder"));
2672 MonoMethod
*method
= MONO_HANDLE_GETVAL (rmethod
, method
);
2673 MonoMethod
*imethod
= reflection_bind_generic_method_parameters (method
, types
, error
);
2674 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
));
2676 MonoReflectionType
*reftype
= MONO_HANDLE_GETVAL (rmethod
, reftype
);
2677 MonoClass
*refclass
= mono_class_from_mono_type_internal (reftype
->type
);
2679 /*FIXME but I think this is no longer necessary*/
2680 if (image_is_dynamic (m_class_get_image (method
->klass
))) {
2681 MonoDynamicImage
*image
= (MonoDynamicImage
*)m_class_get_image (method
->klass
);
2683 * This table maps metadata structures representing inflated methods/fields
2684 * to the reflection objects representing their generic definitions.
2686 mono_image_lock ((MonoImage
*)image
);
2687 mono_g_hash_table_insert_internal (image
->generic_def_objects
, imethod
, MONO_HANDLE_RAW (rmethod
));
2688 mono_image_unlock ((MonoImage
*)image
);
2691 return mono_method_get_object_handle (MONO_HANDLE_DOMAIN (rmethod
), imethod
, refclass
, error
);
2695 /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
2696 const static guint32 declsec_flags_map
[] = {
2697 0x00000000, /* empty */
2698 MONO_DECLSEC_FLAG_REQUEST
, /* SECURITY_ACTION_REQUEST (x01) */
2699 MONO_DECLSEC_FLAG_DEMAND
, /* SECURITY_ACTION_DEMAND (x02) */
2700 MONO_DECLSEC_FLAG_ASSERT
, /* SECURITY_ACTION_ASSERT (x03) */
2701 MONO_DECLSEC_FLAG_DENY
, /* SECURITY_ACTION_DENY (x04) */
2702 MONO_DECLSEC_FLAG_PERMITONLY
, /* SECURITY_ACTION_PERMITONLY (x05) */
2703 MONO_DECLSEC_FLAG_LINKDEMAND
, /* SECURITY_ACTION_LINKDEMAND (x06) */
2704 MONO_DECLSEC_FLAG_INHERITANCEDEMAND
, /* SECURITY_ACTION_INHERITANCEDEMAND (x07) */
2705 MONO_DECLSEC_FLAG_REQUEST_MINIMUM
, /* SECURITY_ACTION_REQUEST_MINIMUM (x08) */
2706 MONO_DECLSEC_FLAG_REQUEST_OPTIONAL
, /* SECURITY_ACTION_REQUEST_OPTIONAL (x09) */
2707 MONO_DECLSEC_FLAG_REQUEST_REFUSE
, /* SECURITY_ACTION_REQUEST_REFUSE (x0A) */
2708 MONO_DECLSEC_FLAG_PREJIT_GRANT
, /* SECURITY_ACTION_PREJIT_GRANT (x0B) */
2709 MONO_DECLSEC_FLAG_PREJIT_DENY
, /* SECURITY_ACTION_PREJIT_DENY (x0C) */
2710 MONO_DECLSEC_FLAG_NONCAS_DEMAND
, /* SECURITY_ACTION_NONCAS_DEMAND (x0D) */
2711 MONO_DECLSEC_FLAG_NONCAS_LINKDEMAND
, /* SECURITY_ACTION_NONCAS_LINKDEMAND (x0E) */
2712 MONO_DECLSEC_FLAG_NONCAS_INHERITANCEDEMAND
, /* SECURITY_ACTION_NONCAS_INHERITANCEDEMAND (x0F) */
2713 MONO_DECLSEC_FLAG_LINKDEMAND_CHOICE
, /* SECURITY_ACTION_LINKDEMAND_CHOICE (x10) */
2714 MONO_DECLSEC_FLAG_INHERITANCEDEMAND_CHOICE
, /* SECURITY_ACTION_INHERITANCEDEMAND_CHOICE (x11) */
2715 MONO_DECLSEC_FLAG_DEMAND_CHOICE
, /* SECURITY_ACTION_DEMAND_CHOICE (x12) */
2719 * Returns flags that includes all available security action associated to the handle.
2720 * @token: metadata token (either for a class or a method)
2721 * @image: image where resides the metadata.
2724 mono_declsec_get_flags (MonoImage
*image
, guint32 token
)
2726 int index
= mono_metadata_declsec_from_index (image
, token
);
2727 MonoTableInfo
*t
= &image
->tables
[MONO_TABLE_DECLSECURITY
];
2732 /* HasSecurity can be present for other, not specially encoded, attributes,
2733 e.g. SuppressUnmanagedCodeSecurityAttribute */
2737 for (i
= index
; i
< t
->rows
; i
++) {
2738 guint32 cols
[MONO_DECL_SECURITY_SIZE
];
2740 mono_metadata_decode_row (t
, i
, cols
, MONO_DECL_SECURITY_SIZE
);
2741 if (cols
[MONO_DECL_SECURITY_PARENT
] != token
)
2744 action
= cols
[MONO_DECL_SECURITY_ACTION
];
2745 if ((action
>= MONO_DECLSEC_ACTION_MIN
) && (action
<= MONO_DECLSEC_ACTION_MAX
)) {
2746 result
|= declsec_flags_map
[action
];
2748 g_assert_not_reached ();
2755 * mono_declsec_flags_from_method:
2756 * \param method The method for which we want the declarative security flags.
2757 * Get the security actions (in the form of flags) associated with the specified method.
2758 * To keep \c MonoMethod size down we do not cache the declarative security flags
2759 * (except for the stack modifiers which are kept in the MonoJitInfo structure)
2760 * \returns the declarative security flags for the method (only).
2763 mono_declsec_flags_from_method (MonoMethod
*method
)
2765 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2766 /* FIXME: No cache (for the moment) */
2767 guint32 idx
= mono_method_get_index (method
);
2768 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2769 idx
|= MONO_HAS_DECL_SECURITY_METHODDEF
;
2770 return mono_declsec_get_flags (m_class_get_image (method
->klass
), idx
);
2776 * mono_declsec_flags_from_class:
2777 * \param klass The class for which we want the declarative security flags.
2778 * Get the security actions (in the form of flags) associated with the specified class.
2779 * We cache the flags inside the \c MonoClass structure as this will get
2780 * called very often (at least for each method).
2781 * \returns the declarative security flags for the class.
2784 mono_declsec_flags_from_class (MonoClass
*klass
)
2786 if (mono_class_get_flags (klass
) & TYPE_ATTRIBUTE_HAS_SECURITY
) {
2787 guint32 flags
= mono_class_get_declsec_flags (klass
);
2792 idx
= mono_metadata_token_index (m_class_get_type_token (klass
));
2793 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2794 idx
|= MONO_HAS_DECL_SECURITY_TYPEDEF
;
2795 flags
= mono_declsec_get_flags (m_class_get_image (klass
), idx
);
2796 /* we cache the flags on classes */
2797 mono_class_set_declsec_flags (klass
, flags
);
2805 * mono_declsec_flags_from_assembly:
2806 * \param assembly The assembly for which we want the declarative security flags.
2807 * Get the security actions (in the form of flags) associated with the specified assembly.
2808 * \returns the declarative security flags for the assembly.
2811 mono_declsec_flags_from_assembly (MonoAssembly
*assembly
)
2813 guint32 idx
= 1; /* there is only one assembly */
2814 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2815 idx
|= MONO_HAS_DECL_SECURITY_ASSEMBLY
;
2816 return mono_declsec_get_flags (assembly
->image
, idx
);
2821 * Fill actions for the specific index (which may either be an encoded class token or
2822 * an encoded method token) from the metadata image.
2823 * Returns TRUE if some actions requiring code generation are present, FALSE otherwise.
2826 fill_actions_from_index (MonoImage
*image
, guint32 token
, MonoDeclSecurityActions
* actions
,
2827 guint32 id_std
, guint32 id_noncas
, guint32 id_choice
)
2829 MonoBoolean result
= FALSE
;
2831 guint32 cols
[MONO_DECL_SECURITY_SIZE
];
2832 int index
= mono_metadata_declsec_from_index (image
, token
);
2835 t
= &image
->tables
[MONO_TABLE_DECLSECURITY
];
2836 for (i
= index
; i
< t
->rows
; i
++) {
2837 mono_metadata_decode_row (t
, i
, cols
, MONO_DECL_SECURITY_SIZE
);
2839 if (cols
[MONO_DECL_SECURITY_PARENT
] != token
)
2842 /* if present only replace (class) permissions with method permissions */
2843 /* if empty accept either class or method permissions */
2844 if (cols
[MONO_DECL_SECURITY_ACTION
] == id_std
) {
2845 if (!actions
->demand
.blob
) {
2846 const char *blob
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2847 actions
->demand
.index
= cols
[MONO_DECL_SECURITY_PERMISSIONSET
];
2848 actions
->demand
.blob
= (char*) (blob
+ 2);
2849 actions
->demand
.size
= mono_metadata_decode_blob_size (blob
, &blob
);
2852 } else if (cols
[MONO_DECL_SECURITY_ACTION
] == id_noncas
) {
2853 if (!actions
->noncasdemand
.blob
) {
2854 const char *blob
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2855 actions
->noncasdemand
.index
= cols
[MONO_DECL_SECURITY_PERMISSIONSET
];
2856 actions
->noncasdemand
.blob
= (char*) (blob
+ 2);
2857 actions
->noncasdemand
.size
= mono_metadata_decode_blob_size (blob
, &blob
);
2860 } else if (cols
[MONO_DECL_SECURITY_ACTION
] == id_choice
) {
2861 if (!actions
->demandchoice
.blob
) {
2862 const char *blob
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
2863 actions
->demandchoice
.index
= cols
[MONO_DECL_SECURITY_PERMISSIONSET
];
2864 actions
->demandchoice
.blob
= (char*) (blob
+ 2);
2865 actions
->demandchoice
.size
= mono_metadata_decode_blob_size (blob
, &blob
);
2875 mono_declsec_get_class_demands_params (MonoClass
*klass
, MonoDeclSecurityActions
* demands
,
2876 guint32 id_std
, guint32 id_noncas
, guint32 id_choice
)
2878 guint32 idx
= mono_metadata_token_index (m_class_get_type_token (klass
));
2879 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2880 idx
|= MONO_HAS_DECL_SECURITY_TYPEDEF
;
2881 return fill_actions_from_index (m_class_get_image (klass
), idx
, demands
, id_std
, id_noncas
, id_choice
);
2885 mono_declsec_get_method_demands_params (MonoMethod
*method
, MonoDeclSecurityActions
* demands
,
2886 guint32 id_std
, guint32 id_noncas
, guint32 id_choice
)
2888 guint32 idx
= mono_method_get_index (method
);
2889 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
2890 idx
|= MONO_HAS_DECL_SECURITY_METHODDEF
;
2891 return fill_actions_from_index (m_class_get_image (method
->klass
), idx
, demands
, id_std
, id_noncas
, id_choice
);
2895 * mono_declsec_get_demands:
2896 * Collect all actions (that requires to generate code in mini) assigned for
2897 * the specified method.
2898 * Don't use the content of actions if the function return FALSE.
2901 mono_declsec_get_demands (MonoMethod
*method
, MonoDeclSecurityActions
* demands
)
2903 guint32 mask
= MONO_DECLSEC_FLAG_DEMAND
| MONO_DECLSEC_FLAG_NONCAS_DEMAND
|
2904 MONO_DECLSEC_FLAG_DEMAND_CHOICE
;
2905 MonoBoolean result
= FALSE
;
2908 /* quick exit if no declarative security is present in the metadata */
2909 if (!m_class_get_image (method
->klass
)->tables
[MONO_TABLE_DECLSECURITY
].rows
)
2912 /* we want the original as the wrapper is "free" of the security informations */
2913 if (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_MANAGED
) {
2914 method
= mono_marshal_method_from_wrapper (method
);
2919 /* First we look for method-level attributes */
2920 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2921 mono_class_init_internal (method
->klass
);
2922 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
2924 result
= mono_declsec_get_method_demands_params (method
, demands
,
2925 SECURITY_ACTION_DEMAND
, SECURITY_ACTION_NONCASDEMAND
, SECURITY_ACTION_DEMANDCHOICE
);
2928 /* Here we use (or create) the class declarative cache to look for demands */
2929 flags
= mono_declsec_flags_from_class (method
->klass
);
2932 mono_class_init_internal (method
->klass
);
2933 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
2935 result
|= mono_declsec_get_class_demands_params (method
->klass
, demands
,
2936 SECURITY_ACTION_DEMAND
, SECURITY_ACTION_NONCASDEMAND
, SECURITY_ACTION_DEMANDCHOICE
);
2939 /* The boolean return value is used as a shortcut in case nothing needs to
2940 be generated (e.g. LinkDemand[Choice] and InheritanceDemand[Choice]) */
2946 * mono_declsec_get_linkdemands:
2947 * Collect all Link actions: \c LinkDemand, \c NonCasLinkDemand and \c LinkDemandChoice (2.0).
2948 * Don't use the content of actions if the function return FALSE.
2951 mono_declsec_get_linkdemands (MonoMethod
*method
, MonoDeclSecurityActions
* klass
, MonoDeclSecurityActions
*cmethod
)
2953 MonoBoolean result
= FALSE
;
2956 /* quick exit if no declarative security is present in the metadata */
2957 if (!m_class_get_image (method
->klass
)->tables
[MONO_TABLE_DECLSECURITY
].rows
)
2960 /* we want the original as the wrapper is "free" of the security informations */
2961 if (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_MANAGED
) {
2962 method
= mono_marshal_method_from_wrapper (method
);
2967 /* results are independant - zeroize both */
2968 memset (cmethod
, 0, sizeof (MonoDeclSecurityActions
));
2969 memset (klass
, 0, sizeof (MonoDeclSecurityActions
));
2971 /* First we look for method-level attributes */
2972 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
2973 mono_class_init_internal (method
->klass
);
2975 result
= mono_declsec_get_method_demands_params (method
, cmethod
,
2976 SECURITY_ACTION_LINKDEMAND
, SECURITY_ACTION_NONCASLINKDEMAND
, SECURITY_ACTION_LINKDEMANDCHOICE
);
2979 /* Here we use (or create) the class declarative cache to look for demands */
2980 flags
= mono_declsec_flags_from_class (method
->klass
);
2981 if (flags
& (MONO_DECLSEC_FLAG_LINKDEMAND
| MONO_DECLSEC_FLAG_NONCAS_LINKDEMAND
| MONO_DECLSEC_FLAG_LINKDEMAND_CHOICE
)) {
2982 mono_class_init_internal (method
->klass
);
2984 result
|= mono_declsec_get_class_demands_params (method
->klass
, klass
,
2985 SECURITY_ACTION_LINKDEMAND
, SECURITY_ACTION_NONCASLINKDEMAND
, SECURITY_ACTION_LINKDEMANDCHOICE
);
2992 * mono_declsec_get_inheritdemands_class:
2993 * \param klass The inherited class - this is the class that provides the security check (attributes)
2995 * Collect all Inherit actions - \c InheritanceDemand, \c NonCasInheritanceDemand and \c InheritanceDemandChoice (2.0).
2996 * Don't use the content of actions if the function return FALSE.
2997 * \returns TRUE if inheritance demands (any kind) are present, FALSE otherwise.
3000 mono_declsec_get_inheritdemands_class (MonoClass
*klass
, MonoDeclSecurityActions
* demands
)
3002 MonoBoolean result
= FALSE
;
3005 /* quick exit if no declarative security is present in the metadata */
3006 if (!m_class_get_image (klass
)->tables
[MONO_TABLE_DECLSECURITY
].rows
)
3009 /* Here we use (or create) the class declarative cache to look for demands */
3010 flags
= mono_declsec_flags_from_class (klass
);
3011 if (flags
& (MONO_DECLSEC_FLAG_INHERITANCEDEMAND
| MONO_DECLSEC_FLAG_NONCAS_INHERITANCEDEMAND
| MONO_DECLSEC_FLAG_INHERITANCEDEMAND_CHOICE
)) {
3012 mono_class_init_internal (klass
);
3013 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
3015 result
|= mono_declsec_get_class_demands_params (klass
, demands
,
3016 SECURITY_ACTION_INHERITDEMAND
, SECURITY_ACTION_NONCASINHERITANCE
, SECURITY_ACTION_INHERITDEMANDCHOICE
);
3023 * mono_declsec_get_inheritdemands_method:
3024 * Collect all Inherit actions: \c InheritanceDemand, \c NonCasInheritanceDemand and \c InheritanceDemandChoice (2.0).
3025 * Don't use the content of actions if the function return FALSE.
3028 mono_declsec_get_inheritdemands_method (MonoMethod
*method
, MonoDeclSecurityActions
* demands
)
3030 /* quick exit if no declarative security is present in the metadata */
3031 if (!m_class_get_image (method
->klass
)->tables
[MONO_TABLE_DECLSECURITY
].rows
)
3034 /* we want the original as the wrapper is "free" of the security informations */
3035 if (method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_NATIVE
|| method
->wrapper_type
== MONO_WRAPPER_MANAGED_TO_MANAGED
) {
3036 method
= mono_marshal_method_from_wrapper (method
);
3041 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
3042 mono_class_init_internal (method
->klass
);
3043 memset (demands
, 0, sizeof (MonoDeclSecurityActions
));
3045 return mono_declsec_get_method_demands_params (method
, demands
,
3046 SECURITY_ACTION_INHERITDEMAND
, SECURITY_ACTION_NONCASINHERITANCE
, SECURITY_ACTION_INHERITDEMANDCHOICE
);
3053 get_declsec_action (MonoImage
*image
, guint32 token
, guint32 action
, MonoDeclSecurityEntry
*entry
)
3055 guint32 cols
[MONO_DECL_SECURITY_SIZE
];
3059 int index
= mono_metadata_declsec_from_index (image
, token
);
3063 t
= &image
->tables
[MONO_TABLE_DECLSECURITY
];
3064 for (i
= index
; i
< t
->rows
; i
++) {
3065 mono_metadata_decode_row (t
, i
, cols
, MONO_DECL_SECURITY_SIZE
);
3067 /* shortcut - index are ordered */
3068 if (token
!= cols
[MONO_DECL_SECURITY_PARENT
])
3071 if (cols
[MONO_DECL_SECURITY_ACTION
] == action
) {
3072 const char *metadata
= mono_metadata_blob_heap (image
, cols
[MONO_DECL_SECURITY_PERMISSIONSET
]);
3073 entry
->blob
= (char*) (metadata
+ 2);
3074 entry
->size
= mono_metadata_decode_blob_size (metadata
, &metadata
);
3083 mono_declsec_get_method_action (MonoMethod
*method
, guint32 action
, MonoDeclSecurityEntry
*entry
)
3085 if (method
->flags
& METHOD_ATTRIBUTE_HAS_SECURITY
) {
3086 guint32 idx
= mono_method_get_index (method
);
3087 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
3088 idx
|= MONO_HAS_DECL_SECURITY_METHODDEF
;
3089 return get_declsec_action (m_class_get_image (method
->klass
), idx
, action
, entry
);
3095 * mono_declsec_get_class_action:
3098 mono_declsec_get_class_action (MonoClass
*klass
, guint32 action
, MonoDeclSecurityEntry
*entry
)
3101 guint32 flags
= mono_declsec_flags_from_class (klass
);
3102 if (declsec_flags_map
[action
] & flags
) {
3103 guint32 idx
= mono_metadata_token_index (m_class_get_type_token (klass
));
3104 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
3105 idx
|= MONO_HAS_DECL_SECURITY_TYPEDEF
;
3106 return get_declsec_action (m_class_get_image (klass
), idx
, action
, entry
);
3112 * mono_declsec_get_assembly_action:
3115 mono_declsec_get_assembly_action (MonoAssembly
*assembly
, guint32 action
, MonoDeclSecurityEntry
*entry
)
3117 guint32 idx
= 1; /* there is only one assembly */
3118 idx
<<= MONO_HAS_DECL_SECURITY_BITS
;
3119 idx
|= MONO_HAS_DECL_SECURITY_ASSEMBLY
;
3121 return get_declsec_action (assembly
->image
, idx
, action
, entry
);
3125 mono_reflection_call_is_assignable_to (MonoClass
*klass
, MonoClass
*oklass
, MonoError
*error
)
3127 MonoObject
*res
, *exc
;
3129 static MonoMethod
*method
= NULL
;
3133 if (method
== NULL
) {
3134 method
= mono_class_get_method_from_name_checked (mono_class_get_type_builder_class (), "IsAssignableTo", 1, 0, error
);
3135 mono_error_assert_ok (error
);
3140 * The result of mono_type_get_object_checked () might be a System.MonoType but we
3141 * need a TypeBuilder so use mono_class_get_ref_info (klass).
3143 g_assert (mono_class_has_ref_info (klass
));
3144 g_assert (!strcmp (m_class_get_name (mono_object_class (&mono_class_get_ref_info_raw (klass
)->type
.object
)), "TypeBuilder")); /* FIXME use handles */
3146 params
[0] = mono_type_get_object_checked (mono_domain_get (), m_class_get_byval_arg (oklass
), error
);
3147 return_val_if_nok (error
, FALSE
);
3149 ERROR_DECL (inner_error
);
3150 res
= mono_runtime_try_invoke (method
, &mono_class_get_ref_info_raw (klass
)->type
.object
, params
, &exc
, inner_error
); /* FIXME use handles */
3152 if (exc
|| !is_ok (inner_error
)) {
3153 mono_error_cleanup (inner_error
);
3156 return *(MonoBoolean
*)mono_object_unbox_internal (res
);
3160 * mono_reflection_type_get_type:
3161 * \param reftype the \c System.Type object
3162 * \returns the \c MonoType* associated with the C# \c System.Type object \p reftype.
3165 mono_reflection_type_get_type (MonoReflectionType
*reftype
)
3168 MONO_ENTER_GC_UNSAFE
;
3172 result
= mono_reflection_type_get_handle (reftype
, error
);
3173 mono_error_assert_ok (error
);
3174 MONO_EXIT_GC_UNSAFE
;
3179 * mono_reflection_assembly_get_assembly:
3180 * \param refassembly the \c System.Reflection.Assembly object
3181 * \returns the \c MonoAssembly* associated with the C# \c System.Reflection.Assembly object \p refassembly.
3184 mono_reflection_assembly_get_assembly (MonoReflectionAssembly
*refassembly
)
3186 g_assert (refassembly
);
3188 return refassembly
->assembly
;
3192 * mono_class_from_mono_type_handle:
3193 * \param reftype the \c System.Type handle
3194 * \returns the \c MonoClass* corresponding to the given type.
3197 mono_class_from_mono_type_handle (MonoReflectionTypeHandle reftype
)
3199 return mono_class_from_mono_type_internal (MONO_HANDLE_RAW (reftype
)->type
);
3202 // This is called by icalls, it will return NULL and set pending exception (in wrapper) on failure.
3203 MonoReflectionTypeHandle
3204 mono_type_from_handle_impl (MonoType
*handle
, MonoError
*error
)
3206 mono_class_init_internal (mono_class_from_mono_type_internal (handle
));
3207 return mono_type_get_object_handle (mono_domain_get (), handle
, error
);