3 * Routines for creating an image at runtime
4 * and related System.Reflection.Emit icalls
8 * Paolo Molaro (lupus@ximian.com)
10 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
12 * Copyright 2011 Rodrigo Kumpera
13 * Copyright 2016 Microsoft
15 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
19 #include "mono/metadata/assembly.h"
20 #include "mono/metadata/assembly-internals.h"
21 #include "mono/metadata/class-init.h"
22 #include "mono/metadata/debug-helpers.h"
23 #include "mono/metadata/dynamic-image-internals.h"
24 #include "mono/metadata/dynamic-stream-internals.h"
25 #include "mono/metadata/exception.h"
26 #include "mono/metadata/gc-internals.h"
27 #include "mono/metadata/mono-ptr-array.h"
28 #include "mono/metadata/object-internals.h"
29 #include "mono/metadata/profiler-private.h"
30 #include "mono/metadata/reflection-internals.h"
31 #include "mono/metadata/reflection-cache.h"
32 #include "mono/metadata/sre-internals.h"
33 #include "mono/metadata/custom-attrs-internals.h"
34 #include "mono/metadata/security-manager.h"
35 #include "mono/metadata/security-core-clr.h"
36 #include "mono/metadata/tabledefs.h"
37 #include "mono/metadata/tokentype.h"
38 #include "mono/metadata/abi-details.h"
39 #include "mono/utils/checked-build.h"
40 #include "mono/utils/mono-digest.h"
41 #include "mono/utils/w32api.h"
42 #ifdef MONO_CLASS_DEF_PRIVATE
43 /* Rationale: Some of the code here does MonoClass construction.
44 * FIXME: Move SRE class construction to class-init.c and unify with ordinary class construction.
46 #define REALLY_INCLUDE_CLASS_DEF 1
47 #include <mono/metadata/class-private-definition.h>
48 #undef REALLY_INCLUDE_CLASS_DEF
50 #include "icall-decl.h"
52 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute
, "System.Runtime.InteropServices", "MarshalAsAttribute");
53 #ifndef DISABLE_REFLECTION_EMIT
54 static GENERATE_GET_CLASS_WITH_CACHE (module_builder
, "System.Reflection.Emit", "ModuleBuilder");
57 static char* string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s
, MonoError
*error
);
59 #ifndef DISABLE_REFLECTION_EMIT
60 static guint32
mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
);
61 static gboolean
ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
);
62 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
);
63 static gboolean
reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
64 static gboolean
reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
65 static gboolean
reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
);
68 static gpointer
register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
);
71 static char* type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
);
72 static MonoReflectionTypeHandle
mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
);
73 static gboolean
is_sre_array (MonoClass
*klass
);
74 static gboolean
is_sre_byref (MonoClass
*klass
);
75 static gboolean
is_sre_pointer (MonoClass
*klass
);
76 static gboolean
is_sre_generic_instance (MonoClass
*klass
);
77 static gboolean
is_sre_type_builder (MonoClass
*klass
);
78 static gboolean
is_sre_method_builder (MonoClass
*klass
);
79 static gboolean
is_sre_field_builder (MonoClass
*klass
);
80 static gboolean
is_sre_gparam_builder (MonoClass
*klass
);
81 static gboolean
is_sre_enum_builder (MonoClass
*klass
);
82 static gboolean
is_sr_mono_method (MonoClass
*klass
);
84 static guint32
mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
);
85 static guint32
mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
);
86 static guint32
mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
);
89 #ifndef DISABLE_REFLECTION_EMIT
90 static MonoType
* mono_type_array_get_and_resolve_raw (MonoArray
* array
, int idx
, MonoError
* error
);
93 static gboolean
mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module
, MonoError
*error
);
96 mono_reflection_emit_init (void)
98 mono_dynamic_images_init ();
102 string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s_raw
, MonoError
*error
)
104 /* FIXME all callers to string_to_utf8_image_raw should use handles */
105 HANDLE_FUNCTION_ENTER ();
107 MONO_HANDLE_DCL (MonoString
, s
);
108 char* const result
= mono_string_to_utf8_image (image
, s
, error
);
109 HANDLE_FUNCTION_RETURN_VAL (result
);
113 type_get_fully_qualified_name (MonoType
*type
)
115 MONO_REQ_GC_NEUTRAL_MODE
;
117 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
121 type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
)
123 MONO_REQ_GC_UNSAFE_MODE
;
128 klass
= mono_class_from_mono_type_internal (type
);
130 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
131 ta
= klass
->image
->assembly
;
132 if (assembly_is_dynamic (ta
) || (ta
== ass
)) {
133 if (mono_class_is_ginst (klass
) || mono_class_is_gtd (klass
))
134 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
135 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_FULL_NAME
);
137 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
140 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
143 #ifndef DISABLE_REFLECTION_EMIT
147 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
151 image_g_malloc (MonoImage
*image
, guint size
)
153 MONO_REQ_GC_NEUTRAL_MODE
;
156 return mono_image_alloc (image
, size
);
158 return g_malloc (size
);
160 #endif /* !DISABLE_REFLECTION_EMIT */
165 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
169 (mono_image_g_malloc0
) (MonoImage
*image
, guint size
)
171 MONO_REQ_GC_NEUTRAL_MODE
;
174 return mono_image_alloc0 (image
, size
);
176 return g_malloc0 (size
);
181 * @image: a MonoImage
184 * If @image is NULL, free @ptr, otherwise do nothing.
187 image_g_free (MonoImage
*image
, gpointer ptr
)
193 #ifndef DISABLE_REFLECTION_EMIT
195 image_strdup (MonoImage
*image
, const char *s
)
197 MONO_REQ_GC_NEUTRAL_MODE
;
200 return mono_image_strdup (image
, s
);
206 #define image_g_new(image,struct_type, n_structs) \
207 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
209 #define image_g_new0(image,struct_type, n_structs) \
210 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
214 alloc_table (MonoDynamicTable
*table
, guint nrows
)
216 mono_dynimage_alloc_table (table
, nrows
);
220 string_heap_insert (MonoDynamicStream
*sh
, const char *str
)
222 return mono_dynstream_insert_string (sh
, str
);
226 mono_image_add_stream_data (MonoDynamicStream
*stream
, const char *data
, guint32 len
)
228 return mono_dynstream_add_data (stream
, data
, len
);
232 * Despite the name, we handle also TypeSpec (with the above helper).
235 mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
)
237 return mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, TRUE
);
241 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
242 * dest may be misaligned.
245 swap_with_size (gpointer void_dest
, gconstpointer void_val
, int len
, int nelem
)
247 char *dest
= (char*)void_dest
;
248 const char* val
= (const char*)void_val
;
249 MONO_REQ_GC_NEUTRAL_MODE
;
250 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
253 for (elem
= 0; elem
< nelem
; ++elem
) {
279 g_assert_not_reached ();
285 memcpy (dest
, val
, len
* nelem
);
290 mono_reflection_method_count_clauses (MonoReflectionILGen
*ilgen
)
292 MONO_REQ_GC_UNSAFE_MODE
;
294 guint32 num_clauses
= 0;
297 MonoILExceptionInfo
*ex_info
;
298 for (i
= 0; i
< mono_array_length_internal (ilgen
->ex_handlers
); ++i
) {
299 ex_info
= (MonoILExceptionInfo
*)mono_array_addr_internal (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
300 if (ex_info
->handlers
)
301 num_clauses
+= mono_array_length_internal (ex_info
->handlers
);
309 #ifndef DISABLE_REFLECTION_EMIT
310 static MonoExceptionClause
*
311 method_encode_clauses (MonoImage
*image
, MonoDynamicImage
*assembly
, MonoReflectionILGen
*ilgen
, guint32 num_clauses
, MonoError
*error
)
313 MONO_REQ_GC_UNSAFE_MODE
;
317 MonoExceptionClause
*clauses
;
318 MonoExceptionClause
*clause
;
319 MonoILExceptionInfo
*ex_info
;
320 MonoILExceptionBlock
*ex_block
;
321 guint32 finally_start
;
322 int i
, j
, clause_index
;
324 clauses
= image_g_new0 (image
, MonoExceptionClause
, num_clauses
);
327 for (i
= mono_array_length_internal (ilgen
->ex_handlers
) - 1; i
>= 0; --i
) {
328 ex_info
= (MonoILExceptionInfo
*)mono_array_addr_internal (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
329 finally_start
= ex_info
->start
+ ex_info
->len
;
330 if (!ex_info
->handlers
)
332 for (j
= 0; j
< mono_array_length_internal (ex_info
->handlers
); ++j
) {
333 ex_block
= (MonoILExceptionBlock
*)mono_array_addr_internal (ex_info
->handlers
, MonoILExceptionBlock
, j
);
334 clause
= &(clauses
[clause_index
]);
336 clause
->flags
= ex_block
->type
;
337 clause
->try_offset
= ex_info
->start
;
339 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FINALLY
)
340 clause
->try_len
= finally_start
- ex_info
->start
;
342 clause
->try_len
= ex_info
->len
;
343 clause
->handler_offset
= ex_block
->start
;
344 clause
->handler_len
= ex_block
->len
;
345 if (ex_block
->extype
) {
346 MonoType
*extype
= mono_reflection_type_get_handle ((MonoReflectionType
*)ex_block
->extype
, error
);
348 if (!is_ok (error
)) {
349 image_g_free (image
, clauses
);
352 clause
->data
.catch_class
= mono_class_from_mono_type_internal (extype
);
354 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FILTER
)
355 clause
->data
.filter_offset
= ex_block
->filter_offset
;
357 clause
->data
.filter_offset
= 0;
359 finally_start
= ex_block
->start
+ ex_block
->len
;
367 #endif /* !DISABLE_REFLECTION_EMIT */
369 #ifndef DISABLE_REFLECTION_EMIT
371 * LOCKING: Acquires the loader lock.
374 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
376 MONO_REQ_GC_UNSAFE_MODE
;
378 MonoCustomAttrInfo
*ainfo
, *tmp
;
380 if (!cattrs
|| !mono_array_length_internal (cattrs
))
383 ainfo
= mono_custom_attrs_from_builders (image
, image
, cattrs
);
386 tmp
= (MonoCustomAttrInfo
*)mono_image_property_lookup (image
, obj
, MONO_PROP_DYNAMIC_CATTR
);
388 mono_custom_attrs_free (tmp
);
389 mono_image_property_insert (image
, obj
, MONO_PROP_DYNAMIC_CATTR
, ainfo
);
390 mono_loader_unlock ();
394 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
396 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
402 mono_reflection_resolution_scope_from_image (MonoDynamicImage
*assembly
, MonoImage
*image
)
404 MONO_REQ_GC_UNSAFE_MODE
;
406 MonoDynamicTable
*table
;
409 guint32 cols
[MONO_ASSEMBLY_SIZE
];
413 if ((token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, image
))))
416 if (assembly_is_dynamic (image
->assembly
) && (image
->assembly
== assembly
->image
.assembly
)) {
417 table
= &assembly
->tables
[MONO_TABLE_MODULEREF
];
418 token
= table
->next_idx
++;
420 alloc_table (table
, table
->rows
);
421 values
= table
->values
+ token
* MONO_MODULEREF_SIZE
;
422 values
[MONO_MODULEREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->module_name
);
424 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
425 token
|= MONO_RESOLUTION_SCOPE_MODULEREF
;
426 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
431 if (assembly_is_dynamic (image
->assembly
))
433 memset (cols
, 0, sizeof (cols
));
435 /* image->assembly->image is the manifest module */
436 image
= image
->assembly
->image
;
437 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_ASSEMBLY
], 0, cols
, MONO_ASSEMBLY_SIZE
);
440 table
= &assembly
->tables
[MONO_TABLE_ASSEMBLYREF
];
441 token
= table
->next_idx
++;
443 alloc_table (table
, table
->rows
);
444 values
= table
->values
+ token
* MONO_ASSEMBLYREF_SIZE
;
445 values
[MONO_ASSEMBLYREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->assembly_name
);
446 values
[MONO_ASSEMBLYREF_MAJOR_VERSION
] = cols
[MONO_ASSEMBLY_MAJOR_VERSION
];
447 values
[MONO_ASSEMBLYREF_MINOR_VERSION
] = cols
[MONO_ASSEMBLY_MINOR_VERSION
];
448 values
[MONO_ASSEMBLYREF_BUILD_NUMBER
] = cols
[MONO_ASSEMBLY_BUILD_NUMBER
];
449 values
[MONO_ASSEMBLYREF_REV_NUMBER
] = cols
[MONO_ASSEMBLY_REV_NUMBER
];
450 values
[MONO_ASSEMBLYREF_FLAGS
] = 0;
451 values
[MONO_ASSEMBLYREF_CULTURE
] = 0;
452 values
[MONO_ASSEMBLYREF_HASH_VALUE
] = 0;
454 if (strcmp ("", image
->assembly
->aname
.culture
)) {
455 values
[MONO_ASSEMBLYREF_CULTURE
] = string_heap_insert (&assembly
->sheap
,
456 image
->assembly
->aname
.culture
);
459 if ((pubkey
= mono_image_get_public_key (image
, &publen
))) {
462 mono_digest_get_public_token (pubtoken
+ 1, (guchar
*)pubkey
, publen
);
463 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = mono_image_add_stream_data (&assembly
->blob
, (char*)pubtoken
, 9);
465 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = 0;
467 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
468 token
|= MONO_RESOLUTION_SCOPE_ASSEMBLYREF
;
469 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
473 #ifndef DISABLE_REFLECTION_EMIT
475 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
)
477 MONO_REQ_GC_UNSAFE_MODE
;
480 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
482 rmb
->ilgen
= mb
->ilgen
;
483 MONO_HANDLE_PIN (rmb
->ilgen
);
484 rmb
->rtype
= (MonoReflectionType
*)mb
->rtype
;
485 MONO_HANDLE_PIN (rmb
->rtype
);
486 rmb
->parameters
= mb
->parameters
;
487 MONO_HANDLE_PIN (rmb
->parameters
);
488 rmb
->generic_params
= mb
->generic_params
;
489 MONO_HANDLE_PIN (rmb
->generic_params
);
490 rmb
->generic_container
= mb
->generic_container
;
491 rmb
->opt_types
= NULL
;
492 rmb
->pinfo
= mb
->pinfo
;
493 MONO_HANDLE_PIN (rmb
->pinfo
);
494 rmb
->attrs
= mb
->attrs
;
495 rmb
->iattrs
= mb
->iattrs
;
496 rmb
->call_conv
= mb
->call_conv
;
497 rmb
->code
= mb
->code
;
498 MONO_HANDLE_PIN (rmb
->code
);
499 rmb
->type
= mb
->type
;
500 MONO_HANDLE_PIN (rmb
->type
);
501 rmb
->name
= mb
->name
;
502 MONO_HANDLE_PIN (rmb
->name
);
503 rmb
->table_idx
= &mb
->table_idx
;
504 rmb
->init_locals
= mb
->init_locals
;
505 rmb
->skip_visibility
= FALSE
;
506 rmb
->return_modreq
= mb
->return_modreq
;
507 MONO_HANDLE_PIN (rmb
->return_modreq
);
508 rmb
->return_modopt
= mb
->return_modopt
;
509 MONO_HANDLE_PIN (rmb
->return_modopt
);
510 rmb
->param_modreq
= mb
->param_modreq
;
511 MONO_HANDLE_PIN (rmb
->param_modreq
);
512 rmb
->param_modopt
= mb
->param_modopt
;
513 MONO_HANDLE_PIN (rmb
->param_modopt
);
514 rmb
->permissions
= mb
->permissions
;
515 MONO_HANDLE_PIN (rmb
->permissions
);
516 rmb
->mhandle
= mb
->mhandle
;
521 rmb
->charset
= mb
->charset
;
522 rmb
->extra_flags
= mb
->extra_flags
;
523 rmb
->native_cc
= mb
->native_cc
;
524 rmb
->dllentry
= mb
->dllentry
;
525 MONO_HANDLE_PIN (rmb
->dllentry
);
527 MONO_HANDLE_PIN (rmb
->dll
);
534 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
536 MONO_REQ_GC_UNSAFE_MODE
;
538 const char *name
= mb
->attrs
& METHOD_ATTRIBUTE_STATIC
? ".cctor": ".ctor";
542 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
544 rmb
->ilgen
= mb
->ilgen
;
545 MONO_HANDLE_PIN (rmb
->ilgen
);
546 rmb
->rtype
= mono_type_get_object_checked (mono_domain_get (), mono_get_void_type (), error
);
547 return_val_if_nok (error
, FALSE
);
548 MONO_HANDLE_PIN (rmb
->rtype
);
549 rmb
->parameters
= mb
->parameters
;
550 MONO_HANDLE_PIN (rmb
->parameters
);
551 rmb
->generic_params
= NULL
;
552 rmb
->generic_container
= NULL
;
553 rmb
->opt_types
= NULL
;
554 rmb
->pinfo
= mb
->pinfo
;
555 MONO_HANDLE_PIN (rmb
->pinfo
);
556 rmb
->attrs
= mb
->attrs
;
557 rmb
->iattrs
= mb
->iattrs
;
558 rmb
->call_conv
= mb
->call_conv
;
560 rmb
->type
= mb
->type
;
561 MONO_HANDLE_PIN (rmb
->type
);
562 rmb
->name
= mono_string_new_checked (mono_domain_get (), name
, error
);
563 return_val_if_nok (error
, FALSE
);
564 MONO_HANDLE_PIN (rmb
->name
);
565 rmb
->table_idx
= &mb
->table_idx
;
566 rmb
->init_locals
= mb
->init_locals
;
567 rmb
->skip_visibility
= FALSE
;
568 rmb
->return_modreq
= NULL
;
569 rmb
->return_modopt
= NULL
;
570 rmb
->param_modreq
= mb
->param_modreq
;
571 MONO_HANDLE_PIN (rmb
->param_modreq
);
572 rmb
->param_modopt
= mb
->param_modopt
;
573 MONO_HANDLE_PIN (rmb
->param_modopt
);
574 rmb
->permissions
= mb
->permissions
;
575 MONO_HANDLE_PIN (rmb
->permissions
);
576 rmb
->mhandle
= mb
->mhandle
;
584 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
)
586 MONO_REQ_GC_UNSAFE_MODE
;
588 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
590 rmb
->ilgen
= mb
->ilgen
;
591 MONO_HANDLE_PIN (rmb
->ilgen
);
592 rmb
->rtype
= mb
->rtype
;
593 MONO_HANDLE_PIN (rmb
->type
);
594 rmb
->parameters
= mb
->parameters
;
595 MONO_HANDLE_PIN (rmb
->parameters
);
596 rmb
->generic_params
= NULL
;
597 rmb
->generic_container
= NULL
;
598 rmb
->opt_types
= NULL
;
600 rmb
->attrs
= mb
->attrs
;
602 rmb
->call_conv
= mb
->call_conv
;
604 rmb
->type
= (MonoObject
*) mb
->owner
;
605 MONO_HANDLE_PIN (rmb
->type
);
606 rmb
->name
= mb
->name
;
607 MONO_HANDLE_PIN (rmb
->name
);
608 rmb
->table_idx
= NULL
;
609 rmb
->init_locals
= mb
->init_locals
;
610 rmb
->skip_visibility
= mb
->skip_visibility
;
611 rmb
->return_modreq
= NULL
;
612 rmb
->return_modopt
= NULL
;
613 rmb
->param_modreq
= NULL
;
614 rmb
->param_modopt
= NULL
;
615 rmb
->permissions
= NULL
;
616 rmb
->mhandle
= mb
->mhandle
;
620 #else /* DISABLE_REFLECTION_EMIT */
622 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
) {
623 g_assert_not_reached ();
627 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
629 g_assert_not_reached ();
632 #endif /* DISABLE_REFLECTION_EMIT */
634 #ifndef DISABLE_REFLECTION_EMIT
636 mono_image_add_memberef_row (MonoDynamicImage
*assembly
, guint32 parent
, const char *name
, guint32 sig
)
638 MONO_REQ_GC_NEUTRAL_MODE
;
640 MonoDynamicTable
*table
;
642 guint32 token
, pclass
;
644 switch (parent
& MONO_TYPEDEFORREF_MASK
) {
645 case MONO_TYPEDEFORREF_TYPEREF
:
646 pclass
= MONO_MEMBERREF_PARENT_TYPEREF
;
648 case MONO_TYPEDEFORREF_TYPESPEC
:
649 pclass
= MONO_MEMBERREF_PARENT_TYPESPEC
;
651 case MONO_TYPEDEFORREF_TYPEDEF
:
652 pclass
= MONO_MEMBERREF_PARENT_TYPEDEF
;
655 g_warning ("unknown typeref or def token 0x%08x for %s", parent
, name
);
658 /* extract the index */
659 parent
>>= MONO_TYPEDEFORREF_BITS
;
661 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
663 if (assembly
->save
) {
664 alloc_table (table
, table
->rows
+ 1);
665 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
666 values
[MONO_MEMBERREF_CLASS
] = pclass
| (parent
<< MONO_MEMBERREF_PARENT_BITS
);
667 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
668 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
671 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
678 * Insert a memberef row into the metadata: the token that point to the memberref
679 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
680 * mono_image_get_fieldref_token()).
681 * The sig param is an index to an already built signature.
684 mono_image_get_memberref_token (MonoDynamicImage
*assembly
, MonoType
*type
, const char *name
, guint32 sig
)
686 MONO_REQ_GC_NEUTRAL_MODE
;
688 guint32 parent
= mono_image_typedef_or_ref (assembly
, type
);
689 return mono_image_add_memberef_row (assembly
, parent
, name
, sig
);
694 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
696 MONO_REQ_GC_NEUTRAL_MODE
;
699 MonoMethodSignature
*sig
;
701 create_typespec
= create_typespec
&& method
->is_generic
&& method
->klass
->image
!= &assembly
->image
;
703 if (create_typespec
) {
704 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1)));
709 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
710 if (token
&& !create_typespec
)
713 g_assert (!method
->is_inflated
);
716 * A methodref signature can't contain an unmanaged calling convention.
718 sig
= mono_metadata_signature_dup (mono_method_signature_internal (method
));
719 if ((sig
->call_convention
!= MONO_CALL_DEFAULT
) && (sig
->call_convention
!= MONO_CALL_VARARG
))
720 sig
->call_convention
= MONO_CALL_DEFAULT
;
721 token
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (method
->klass
),
722 method
->name
, mono_dynimage_encode_method_signature (assembly
, sig
));
724 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
727 if (create_typespec
) {
728 MonoDynamicTable
*table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
729 g_assert (mono_metadata_token_table (token
) == MONO_TABLE_MEMBERREF
);
730 token
= (mono_metadata_token_index (token
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
732 if (assembly
->save
) {
735 alloc_table (table
, table
->rows
+ 1);
736 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
737 values
[MONO_METHODSPEC_METHOD
] = token
;
738 values
[MONO_METHODSPEC_SIGNATURE
] = mono_dynimage_encode_generic_method_sig (assembly
, &mono_method_get_generic_container (method
)->context
);
741 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
743 /*methodspec and memberef tokens are diferent, */
744 g_hash_table_insert (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1), GUINT_TO_POINTER (token
));
751 mono_image_get_varargs_method_token (MonoDynamicImage
*assembly
, guint32 original
,
752 const gchar
*name
, guint32 sig
)
754 MonoDynamicTable
*table
;
758 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
760 if (assembly
->save
) {
761 alloc_table (table
, table
->rows
+ 1);
762 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
763 values
[MONO_MEMBERREF_CLASS
] = original
;
764 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
765 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
768 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
774 #else /* DISABLE_REFLECTION_EMIT */
777 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
779 g_assert_not_reached ();
785 is_field_on_inst (MonoClassField
*field
)
787 return mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->is_dynamic
;
791 is_field_on_gtd (MonoClassField
*field
)
793 return mono_class_is_gtd (field
->parent
);
796 #ifndef DISABLE_REFLECTION_EMIT
798 mono_image_get_fieldref_token (MonoDynamicImage
*assembly
, MonoClassField
*field
)
804 g_assert (field
->parent
);
806 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, field
));
810 if (mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->container_class
&& mono_class_get_generic_class (field
->parent
)->container_class
->fields
) {
811 int index
= field
- field
->parent
->fields
;
812 type
= mono_field_get_type_internal (&mono_class_get_generic_class (field
->parent
)->container_class
->fields
[index
]);
814 type
= mono_field_get_type_internal (field
);
816 token
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (field
->parent
),
817 mono_field_get_name (field
),
818 mono_dynimage_encode_fieldref_signature (assembly
, field
->parent
->image
, type
));
819 g_hash_table_insert (assembly
->handleref
, field
, GUINT_TO_POINTER(token
));
824 method_encode_methodspec (MonoDynamicImage
*assembly
, MonoMethod
*method
)
826 MonoDynamicTable
*table
;
828 guint32 token
, mtoken
= 0, sig
;
829 MonoMethodInflated
*imethod
;
830 MonoMethod
*declaring
;
832 table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
834 g_assert (method
->is_inflated
);
835 imethod
= (MonoMethodInflated
*) method
;
836 declaring
= imethod
->declaring
;
838 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature_internal (declaring
));
839 mtoken
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (method
->klass
), declaring
->name
, sig
);
841 if (!mono_method_signature_internal (declaring
)->generic_param_count
)
844 switch (mono_metadata_token_table (mtoken
)) {
845 case MONO_TABLE_MEMBERREF
:
846 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
848 case MONO_TABLE_METHOD
:
849 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODDEF
;
852 g_assert_not_reached ();
855 sig
= mono_dynimage_encode_generic_method_sig (assembly
, mono_method_get_context (method
));
857 if (assembly
->save
) {
858 alloc_table (table
, table
->rows
+ 1);
859 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
860 values
[MONO_METHODSPEC_METHOD
] = mtoken
;
861 values
[MONO_METHODSPEC_SIGNATURE
] = sig
;
864 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
871 mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
)
873 MonoMethodInflated
*imethod
;
876 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
880 g_assert (method
->is_inflated
);
881 imethod
= (MonoMethodInflated
*) method
;
883 if (mono_method_signature_internal (imethod
->declaring
)->generic_param_count
) {
884 token
= method_encode_methodspec (assembly
, method
);
886 guint32 sig
= mono_dynimage_encode_method_signature (
887 assembly
, mono_method_signature_internal (imethod
->declaring
));
888 token
= mono_image_get_memberref_token (
889 assembly
, m_class_get_byval_arg (method
->klass
), method
->name
, sig
);
892 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
897 mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
)
899 MonoMethodInflated
*imethod
= (MonoMethodInflated
*) m
;
902 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature_internal (imethod
->declaring
));
903 token
= mono_image_get_memberref_token (
904 assembly
, m_class_get_byval_arg (m
->klass
), m
->name
, sig
);
910 mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
)
913 MonoDynamicTable
*table
;
918 table
= &assembly
->tables
[MONO_TABLE_STANDALONESIG
];
919 idx
= table
->next_idx
++;
921 alloc_table (table
, table
->rows
);
922 values
= table
->values
+ idx
* MONO_STAND_ALONE_SIGNATURE_SIZE
;
924 values
[MONO_STAND_ALONE_SIGNATURE
] =
925 mono_dynimage_encode_reflection_sighelper (assembly
, helper
, error
);
926 return_val_if_nok (error
, 0);
932 reflection_cc_to_file (int call_conv
) {
933 switch (call_conv
& 0x3) {
935 case 1: return MONO_CALL_DEFAULT
;
936 case 2: return MONO_CALL_VARARG
;
938 g_assert_not_reached ();
942 #endif /* !DISABLE_REFLECTION_EMIT */
944 struct _ArrayMethod
{
946 MonoMethodSignature
*sig
;
952 mono_sre_array_method_free (ArrayMethod
*am
)
959 #ifndef DISABLE_REFLECTION_EMIT
961 mono_image_get_array_token (MonoDynamicImage
*assembly
, MonoReflectionArrayMethodHandle m
, MonoError
*error
)
963 MonoMethodSignature
*sig
= NULL
;
968 MonoArrayHandle parameters
= MONO_HANDLE_NEW_GET (MonoArray
, m
, parameters
);
969 guint32 nparams
= mono_array_handle_length (parameters
);
970 sig
= (MonoMethodSignature
*)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * nparams
);
972 sig
->sentinelpos
= -1;
973 sig
->call_convention
= reflection_cc_to_file (MONO_HANDLE_GETVAL (m
, call_conv
));
974 sig
->param_count
= nparams
;
975 MonoReflectionTypeHandle ret
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, ret
);
976 if (!MONO_HANDLE_IS_NULL (ret
)) {
977 sig
->ret
= mono_reflection_type_handle_mono_type (ret
, error
);
978 goto_if_nok (error
, fail
);
980 sig
->ret
= mono_get_void_type ();
982 MonoReflectionTypeHandle parent
;
983 parent
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, parent
);
985 mtype
= mono_reflection_type_handle_mono_type (parent
, error
);
986 goto_if_nok (error
, fail
);
988 for (int i
= 0; i
< nparams
; ++i
) {
989 sig
->params
[i
] = mono_type_array_get_and_resolve (parameters
, i
, error
);
990 goto_if_nok (error
, fail
);
993 MonoStringHandle mname
;
994 mname
= MONO_HANDLE_NEW_GET (MonoString
, m
, name
);
995 name
= mono_string_handle_to_utf8 (mname
, error
);
996 goto_if_nok (error
, fail
);
1000 for (GList
*tmp
= assembly
->array_methods
; tmp
; tmp
= tmp
->next
) {
1001 am
= (ArrayMethod
*)tmp
->data
;
1002 if (strcmp (name
, am
->name
) == 0 &&
1003 mono_metadata_type_equal (am
->parent
, mtype
) &&
1004 mono_metadata_signature_equal (am
->sig
, sig
)) {
1007 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
1011 am
= g_new0 (ArrayMethod
, 1);
1015 am
->token
= mono_image_get_memberref_token (assembly
, am
->parent
, name
,
1016 mono_dynimage_encode_method_signature (assembly
, sig
));
1017 assembly
->array_methods
= g_list_prepend (assembly
->array_methods
, am
);
1018 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
1028 #ifndef DISABLE_REFLECTION_EMIT
1031 * mono_image_insert_string:
1032 * @module: module builder object
1035 * Insert @str into the user string stream of @module.
1038 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module
, MonoStringHandle str
, MonoError
*error
)
1040 HANDLE_FUNCTION_ENTER ();
1046 MonoDynamicImage
*assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1048 if (!mono_image_module_basic_init (ref_module
, error
))
1051 assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1053 g_assert (assembly
!= NULL
);
1055 if (assembly
->save
) {
1056 int32_t length
= mono_string_length_internal (MONO_HANDLE_RAW (str
));
1057 mono_metadata_encode_value (1 | (length
* 2), b
, &b
);
1058 idx
= mono_image_add_stream_data (&assembly
->us
, buf
, b
-buf
);
1060 MonoGCHandle gchandle
= mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject
, str
), TRUE
);
1061 const char *p
= (const char*)mono_string_chars_internal (MONO_HANDLE_RAW (str
));
1062 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1064 char *swapped
= g_malloc (2 * length
);
1066 swap_with_size (swapped
, p
, 2, length
);
1067 mono_image_add_stream_data (&assembly
->us
, swapped
, length
* 2);
1071 mono_image_add_stream_data (&assembly
->us
, p
, length
* 2);
1073 mono_gchandle_free_internal (gchandle
);
1074 mono_image_add_stream_data (&assembly
->us
, "", 1);
1076 idx
= assembly
->us
.index
++;
1079 token
= MONO_TOKEN_STRING
| idx
;
1080 mono_dynamic_image_register_token (assembly
, token
, MONO_HANDLE_CAST (MonoObject
, str
), MONO_DYN_IMAGE_TOK_NEW
);
1083 HANDLE_FUNCTION_RETURN_VAL (token
);
1087 create_method_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1089 guint32 sig_token
, parent
;
1092 int nargs
= mono_array_handle_length (opt_param_types
);
1093 MonoMethodSignature
*old
= mono_method_signature_internal (method
);
1094 MonoMethodSignature
*sig
= mono_metadata_signature_alloc ( &assembly
->image
, old
->param_count
+ nargs
);
1096 sig
->hasthis
= old
->hasthis
;
1097 sig
->explicit_this
= old
->explicit_this
;
1098 sig
->call_convention
= old
->call_convention
;
1099 sig
->generic_param_count
= old
->generic_param_count
;
1100 sig
->param_count
= old
->param_count
+ nargs
;
1101 sig
->sentinelpos
= old
->param_count
;
1102 sig
->ret
= old
->ret
;
1104 for (int i
= 0; i
< old
->param_count
; i
++)
1105 sig
->params
[i
] = old
->params
[i
];
1107 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1108 for (int i
= 0; i
< nargs
; i
++) {
1109 MONO_HANDLE_ARRAY_GETREF (rt
, opt_param_types
, i
);
1110 sig
->params
[old
->param_count
+ i
] = mono_reflection_type_handle_mono_type (rt
, error
);
1111 goto_if_nok (error
, fail
);
1114 parent
= mono_image_typedef_or_ref (assembly
, m_class_get_byval_arg (method
->klass
));
1115 g_assert ((parent
& MONO_TYPEDEFORREF_MASK
) == MONO_MEMBERREF_PARENT_TYPEREF
);
1116 parent
>>= MONO_TYPEDEFORREF_BITS
;
1118 parent
<<= MONO_MEMBERREF_PARENT_BITS
;
1119 parent
|= MONO_MEMBERREF_PARENT_TYPEREF
;
1121 sig_token
= mono_dynimage_encode_method_signature (assembly
, sig
);
1123 token
= mono_image_get_varargs_method_token (assembly
, parent
, method
->name
, sig_token
);
1124 g_hash_table_insert (assembly
->vararg_aux_hash
, GUINT_TO_POINTER (token
), sig
);
1131 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1137 MonoClass
*klass
= mono_handle_class (obj
);
1138 if (strcmp (klass
->name
, "RuntimeMethodInfo") == 0 || strcmp (klass
->name
, "RuntimeConstructorInfo") == 0) {
1139 MonoReflectionMethodHandle ref_method
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1140 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
1141 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types
) && (mono_method_signature_internal (method
)->sentinelpos
>= 0));
1142 token
= create_method_token (assembly
, method
, opt_param_types
, error
);
1143 goto_if_nok (error
, fail
);
1144 } else if (strcmp (klass
->name
, "MethodBuilder") == 0) {
1145 g_assert_not_reached ();
1147 g_error ("requested method token for %s\n", klass
->name
);
1150 mono_dynamic_image_register_token (assembly
, token
, obj
, MONO_DYN_IMAGE_TOK_NEW
);
1153 g_assert (!is_ok (error
));
1158 * mono_image_create_token:
1159 * @assembly: a dynamic assembly
1161 * @register_token: Whenever to register the token in the assembly->tokens hash.
1163 * Get a token to insert in the IL code stream for the given MemberInfo.
1164 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1165 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1169 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
1170 gboolean create_open_instance
, gboolean register_token
,
1173 HANDLE_FUNCTION_ENTER ();
1178 MonoClass
*klass
= mono_handle_class (obj
);
1179 MonoObjectHandle register_obj
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1180 MONO_HANDLE_ASSIGN (register_obj
, obj
);
1182 /* Check for user defined reflection objects */
1183 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1184 if (klass
->image
!= mono_defaults
.corlib
|| (strcmp (klass
->name
, "TypeDelegator") == 0)) {
1185 mono_error_set_not_supported (error
, "User defined subclasses of System.Type are not yet supported");
1189 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1191 how_collide
= MONO_DYN_IMAGE_TOK_SAME_OK
;
1193 if (strcmp (klass
->name
, "RuntimeType") == 0) {
1194 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, obj
), error
);
1195 goto_if_nok (error
, leave
);
1196 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
1197 token
= mono_metadata_token_from_dor (
1198 mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, !mono_class_is_gtd (mc
) || create_open_instance
));
1199 /* If it's a RuntimeType now, we could have registered a
1200 * TypeBuilder for it before, so replacing is okay. */
1201 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1202 } else if (strcmp (klass
->name
, "RuntimeMethodInfo") == 0 ||
1203 strcmp (klass
->name
, "RuntimeConstructorInfo") == 0) {
1204 MonoReflectionMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1205 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
1206 if (method
->is_inflated
) {
1207 if (create_open_instance
) {
1208 guint32 methodspec_token
= mono_image_get_methodspec_token (assembly
, method
);
1209 MonoReflectionMethodHandle canonical_obj
=
1210 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1211 goto_if_nok (error
, leave
);
1212 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1213 token
= methodspec_token
;
1215 token
= mono_image_get_inflated_method_token (assembly
, method
);
1216 } else if ((method
->klass
->image
== &assembly
->image
) &&
1217 !mono_class_is_ginst (method
->klass
) &&
1218 !mono_class_is_gtd (method
->klass
)) {
1219 static guint32 method_table_idx
= 0xffffff;
1220 if (method
->klass
->wastypebuilder
) {
1221 /* we use the same token as the one that was assigned
1222 * to the Methodbuilder.
1223 * FIXME: do the equivalent for Fields.
1225 token
= method
->token
;
1226 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1229 * Each token should have a unique index, but the indexes are
1230 * assigned by managed code, so we don't know about them. An
1231 * easy solution is to count backwards...
1233 method_table_idx
--;
1234 token
= MONO_TOKEN_METHOD_DEF
| method_table_idx
;
1235 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1238 guint32 methodref_token
= mono_image_get_methodref_token (assembly
, method
, create_open_instance
);
1239 /* We need to register a 'canonical' object. The same
1240 * MonoMethod could have been reflected via different
1241 * classes so the MonoReflectionMethod:reftype could be
1242 * different, and the object lookup in
1243 * dynamic_image_register_token would assert assert. So
1244 * we pick the MonoReflectionMethod object that has the
1245 * reflected type as NULL (ie, take the declaring type
1247 MonoReflectionMethodHandle canonical_obj
=
1248 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1249 goto_if_nok (error
, leave
);
1250 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1251 token
= methodref_token
;
1253 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1254 } else if (strcmp (klass
->name
, "RuntimeFieldInfo") == 0) {
1255 MonoReflectionFieldHandle f
= MONO_HANDLE_CAST (MonoReflectionField
, obj
);
1256 MonoClassField
*field
= MONO_HANDLE_GETVAL (f
, field
);
1257 if ((field
->parent
->image
== &assembly
->image
) &&
1258 !is_field_on_gtd (field
) &&
1259 !is_field_on_inst (field
)) {
1260 static guint32 field_table_idx
= 0xffffff;
1262 token
= MONO_TOKEN_FIELD_DEF
| field_table_idx
;
1263 g_assert (!mono_class_is_gtd (field
->parent
));
1264 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1266 guint32 fieldref_token
= mono_image_get_fieldref_token (assembly
, field
);
1267 /* Same as methodref: get a canonical object to
1268 * register with the token. */
1269 MonoReflectionFieldHandle canonical_obj
=
1270 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj
), field
->parent
, field
, error
);
1271 goto_if_nok (error
, leave
);
1272 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1273 token
= fieldref_token
;
1275 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1276 } else if (strcmp (klass
->name
, "MonoArrayMethod") == 0) {
1277 MonoReflectionArrayMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionArrayMethod
, obj
);
1278 /* mono_image_get_array_token caches tokens by signature */
1279 guint32 array_token
= mono_image_get_array_token (assembly
, m
, error
);
1280 goto_if_nok (error
, leave
);
1281 token
= array_token
;
1282 /* ModuleBuilder:GetArrayMethod() always returns a fresh
1283 * MonoArrayMethod instance even given the same method name and
1284 * signature. But they're all interchangeable, so it's okay to
1287 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1288 } else if (strcmp (klass
->name
, "SignatureHelper") == 0) {
1289 MonoReflectionSigHelperHandle s
= MONO_HANDLE_CAST (MonoReflectionSigHelper
, obj
);
1290 /* always returns a fresh token */
1291 guint32 sig_token
= MONO_TOKEN_SIGNATURE
| mono_image_get_sighelper_token (assembly
, s
, error
);
1292 goto_if_nok (error
, leave
);
1294 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1296 g_error ("requested token for %s\n", klass
->name
);
1300 mono_dynamic_image_register_token (assembly
, token
, register_obj
, how_collide
);
1303 HANDLE_FUNCTION_RETURN_VAL (token
);
1309 #ifndef DISABLE_REFLECTION_EMIT
1312 assemblybuilderaccess_can_refonlyload (guint32 access
)
1314 return (access
& 0x4) != 0;
1318 assemblybuilderaccess_can_run (guint32 access
)
1320 return (access
& MonoAssemblyBuilderAccess_Run
) != 0;
1324 assemblybuilderaccess_can_save (guint32 access
)
1326 return (access
& MonoAssemblyBuilderAccess_Save
) != 0;
1331 * mono_reflection_dynimage_basic_init:
1332 * @assembly: an assembly builder object
1334 * Create the MonoImage that represents the assembly builder and setup some
1335 * of the helper hash table and the basic metadata streams.
1338 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
, MonoError
*error
)
1340 MonoDynamicAssembly
*assembly
;
1341 MonoDynamicImage
*image
;
1342 MonoDomain
*domain
= mono_object_domain (assemblyb
);
1343 MonoAssemblyLoadContext
*alc
= mono_domain_default_alc (domain
);
1345 if (assemblyb
->dynamic_assembly
)
1348 assembly
= assemblyb
->dynamic_assembly
= g_new0 (MonoDynamicAssembly
, 1);
1350 MONO_PROFILER_RAISE (assembly_loading
, (&assembly
->assembly
));
1352 assembly
->assembly
.ref_count
= 1;
1353 assembly
->assembly
.dynamic
= TRUE
;
1354 assembly
->assembly
.corlib_internal
= assemblyb
->corlib_internal
;
1355 assemblyb
->assembly
.assembly
= (MonoAssembly
*)assembly
;
1356 assembly
->assembly
.basedir
= mono_string_to_utf8_checked_internal (assemblyb
->dir
, error
);
1357 return_if_nok (error
);
1358 if (assemblyb
->culture
) {
1359 assembly
->assembly
.aname
.culture
= mono_string_to_utf8_checked_internal (assemblyb
->culture
, error
);
1360 return_if_nok (error
);
1362 assembly
->assembly
.aname
.culture
= g_strdup ("");
1364 if (assemblyb
->version
) {
1365 char *vstr
= mono_string_to_utf8_checked_internal (assemblyb
->version
, error
);
1366 if (mono_error_set_pending_exception (error
))
1368 char **version
= g_strsplit (vstr
, ".", 4);
1369 char **parts
= version
;
1370 assembly
->assembly
.aname
.major
= atoi (*parts
++);
1371 assembly
->assembly
.aname
.minor
= atoi (*parts
++);
1372 assembly
->assembly
.aname
.build
= *parts
!= NULL
? atoi (*parts
++) : 0;
1373 assembly
->assembly
.aname
.revision
= *parts
!= NULL
? atoi (*parts
) : 0;
1375 g_strfreev (version
);
1378 assembly
->assembly
.aname
.major
= 0;
1379 assembly
->assembly
.aname
.minor
= 0;
1380 assembly
->assembly
.aname
.build
= 0;
1381 assembly
->assembly
.aname
.revision
= 0;
1384 /* SRE assemblies are loaded into the individual loading context, ie,
1385 * they only fire AssemblyResolve events, they don't cause probing for
1386 * referenced assemblies to happen. */
1387 assembly
->assembly
.context
.kind
= assemblybuilderaccess_can_refonlyload (assemblyb
->access
) ? MONO_ASMCTX_REFONLY
: MONO_ASMCTX_INDIVIDUAL
;
1388 assembly
->run
= assemblybuilderaccess_can_run (assemblyb
->access
);
1389 assembly
->save
= assemblybuilderaccess_can_save (assemblyb
->access
);
1390 assembly
->domain
= domain
;
1392 char *assembly_name
= mono_string_to_utf8_checked_internal (assemblyb
->name
, error
);
1393 return_if_nok (error
);
1394 image
= mono_dynamic_image_create (assembly
, assembly_name
, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1395 image
->initial_image
= TRUE
;
1396 assembly
->assembly
.aname
.name
= image
->image
.name
;
1397 assembly
->assembly
.image
= &image
->image
;
1398 if (assemblyb
->pktoken
&& assemblyb
->pktoken
->max_length
) {
1399 /* -1 to correct for the trailing NULL byte */
1400 if (assemblyb
->pktoken
->max_length
!= MONO_PUBLIC_KEY_TOKEN_LENGTH
- 1) {
1401 g_error ("Public key token length invalid for assembly %s: %i", assembly
->assembly
.aname
.name
, assemblyb
->pktoken
->max_length
);
1403 memcpy (&assembly
->assembly
.aname
.public_key_token
, mono_array_addr_internal (assemblyb
->pktoken
, guint8
, 0), assemblyb
->pktoken
->max_length
);
1406 mono_domain_assemblies_lock (domain
);
1407 domain
->domain_assemblies
= g_slist_append (domain
->domain_assemblies
, assembly
);
1408 #ifdef ENABLE_NETCORE
1409 // TODO: potentially relax the locking here?
1410 mono_alc_assemblies_lock (alc
);
1411 alc
->loaded_assemblies
= g_slist_append (alc
->loaded_assemblies
, assembly
);
1412 mono_alc_assemblies_unlock (alc
);
1414 mono_domain_assemblies_unlock (domain
);
1416 register_assembly (mono_object_domain (assemblyb
), &assemblyb
->assembly
, &assembly
->assembly
);
1418 MONO_PROFILER_RAISE (assembly_loaded
, (&assembly
->assembly
));
1420 mono_assembly_invoke_load_hook_internal (alc
, (MonoAssembly
*)assembly
);
1423 #endif /* !DISABLE_REFLECTION_EMIT */
1425 #ifndef DISABLE_REFLECTION_EMIT
1427 register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
)
1429 return CACHE_OBJECT (MonoReflectionAssembly
*, assembly
, &res
->object
, NULL
);
1432 static MonoReflectionModuleBuilderHandle
1433 register_module (MonoDomain
*domain
, MonoReflectionModuleBuilderHandle res
, MonoDynamicImage
*module
)
1435 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilder
, module
, MONO_HANDLE_CAST (MonoObject
, res
), NULL
);
1439 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1442 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (moduleb
);
1443 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
1444 MonoReflectionAssemblyBuilderHandle ab
= MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder
, NULL
);
1445 MONO_HANDLE_GET (ab
, moduleb
, assemblyb
);
1448 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1449 * we don't know which module it belongs to, since that is only
1450 * determined at assembly save time.
1452 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1453 MonoStringHandle abname
= MONO_HANDLE_NEW_GET (MonoString
, ab
, name
);
1454 char *name
= mono_string_handle_to_utf8 (abname
, error
);
1455 return_val_if_nok (error
, FALSE
);
1456 MonoStringHandle modfqname
= MONO_HANDLE_NEW_GET (MonoString
, MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), fqname
);
1457 char *fqname
= mono_string_handle_to_utf8 (modfqname
, error
);
1458 if (!is_ok (error
)) {
1462 MonoDynamicAssembly
*dynamic_assembly
= MONO_HANDLE_GETVAL (ab
, dynamic_assembly
);
1463 image
= mono_dynamic_image_create (dynamic_assembly
, name
, fqname
);
1465 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), image
, MonoImage
*, &image
->image
);
1466 MONO_HANDLE_SETVAL (moduleb
, dynamic_image
, MonoDynamicImage
*, image
);
1467 register_module (domain
, moduleb
, image
);
1469 /* register the module with the assembly */
1470 MonoImage
*ass
= dynamic_assembly
->assembly
.image
;
1471 int module_count
= ass
->module_count
;
1472 MonoImage
**new_modules
= g_new0 (MonoImage
*, module_count
+ 1);
1475 memcpy (new_modules
, ass
->modules
, module_count
* sizeof (MonoImage
*));
1476 new_modules
[module_count
] = &image
->image
;
1477 mono_image_addref (&image
->image
);
1479 g_free (ass
->modules
);
1480 ass
->modules
= new_modules
;
1481 ass
->module_count
++;
1487 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1490 return image_module_basic_init (moduleb
, error
);
1496 is_corlib_type (MonoClass
*klass
)
1498 return klass
->image
== mono_defaults
.corlib
;
1501 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1502 static MonoClass *cached_class; \
1504 return cached_class == _class; \
1505 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1506 cached_class = _class; \
1514 mono_type_array_get_and_resolve (MonoArrayHandle array
, int idx
, MonoError
*error
)
1516 HANDLE_FUNCTION_ENTER();
1518 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1519 MONO_HANDLE_ARRAY_GETREF (t
, array
, idx
);
1520 MonoType
*result
= mono_reflection_type_handle_mono_type (t
, error
);
1521 HANDLE_FUNCTION_RETURN_VAL (result
);
1525 add_custom_modifiers_to_type (MonoType
*without_mods
, MonoArrayHandle req_array
, MonoArrayHandle opt_array
, MonoImage
*image
, MonoError
*error
)
1527 HANDLE_FUNCTION_ENTER();
1530 int num_req_mods
= 0;
1531 if (!MONO_HANDLE_IS_NULL (req_array
))
1532 num_req_mods
= mono_array_handle_length (req_array
);
1534 int num_opt_mods
= 0;
1535 if (!MONO_HANDLE_IS_NULL (opt_array
))
1536 num_opt_mods
= mono_array_handle_length (opt_array
);
1538 const int total_mods
= num_req_mods
+ num_opt_mods
;
1539 if (total_mods
== 0)
1540 return without_mods
;
1542 MonoTypeWithModifiers
*result
;
1543 result
= mono_image_g_malloc0 (image
, mono_sizeof_type_with_mods (total_mods
, FALSE
));
1544 memcpy (result
, without_mods
, MONO_SIZEOF_TYPE
);
1545 result
->unmodified
.has_cmods
= 1;
1546 MonoCustomModContainer
*cmods
= mono_type_get_cmods ((MonoType
*)result
);
1548 cmods
->count
= total_mods
;
1549 cmods
->image
= image
;
1551 g_assert (image_is_dynamic (image
));
1552 MonoDynamicImage
*allocator
= (MonoDynamicImage
*) image
;
1554 g_assert (total_mods
> 0);
1555 /* store cmods in reverse order from how the API supplies them.
1556 (Assemblies store modifiers in reverse order of IL syntax - and SRE
1557 follows the same order as IL syntax). */
1558 int modifier_index
= total_mods
- 1;
1560 MonoObjectHandle mod_handle
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1561 for (int i
=0; i
< num_req_mods
; i
++) {
1562 cmods
->modifiers
[modifier_index
].required
= TRUE
;
1563 MONO_HANDLE_ARRAY_GETREF (mod_handle
, req_array
, i
);
1564 cmods
->modifiers
[modifier_index
].token
= mono_image_create_token (allocator
, mod_handle
, FALSE
, TRUE
, error
);
1568 for (int i
=0; i
< num_opt_mods
; i
++) {
1569 cmods
->modifiers
[modifier_index
].required
= FALSE
;
1570 MONO_HANDLE_ARRAY_GETREF (mod_handle
, opt_array
, i
);
1571 cmods
->modifiers
[modifier_index
].token
= mono_image_create_token (allocator
, mod_handle
, FALSE
, TRUE
, error
);
1575 g_assert (modifier_index
== -1);
1577 HANDLE_FUNCTION_RETURN_VAL ((MonoType
*) result
);
1582 mono_type_array_get_and_resolve_with_modifiers (MonoArrayHandle types
, MonoArrayHandle required_modifiers
, MonoArrayHandle optional_modifiers
, int idx
, MonoImage
*image
, MonoError
*error
)
1584 HANDLE_FUNCTION_ENTER();
1586 MonoReflectionTypeHandle type
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1587 MonoArrayHandle req_mods_handle
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1588 MonoArrayHandle opt_mods_handle
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1590 if (!MONO_HANDLE_IS_NULL (required_modifiers
))
1591 MONO_HANDLE_ARRAY_GETREF (req_mods_handle
, required_modifiers
, idx
);
1593 if (!MONO_HANDLE_IS_NULL (optional_modifiers
))
1594 MONO_HANDLE_ARRAY_GETREF (opt_mods_handle
, optional_modifiers
, idx
);
1596 MONO_HANDLE_ARRAY_GETREF (type
, types
, idx
);
1598 MonoType
*result
= mono_reflection_type_handle_mono_type (type
, error
);
1599 result
= (MonoType
*) add_custom_modifiers_to_type (result
, req_mods_handle
, opt_mods_handle
, image
, error
);
1601 HANDLE_FUNCTION_RETURN_VAL (result
);
1605 #ifndef DISABLE_REFLECTION_EMIT
1607 is_sre_array (MonoClass
*klass
)
1609 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ArrayType");
1613 is_sre_byref (MonoClass
*klass
)
1615 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ByRefType");
1619 is_sre_pointer (MonoClass
*klass
)
1621 check_corlib_type_cached (klass
, "System.Reflection.Emit", "PointerType");
1625 is_sre_generic_instance (MonoClass
*klass
)
1627 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilderInstantiation");
1631 is_sre_type_builder (MonoClass
*klass
)
1633 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilder");
1637 is_sre_method_builder (MonoClass
*klass
)
1639 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodBuilder");
1643 mono_is_sre_ctor_builder (MonoClass
*klass
)
1645 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorBuilder");
1649 is_sre_field_builder (MonoClass
*klass
)
1651 check_corlib_type_cached (klass
, "System.Reflection.Emit", "FieldBuilder");
1655 is_sre_gparam_builder (MonoClass
*klass
)
1657 check_corlib_type_cached (klass
, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1661 is_sre_enum_builder (MonoClass
*klass
)
1663 check_corlib_type_cached (klass
, "System.Reflection.Emit", "EnumBuilder");
1667 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1669 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1673 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1675 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1678 static MonoReflectionTypeHandle
1679 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
)
1681 HANDLE_FUNCTION_ENTER ();
1685 MONO_STATIC_POINTER_INIT (MonoMethod
, method_get_underlying_system_type
)
1687 method_get_underlying_system_type
= mono_class_get_method_from_name_checked (mono_defaults
.systemtype_class
, "get_UnderlyingSystemType", 0, 0, error
);
1688 mono_error_assert_ok (error
);
1690 MONO_STATIC_POINTER_INIT_END (MonoMethod
, method_get_underlying_system_type
)
1692 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1694 MonoMethod
*usertype_method
= mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject
, t
), method_get_underlying_system_type
, error
);
1695 goto_if_nok (error
, leave
);
1697 MONO_HANDLE_ASSIGN (rt
, MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW (MonoObject
, mono_runtime_invoke_checked (usertype_method
, MONO_HANDLE_RAW (t
), NULL
, error
))));
1700 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType
, rt
);
1704 mono_reflection_type_get_handle (MonoReflectionType
* ref_raw
, MonoError
*error
)
1706 HANDLE_FUNCTION_ENTER ();
1708 MONO_HANDLE_DCL (MonoReflectionType
, ref
);
1709 MonoType
* const result
= mono_reflection_type_handle_mono_type (ref
, error
);
1710 HANDLE_FUNCTION_RETURN_VAL (result
);
1714 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass
, MonoError
*error
)
1716 HANDLE_FUNCTION_ENTER ();
1717 MonoType
*result
= NULL
;
1718 MonoType
**types
= NULL
;
1720 MonoArrayHandle typeargs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_gclass
, type_arguments
);
1721 int count
= mono_array_handle_length (typeargs
);
1722 types
= g_new0 (MonoType
*, count
);
1723 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1724 for (int i
= 0; i
< count
; ++i
) {
1725 MONO_HANDLE_ARRAY_GETREF (t
, typeargs
, i
);
1726 types
[i
] = mono_reflection_type_handle_mono_type (t
, error
);
1727 if (!types
[i
] || !is_ok (error
)) {
1731 /* Need to resolve the generic_type in order for it to create its generic context. */
1732 MonoReflectionTypeHandle ref_gtd
;
1733 ref_gtd
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_gclass
, generic_type
);
1735 gtd
= mono_reflection_type_handle_mono_type (ref_gtd
, error
);
1736 goto_if_nok (error
, leave
);
1737 MonoClass
*gtd_klass
;
1738 gtd_klass
= mono_class_from_mono_type_internal (gtd
);
1739 if (is_sre_type_builder (mono_handle_class (ref_gtd
))) {
1740 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_gtd
), error
);
1741 goto_if_nok (error
, leave
);
1743 g_assert (count
== 0 || mono_class_is_gtd (gtd_klass
));
1744 result
= mono_reflection_bind_generic_parameters (ref_gtd
, count
, types
, error
);
1745 goto_if_nok (error
, leave
);
1747 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gclass
), type
, MonoType
*, result
);
1750 HANDLE_FUNCTION_RETURN_VAL (result
);
1754 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam
, MonoError
*error
)
1756 HANDLE_FUNCTION_ENTER ();
1758 MonoType
*result
= NULL
;
1761 MonoReflectionTypeBuilderHandle ref_tbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_gparam
, tbuilder
);
1762 MonoReflectionModuleBuilderHandle ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tbuilder
, module
);
1763 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1764 MonoImage
*image
= &dynamic_image
->image
;
1766 MonoGenericParamFull
*param
= mono_image_new0 (image
, MonoGenericParamFull
, 1);
1768 MonoStringHandle ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_gparam
, name
);
1769 param
->info
.name
= mono_string_to_utf8_image (image
, ref_name
, error
);
1770 mono_error_assert_ok (error
);
1771 param
->num
= MONO_HANDLE_GETVAL (ref_gparam
, index
);
1773 MonoReflectionMethodBuilderHandle ref_mbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder
, ref_gparam
, mbuilder
);
1774 if (!MONO_HANDLE_IS_NULL (ref_mbuilder
)) {
1775 MonoGenericContainer
*generic_container
= MONO_HANDLE_GETVAL (ref_mbuilder
, generic_container
);
1776 if (!generic_container
) {
1777 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (image
, sizeof (MonoGenericContainer
));
1778 generic_container
->is_method
= TRUE
;
1780 * Cannot set owner.method, since the MonoMethod is not created yet.
1781 * Set the image field instead, so type_in_image () works.
1783 generic_container
->is_anonymous
= TRUE
;
1784 generic_container
->owner
.image
= image
;
1785 MONO_HANDLE_SETVAL (ref_mbuilder
, generic_container
, MonoGenericContainer
*, generic_container
);
1787 param
->owner
= generic_container
;
1789 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_tbuilder
), error
);
1790 goto_if_nok (error
, leave
);
1792 owner
= mono_class_from_mono_type_internal (type
);
1793 g_assert (mono_class_is_gtd (owner
));
1794 param
->owner
= mono_class_get_generic_container (owner
);
1798 pklass
= mono_class_create_generic_parameter ((MonoGenericParam
*) param
);
1800 result
= m_class_get_byval_arg (pklass
);
1802 mono_class_set_ref_info (pklass
, MONO_HANDLE_CAST (MonoObject
, ref_gparam
));
1803 mono_image_append_class_to_reflection_info_set (pklass
);
1805 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), type
, MonoType
*, result
);
1808 HANDLE_FUNCTION_RETURN_VAL (result
);
1812 mono_type_array_get_and_resolve_raw (MonoArray
* array_raw
, int idx
, MonoError
*error
)
1814 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1816 MONO_HANDLE_DCL (MonoArray
, array
);
1817 MonoType
* const result
= mono_type_array_get_and_resolve (array
, idx
, error
);
1818 HANDLE_FUNCTION_RETURN_VAL (result
);
1822 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
1824 HANDLE_FUNCTION_ENTER ();
1827 MonoType
* result
= NULL
;
1829 g_assert (!MONO_HANDLE_IS_NULL (ref
));
1830 if (MONO_HANDLE_IS_NULL (ref
))
1833 t
= MONO_HANDLE_GETVAL (ref
, type
);
1839 if (mono_reflection_is_usertype (ref
)) {
1840 MONO_HANDLE_ASSIGN (ref
, mono_reflection_type_get_underlying_system_type (ref
, error
));
1841 if (!is_ok (error
) || MONO_HANDLE_IS_NULL (ref
) || mono_reflection_is_usertype (ref
))
1843 t
= MONO_HANDLE_GETVAL (ref
, type
);
1851 klass
= mono_handle_class (ref
);
1853 if (is_sre_array (klass
)) {
1854 MonoReflectionArrayTypeHandle sre_array
= MONO_HANDLE_CAST (MonoReflectionArrayType
, ref
);
1855 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_array
, element_type
);
1856 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1857 goto_if_nok (error
, leave
);
1859 gint32 rank
= MONO_HANDLE_GETVAL (sre_array
, rank
);
1860 MonoClass
*eclass
= mono_class_from_mono_type_internal (base
);
1861 result
= mono_image_new0 (eclass
->image
, MonoType
, 1);
1863 result
->type
= MONO_TYPE_SZARRAY
;
1864 result
->data
.klass
= eclass
;
1866 MonoArrayType
*at
= (MonoArrayType
*)mono_image_alloc0 (eclass
->image
, sizeof (MonoArrayType
));
1867 result
->type
= MONO_TYPE_ARRAY
;
1868 result
->data
.array
= at
;
1869 at
->eklass
= eclass
;
1872 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1873 } else if (is_sre_byref (klass
)) {
1874 MonoReflectionDerivedTypeHandle sre_byref
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1875 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_byref
, element_type
);
1876 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1877 goto_if_nok (error
, leave
);
1879 result
= &mono_class_from_mono_type_internal (base
)->this_arg
;
1880 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1881 } else if (is_sre_pointer (klass
)) {
1882 MonoReflectionDerivedTypeHandle sre_pointer
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1883 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_pointer
, element_type
);
1884 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1885 goto_if_nok (error
, leave
);
1887 result
= m_class_get_byval_arg (mono_class_create_ptr (base
));
1888 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1889 } else if (is_sre_generic_instance (klass
)) {
1890 result
= reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass
, ref
), error
);
1891 } else if (is_sre_gparam_builder (klass
)) {
1892 result
= reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam
, ref
), error
);
1893 } else if (is_sre_enum_builder (klass
)) {
1894 MonoReflectionEnumBuilderHandle ref_ebuilder
= MONO_HANDLE_CAST (MonoReflectionEnumBuilder
, ref
);
1896 MonoReflectionTypeHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_ebuilder
, tb
));
1897 result
= mono_reflection_type_handle_mono_type (ref_tb
, error
);
1898 } else if (is_sre_type_builder (klass
)) {
1899 MonoReflectionTypeBuilderHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref
);
1901 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1902 reflection_setup_internal_class (ref_tb
, error
);
1903 mono_error_assert_ok (error
);
1904 result
= MONO_HANDLE_GETVAL (ref
, type
);
1906 g_error ("Cannot handle corlib user type %s", mono_type_full_name (m_class_get_byval_arg (mono_handle_class (ref
))));
1909 HANDLE_FUNCTION_RETURN_VAL (result
);
1913 * LOCKING: Assumes the loader lock is held.
1915 static MonoMethodSignature
*
1916 parameters_to_signature (MonoImage
*image
, MonoArrayHandle parameters
, MonoArrayHandle required_modifiers
, MonoArrayHandle optional_modifiers
, MonoError
*error
) {
1917 MonoMethodSignature
*sig
;
1922 count
= MONO_HANDLE_IS_NULL (parameters
) ? 0 : mono_array_handle_length (parameters
);
1924 sig
= (MonoMethodSignature
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * count
);
1925 sig
->param_count
= count
;
1926 sig
->sentinelpos
= -1; /* FIXME */
1927 for (i
= 0; i
< count
; ++i
) {
1928 sig
->params
[i
] = mono_type_array_get_and_resolve_with_modifiers (parameters
, required_modifiers
, optional_modifiers
, i
, image
, error
);
1929 if (!is_ok (error
)) {
1930 image_g_free (image
, sig
);
1938 * LOCKING: Assumes the loader lock is held.
1940 static MonoMethodSignature
*
1941 ctor_builder_to_signature (MonoImage
*image
, MonoReflectionCtorBuilderHandle ctor
, MonoError
*error
) {
1942 MonoMethodSignature
*sig
;
1945 MonoArrayHandle params
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, parameters
);
1946 MonoArrayHandle required_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, param_modreq
);
1947 MonoArrayHandle optional_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, param_modopt
);
1949 sig
= parameters_to_signature (image
, params
, required_modifiers
, optional_modifiers
, error
);
1950 return_val_if_nok (error
, NULL
);
1951 sig
->hasthis
= MONO_HANDLE_GETVAL (ctor
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1952 sig
->ret
= mono_get_void_type ();
1956 static MonoMethodSignature
*
1957 ctor_builder_to_signature_raw (MonoImage
*image
, MonoReflectionCtorBuilder
* ctor_raw
, MonoError
*error
) {
1958 HANDLE_FUNCTION_ENTER();
1959 MONO_HANDLE_DCL (MonoReflectionCtorBuilder
, ctor
);
1960 MonoMethodSignature
* const sig
= ctor_builder_to_signature (image
, ctor
, error
);
1961 HANDLE_FUNCTION_RETURN_VAL (sig
);
1964 * LOCKING: Assumes the loader lock is held.
1966 static MonoMethodSignature
*
1967 method_builder_to_signature (MonoImage
*image
, MonoReflectionMethodBuilderHandle method
, MonoError
*error
)
1969 MonoMethodSignature
*sig
;
1972 MonoArrayHandle params
= MONO_HANDLE_NEW_GET(MonoArray
, method
, parameters
);
1973 MonoArrayHandle required_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, method
, param_modreq
);
1974 MonoArrayHandle optional_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, method
, param_modopt
);
1975 MonoArrayHandle ret_req_modifiers
= MONO_HANDLE_NEW_GET (MonoArray
, method
, return_modreq
);
1976 MonoArrayHandle ret_opt_modifiers
= MONO_HANDLE_NEW_GET (MonoArray
, method
, return_modopt
);
1978 sig
= parameters_to_signature (image
, params
, required_modifiers
, optional_modifiers
, error
);
1979 return_val_if_nok (error
, NULL
);
1980 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1981 MonoReflectionTypeHandle rtype
;
1982 rtype
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoObject
, method
, rtype
));
1983 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1984 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1985 sig
->ret
= add_custom_modifiers_to_type (sig
->ret
, ret_req_modifiers
, ret_opt_modifiers
, image
, error
);
1986 if (!is_ok (error
)) {
1987 image_g_free (image
, sig
);
1991 sig
->ret
= mono_get_void_type ();
1993 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, method
, generic_params
);
1994 sig
->generic_param_count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
1998 static MonoMethodSignature
*
1999 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method
, MonoError
*error
)
2001 HANDLE_FUNCTION_ENTER ();
2002 MonoMethodSignature
*sig
= NULL
;
2006 sig
= parameters_to_signature (NULL
, MONO_HANDLE_NEW_GET (MonoArray
, method
, parameters
),
2007 MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
), MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
), error
);
2008 goto_if_nok (error
, leave
);
2009 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
2010 MonoReflectionTypeHandle rtype
;
2011 rtype
= MONO_HANDLE_NEW_GET (MonoReflectionType
, method
, rtype
);
2012 if (!MONO_HANDLE_IS_NULL (rtype
)) {
2013 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
2014 if (!is_ok (error
)) {
2020 sig
->ret
= mono_get_void_type ();
2022 sig
->generic_param_count
= 0;
2024 HANDLE_FUNCTION_RETURN_VAL (sig
);
2028 get_prop_name_and_type (MonoObject
*prop
, char **name
, MonoType
**type
, MonoError
*error
)
2031 MonoClass
*klass
= mono_object_class (prop
);
2032 if (strcmp (klass
->name
, "PropertyBuilder") == 0) {
2033 MonoReflectionPropertyBuilder
*pb
= (MonoReflectionPropertyBuilder
*)prop
;
2034 *name
= mono_string_to_utf8_checked_internal (pb
->name
, error
);
2035 return_if_nok (error
);
2036 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)pb
->type
, error
);
2038 MonoReflectionProperty
*p
= (MonoReflectionProperty
*)prop
;
2039 *name
= g_strdup (p
->property
->name
);
2040 if (p
->property
->get
)
2041 *type
= mono_method_signature_internal (p
->property
->get
)->ret
;
2043 *type
= mono_method_signature_internal (p
->property
->set
)->params
[mono_method_signature_internal (p
->property
->set
)->param_count
- 1];
2048 get_field_name_and_type (MonoObject
*field
, char **name
, MonoType
**type
, MonoError
*error
)
2051 MonoClass
*klass
= mono_object_class (field
);
2052 if (strcmp (klass
->name
, "FieldBuilder") == 0) {
2053 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)field
;
2054 *name
= mono_string_to_utf8_checked_internal (fb
->name
, error
);
2055 return_if_nok (error
);
2056 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
2058 MonoReflectionField
*f
= (MonoReflectionField
*)field
;
2059 *name
= g_strdup (mono_field_get_name (f
->field
));
2060 *type
= f
->field
->type
;
2064 #else /* DISABLE_REFLECTION_EMIT */
2067 is_sre_type_builder (MonoClass
*klass
)
2073 is_sre_generic_instance (MonoClass
*klass
)
2079 mono_is_sre_ctor_builder (MonoClass
*klass
)
2085 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
2091 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
2096 #endif /* !DISABLE_REFLECTION_EMIT */
2099 mono_is_sr_mono_property (MonoClass
*klass
)
2101 check_corlib_type_cached (klass
, "System.Reflection", "RuntimePropertyInfo");
2105 is_sr_mono_method (MonoClass
*klass
)
2107 check_corlib_type_cached (klass
, "System.Reflection", "RuntimeMethodInfo");
2111 mono_is_sr_mono_cmethod (MonoClass
*klass
)
2113 check_corlib_type_cached (klass
, "System.Reflection", "RuntimeConstructorInfo");
2117 mono_class_is_reflection_method_or_constructor (MonoClass
*klass
)
2119 return is_sr_mono_method (klass
) || mono_is_sr_mono_cmethod (klass
);
2123 mono_is_sre_type_builder (MonoClass
*klass
)
2125 return is_sre_type_builder (klass
);
2129 mono_is_sre_generic_instance (MonoClass
*klass
)
2131 return is_sre_generic_instance (klass
);
2137 * encode_cattr_value:
2138 * Encode a value in a custom attribute stream of bytes.
2139 * The value to encode is either supplied as an object in argument val
2140 * (valuetypes are boxed), or as a pointer to the data in the
2142 * @type represents the type of the value
2143 * @buffer is the start of the buffer
2144 * @p the current position in the buffer
2145 * @buflen contains the size of the buffer and is used to return the new buffer size
2146 * if this needs to be realloced.
2147 * @retbuffer and @retp return the start and the position of the buffer
2148 * @error set on error.
2151 encode_cattr_value (MonoAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, MonoObject
*arg
, gconstpointer void_argval
, MonoError
*error
)
2153 const char *argval
= (const char*)void_argval
;
2154 MonoTypeEnum simple_type
;
2157 if ((p
-buffer
) + 10 >= *buflen
) {
2160 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2161 p
= newbuf
+ (p
-buffer
);
2165 argval
= (const char*)mono_object_get_data (arg
);
2166 simple_type
= type
->type
;
2168 switch (simple_type
) {
2169 case MONO_TYPE_BOOLEAN
:
2174 case MONO_TYPE_CHAR
:
2177 swap_with_size (p
, argval
, 2, 1);
2183 swap_with_size (p
, argval
, 4, 1);
2187 swap_with_size (p
, argval
, 8, 1);
2192 swap_with_size (p
, argval
, 8, 1);
2195 case MONO_TYPE_VALUETYPE
:
2196 if (type
->data
.klass
->enumtype
) {
2197 simple_type
= mono_class_enum_basetype_internal (type
->data
.klass
)->type
;
2200 g_warning ("generic valuetype %s not handled in custom attr value decoding", type
->data
.klass
->name
);
2203 case MONO_TYPE_STRING
: {
2207 MONO_DISABLE_WARNING(4309) // truncation of constant
2209 MONO_RESTORE_WARNING
2212 str
= mono_string_to_utf8_checked_internal ((MonoString
*)arg
, error
);
2213 return_if_nok (error
);
2214 slen
= strlen (str
);
2215 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2219 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2220 p
= newbuf
+ (p
-buffer
);
2223 mono_metadata_encode_value (slen
, p
, &p
);
2224 memcpy (p
, str
, slen
);
2229 case MONO_TYPE_CLASS
: {
2234 MONO_DISABLE_WARNING(4309) // truncation of constant
2236 MONO_RESTORE_WARNING
2240 arg_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)arg
, error
);
2241 return_if_nok (error
);
2243 str
= type_get_qualified_name (arg_type
, NULL
);
2244 slen
= strlen (str
);
2245 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2249 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2250 p
= newbuf
+ (p
-buffer
);
2253 mono_metadata_encode_value (slen
, p
, &p
);
2254 memcpy (p
, str
, slen
);
2259 case MONO_TYPE_SZARRAY
: {
2261 MonoClass
*eclass
, *arg_eclass
;
2264 MONO_DISABLE_WARNING(4309) // truncation of constant
2265 *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff;
2266 MONO_RESTORE_WARNING
2269 len
= mono_array_length_internal ((MonoArray
*)arg
);
2271 *p
++ = (len
>> 8) & 0xff;
2272 *p
++ = (len
>> 16) & 0xff;
2273 *p
++ = (len
>> 24) & 0xff;
2275 *retbuffer
= buffer
;
2276 eclass
= type
->data
.klass
;
2277 arg_eclass
= mono_object_class (arg
)->element_class
;
2280 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2281 eclass
= mono_defaults
.object_class
;
2283 if (eclass
== mono_defaults
.object_class
&& arg_eclass
->valuetype
) {
2284 char *elptr
= mono_array_addr_internal ((MonoArray
*)arg
, char, 0);
2285 int elsize
= mono_class_array_element_size (arg_eclass
);
2286 for (i
= 0; i
< len
; ++i
) {
2287 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (arg_eclass
), NULL
, elptr
, error
);
2288 return_if_nok (error
);
2291 } else if (eclass
->valuetype
&& arg_eclass
->valuetype
) {
2292 char *elptr
= mono_array_addr_internal ((MonoArray
*)arg
, char, 0);
2293 int elsize
= mono_class_array_element_size (eclass
);
2294 for (i
= 0; i
< len
; ++i
) {
2295 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (eclass
), NULL
, elptr
, error
);
2296 return_if_nok (error
);
2300 for (i
= 0; i
< len
; ++i
) {
2301 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (eclass
), mono_array_get_internal ((MonoArray
*)arg
, MonoObject
*, i
), NULL
, error
);
2302 return_if_nok (error
);
2307 case MONO_TYPE_OBJECT
: {
2313 * The parameter type is 'object' but the type of the actual
2314 * argument is not. So we have to add type information to the blob
2315 * too. This is completely undocumented in the spec.
2319 *p
++ = MONO_TYPE_STRING
; // It's same hack as MS uses
2320 MONO_DISABLE_WARNING(4309) // truncation of constant
2322 MONO_RESTORE_WARNING
2326 klass
= mono_object_class (arg
);
2328 if (mono_object_isinst_checked (arg
, mono_defaults
.systemtype_class
, error
)) {
2332 return_if_nok (error
);
2335 MonoType
*klass_byval_arg
= m_class_get_byval_arg (klass
);
2336 if (klass
->enumtype
) {
2338 } else if (klass
== mono_defaults
.string_class
) {
2339 simple_type
= MONO_TYPE_STRING
;
2342 } else if (klass
->rank
== 1) {
2344 if (m_class_get_byval_arg (m_class_get_element_class (klass
))->type
== MONO_TYPE_OBJECT
)
2345 /* See Partition II, Appendix B3 */
2348 *p
++ = m_class_get_byval_arg (m_class_get_element_class (klass
))->type
;
2349 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, klass_byval_arg
, arg
, NULL
, error
);
2350 return_if_nok (error
);
2352 } else if (klass_byval_arg
->type
>= MONO_TYPE_BOOLEAN
&& klass_byval_arg
->type
<= MONO_TYPE_R8
) {
2353 *p
++ = simple_type
= klass_byval_arg
->type
;
2356 mono_error_set_not_supported (error
, "unhandled type in custom attr");
2359 str
= type_get_qualified_name (m_class_get_byval_arg (klass
), NULL
);
2360 slen
= strlen (str
);
2361 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2365 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2366 p
= newbuf
+ (p
-buffer
);
2369 mono_metadata_encode_value (slen
, p
, &p
);
2370 memcpy (p
, str
, slen
);
2373 simple_type
= mono_class_enum_basetype_internal (klass
)->type
;
2377 mono_error_set_not_supported (error
, "type 0x%02x not yet supported in custom attr encoder", simple_type
);
2380 *retbuffer
= buffer
;
2384 encode_field_or_prop_type (MonoType
*type
, char *p
, char **retp
)
2386 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2387 char *str
= type_get_qualified_name (type
, NULL
);
2388 int slen
= strlen (str
);
2392 * This seems to be optional...
2395 mono_metadata_encode_value (slen
, p
, &p
);
2396 memcpy (p
, str
, slen
);
2399 } else if (type
->type
== MONO_TYPE_OBJECT
) {
2401 } else if (type
->type
== MONO_TYPE_CLASS
) {
2402 /* it should be a type: encode_cattr_value () has the check */
2405 mono_metadata_encode_value (type
->type
, p
, &p
);
2406 if (type
->type
== MONO_TYPE_SZARRAY
)
2407 /* See the examples in Partition VI, Annex B */
2408 encode_field_or_prop_type (m_class_get_byval_arg (type
->data
.klass
), p
, &p
);
2414 #ifndef DISABLE_REFLECTION_EMIT
2416 encode_named_val (MonoReflectionAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, char *name
, MonoObject
*value
, MonoError
*error
)
2422 /* Preallocate a large enough buffer */
2423 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2424 char *str
= type_get_qualified_name (type
, NULL
);
2427 } else if (type
->type
== MONO_TYPE_SZARRAY
&& type
->data
.klass
->enumtype
) {
2428 char *str
= type_get_qualified_name (m_class_get_byval_arg (type
->data
.klass
), NULL
);
2434 len
+= strlen (name
);
2436 if ((p
-buffer
) + 20 + len
>= *buflen
) {
2440 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2441 p
= newbuf
+ (p
-buffer
);
2445 encode_field_or_prop_type (type
, p
, &p
);
2447 len
= strlen (name
);
2448 mono_metadata_encode_value (len
, p
, &p
);
2449 memcpy (p
, name
, len
);
2451 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, buflen
, type
, value
, NULL
, error
);
2452 return_if_nok (error
);
2454 *retbuffer
= buffer
;
2458 * mono_reflection_get_custom_attrs_blob:
2459 * \param ctor custom attribute constructor
2460 * \param ctorArgs arguments o the constructor
2464 * \param fieldValues
2465 * Creates the blob of data that needs to be saved in the metadata and that represents
2466 * the custom attributed described by \p ctor, \p ctorArgs etc.
2467 * \returns a \c Byte array representing the blob of data.
2470 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
2472 HANDLE_FUNCTION_ENTER ();
2474 MonoArrayHandle result
;
2476 MONO_ENTER_GC_UNSAFE
;
2480 MONO_HANDLE_NEW (MonoReflectionAssembly
, assembly
);
2481 MONO_HANDLE_NEW (MonoObject
, ctor
);
2482 MONO_HANDLE_NEW (MonoArray
, ctorArgs
);
2483 MONO_HANDLE_NEW (MonoArray
, properties
);
2484 MONO_HANDLE_NEW (MonoArray
, propValues
);
2485 MONO_HANDLE_NEW (MonoArray
, fields
);
2486 MONO_HANDLE_NEW (MonoArray
, fieldValues
);
2488 result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, error
);
2490 mono_error_cleanup (error
);
2492 MONO_EXIT_GC_UNSAFE
;
2494 HANDLE_FUNCTION_RETURN_OBJ (result
);
2498 * mono_reflection_get_custom_attrs_blob_checked:
2499 * \param ctor custom attribute constructor
2500 * \param ctorArgs arguments o the constructor
2504 * \param fieldValues
2505 * \param error set on error
2506 * Creates the blob of data that needs to be saved in the metadata and that represents
2507 * the custom attributed described by \p ctor, \p ctorArgs etc.
2508 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2511 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
, MonoError
*error
)
2513 MonoArrayHandle result
= NULL_HANDLE_INIT
;
2514 MonoMethodSignature
*sig
;
2515 MonoMethodSignature
*sig_free
= NULL
;
2517 char *buffer
= NULL
;
2520 MonoObjectHandle h1
= NULL_HANDLE_INIT
;
2521 MonoObjectHandle h2
= NULL_HANDLE_INIT
;
2522 MonoObjectHandle argh
= NULL_HANDLE_INIT
;
2524 HANDLE_FUNCTION_ENTER ();
2526 if (strcmp (ctor
->vtable
->klass
->name
, "RuntimeConstructorInfo")) {
2527 /* sig is freed later so allocate it in the heap */
2528 sig
= ctor_builder_to_signature_raw (NULL
, (MonoReflectionCtorBuilder
*)ctor
, error
); /* FIXME use handles */
2530 goto_if_nok (error
, leave
);
2532 sig
= mono_method_signature_internal (((MonoReflectionMethod
*)ctor
)->method
);
2535 g_assert (mono_array_length_internal (ctorArgs
) == sig
->param_count
);
2537 p
= buffer
= (char *)g_malloc (buflen
);
2538 /* write the prolog */
2542 argh
= MONO_HANDLE_NEW (MonoObject
, NULL
);
2544 for (i
= 0; i
< sig
->param_count
; ++i
) {
2545 arg
= mono_array_get_internal (ctorArgs
, MonoObject
*, i
);
2546 MONO_HANDLE_ASSIGN_RAW (argh
, arg
);
2547 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, &buflen
, sig
->params
[i
], arg
, NULL
, error
);
2548 goto_if_nok (error
, leave
);
2552 i
+= mono_array_length_internal (properties
);
2554 i
+= mono_array_length_internal (fields
);
2556 *p
++ = (i
>> 8) & 0xff;
2558 if (properties
|| fields
) {
2559 h1
= MONO_HANDLE_NEW (MonoObject
, NULL
);
2560 h2
= MONO_HANDLE_NEW (MonoObject
, NULL
);
2567 for (i
= 0; i
< mono_array_length_internal (properties
); ++i
) {
2571 prop
= (MonoObject
*)mono_array_get_internal (properties
, gpointer
, i
);
2572 MONO_HANDLE_ASSIGN_RAW (h1
, prop
);
2574 get_prop_name_and_type (prop
, &pname
, &ptype
, error
);
2575 goto_if_nok (error
, leave
);
2576 *p
++ = 0x54; /* PROPERTY signature */
2578 prop
= (MonoObject
*)mono_array_get_internal (propValues
, gpointer
, i
);
2579 MONO_HANDLE_ASSIGN_RAW (h2
, prop
);
2581 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ptype
, pname
, prop
, error
);
2583 goto_if_nok (error
, leave
);
2591 for (i
= 0; i
< mono_array_length_internal (fields
); ++i
) {
2595 field
= (MonoObject
*)mono_array_get_internal (fields
, gpointer
, i
);
2596 MONO_HANDLE_ASSIGN_RAW (h1
, field
);
2598 get_field_name_and_type (field
, &fname
, &ftype
, error
);
2599 goto_if_nok (error
, leave
);
2600 *p
++ = 0x53; /* FIELD signature */
2602 field
= (MonoObject
*)mono_array_get_internal (fieldValues
, gpointer
, i
);
2603 MONO_HANDLE_ASSIGN_RAW (h2
, field
);
2605 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ftype
, fname
, field
, error
);
2607 goto_if_nok (error
, leave
);
2611 g_assert (p
- buffer
<= buflen
);
2612 buflen
= p
- buffer
;
2613 result
= mono_array_new_handle (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
2614 goto_if_nok (error
, leave
);
2615 p
= mono_array_addr_internal (MONO_HANDLE_RAW (result
), char, 0);
2616 memcpy (p
, buffer
, buflen
);
2621 HANDLE_FUNCTION_RETURN_REF (MonoArray
, result
);
2625 reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
)
2629 mono_loader_lock ();
2631 MonoType
*parent_type
;
2632 MonoType
*child_type
;
2633 GHashTableIter iter
;
2635 g_hash_table_iter_init (&iter
, unparented
);
2637 while (g_hash_table_iter_next (&iter
, (gpointer
*) &child_type
, (gpointer
*) &parent_type
)) {
2638 MonoClass
*child_class
= mono_class_from_mono_type_internal (child_type
);
2639 if (parent_type
!= NULL
) {
2640 MonoClass
*parent_class
= mono_class_from_mono_type_internal (parent_type
);
2641 child_class
->parent
= NULL
;
2642 /* fool mono_class_setup_parent */
2643 child_class
->supertypes
= NULL
;
2644 mono_class_setup_parent (child_class
, parent_class
);
2645 } else if (strcmp (child_class
->name
, "Object") == 0 && strcmp (child_class
->name_space
, "System") == 0) {
2646 const char *old_n
= child_class
->name
;
2647 /* trick to get relative numbering right when compiling corlib */
2648 child_class
->name
= "BuildingObject";
2649 mono_class_setup_parent (child_class
, mono_defaults
.object_class
);
2650 child_class
->name
= old_n
;
2652 mono_class_setup_mono_type (child_class
);
2653 mono_class_setup_supertypes (child_class
);
2656 mono_loader_unlock ();
2657 return is_ok (error
);
2661 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2663 HANDLE_FUNCTION_ENTER ();
2666 mono_loader_lock ();
2668 gint32 entering_state
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_tb
), state
);
2669 if (entering_state
!= MonoTypeBuilderNew
) {
2670 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
));
2674 MONO_HANDLE_SETVAL (ref_tb
, state
, gint32
/*MonoTypeBuilderState*/, MonoTypeBuilderEntered
);
2675 MonoReflectionModuleBuilderHandle module_ref
;
2676 module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2677 GHashTable
*unparented_classes
;
2678 unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
2680 // If this type is already setup, exit. We'll fix the parenting later
2682 type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2686 MonoReflectionModuleBuilderHandle ref_module
;
2687 ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2688 MonoDynamicImage
*dynamic_image
;
2689 dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
2691 MonoStringHandle ref_name
;
2692 ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, name
);
2693 MonoStringHandle ref_nspace
;
2694 ref_nspace
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, nspace
);
2697 table_idx
= MONO_HANDLE_GETVAL (ref_tb
, table_idx
);
2699 * The size calculation here warrants some explaining.
2700 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2701 * meaning we need to alloc enough space to morth a def into a gtd.
2704 klass
= (MonoClass
*)mono_image_alloc0 (&dynamic_image
->image
, MAX (sizeof (MonoClassDef
), sizeof (MonoClassGtd
)));
2705 klass
->class_kind
= MONO_CLASS_DEF
;
2707 klass
->image
= &dynamic_image
->image
;
2709 klass
->inited
= 1; /* we lie to the runtime */
2710 klass
->name
= mono_string_to_utf8_image (klass
->image
, ref_name
, error
);
2711 goto_if_nok (error
, leave
);
2712 klass
->name_space
= mono_string_to_utf8_image (klass
->image
, ref_nspace
, error
);
2713 goto_if_nok (error
, leave
);
2714 klass
->type_token
= MONO_TOKEN_TYPE_DEF
| table_idx
;
2715 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
2717 MONO_PROFILER_RAISE (class_loading
, (klass
));
2719 klass
->element_class
= klass
;
2721 g_assert (!mono_class_has_ref_info (klass
));
2722 mono_class_set_ref_info (klass
, MONO_HANDLE_CAST (MonoObject
, ref_tb
));
2724 MonoReflectionTypeHandle ref_nesting_type
;
2725 ref_nesting_type
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_tb
, nesting_type
);
2726 /* Put into cache so mono_class_get_checked () will find it.
2727 Skip nested types as those should not be available on the global scope. */
2728 if (MONO_HANDLE_IS_NULL (ref_nesting_type
))
2729 mono_image_add_to_name_cache (klass
->image
, klass
->name_space
, klass
->name
, table_idx
);
2732 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2733 by performing a mono_class_get which does the full resolution.
2735 Working around this semantics would require us to write a lot of code for no clear advantage.
2737 mono_image_append_class_to_reflection_info_set (klass
);
2739 mono_dynamic_image_register_token (dynamic_image
, MONO_TOKEN_TYPE_DEF
| table_idx
, MONO_HANDLE_CAST (MonoObject
, ref_tb
), MONO_DYN_IMAGE_TOK_NEW
);
2741 if ((!strcmp (klass
->name
, "ValueType") && !strcmp (klass
->name_space
, "System")) ||
2742 (!strcmp (klass
->name
, "Object") && !strcmp (klass
->name_space
, "System")) ||
2743 (!strcmp (klass
->name
, "Enum") && !strcmp (klass
->name_space
, "System"))) {
2744 klass
->instance_size
= MONO_ABI_SIZEOF (MonoObject
);
2745 klass
->size_inited
= 1;
2746 mono_class_setup_vtable_general (klass
, NULL
, 0, NULL
);
2749 mono_class_setup_mono_type (klass
);
2752 * FIXME: handle interfaces.
2754 MonoReflectionTypeHandle ref_tb_type
;
2755 ref_tb_type
= MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
);
2756 MONO_HANDLE_SETVAL (ref_tb_type
, type
, MonoType
*, m_class_get_byval_arg (klass
));
2757 MONO_HANDLE_SETVAL (ref_tb
, state
, gint32
, MonoTypeBuilderFinished
);
2759 reflection_init_generic_class (ref_tb
, error
);
2760 goto_if_nok (error
, leave
);
2762 // Do here so that the search inside of the parent can see the above type that's been set.
2763 MonoReflectionTypeHandle ref_parent
;
2764 ref_parent
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoObject
, ref_tb
, parent
));
2765 MonoType
*parent_type
;
2767 if (!MONO_HANDLE_IS_NULL (ref_parent
)) {
2768 MonoClass
*parent_klass
= mono_handle_class (ref_parent
);
2769 gboolean recursive_init
= TRUE
;
2771 if (is_sre_type_builder (parent_klass
)) {
2772 MonoTypeBuilderState parent_state
= (MonoTypeBuilderState
)MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_parent
), state
);
2774 if (parent_state
!= MonoTypeBuilderNew
) {
2775 // Initialize types reachable from parent recursively
2776 // We'll fix the type hierarchy later
2777 recursive_init
= FALSE
;
2781 if (recursive_init
) {
2782 // If we haven't encountered a cycle, force the creation of ref_parent's type
2783 mono_reflection_type_handle_mono_type (ref_parent
, error
);
2784 goto_if_nok (error
, leave
);
2787 parent_type
= MONO_HANDLE_GETVAL (ref_parent
, type
);
2789 // If we failed to create the parent, fail the child
2794 // Push the child type and parent type to process later
2795 // Note: parent_type may be null.
2796 g_assert (!g_hash_table_lookup (unparented_classes
, m_class_get_byval_arg (klass
)));
2797 g_hash_table_insert (unparented_classes
, m_class_get_byval_arg (klass
), parent_type
);
2799 if (!MONO_HANDLE_IS_NULL (ref_nesting_type
)) {
2800 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_nesting_type
), error
))
2803 MonoType
*nesting_type
= mono_reflection_type_handle_mono_type (ref_nesting_type
, error
);
2804 goto_if_nok (error
, leave
);
2805 klass
->nested_in
= mono_class_from_mono_type_internal (nesting_type
);
2808 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2810 MONO_PROFILER_RAISE (class_loaded
, (klass
));
2813 mono_loader_unlock ();
2814 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2818 * reflection_init_generic_class:
2819 * @tb: a TypeBuilder object
2820 * @error: set on error
2822 * Creates the generic class after all generic parameters have been added.
2823 * On success returns TRUE, on failure returns FALSE and sets @error.
2825 * This assumes that reflection_setup_internal_class has already set up
2829 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2831 HANDLE_FUNCTION_ENTER ();
2835 MonoTypeBuilderState ref_state
= (MonoTypeBuilderState
)MONO_HANDLE_GETVAL (ref_tb
, state
);
2836 g_assert (ref_state
== MonoTypeBuilderFinished
);
2838 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2839 MonoClass
*klass
= mono_class_from_mono_type_internal (type
);
2841 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
2842 int count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
2847 if (mono_class_try_get_generic_container (klass
) != NULL
)
2848 goto leave
; /* already setup */
2850 MonoGenericContainer
*generic_container
;
2851 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2853 generic_container
->owner
.klass
= klass
;
2854 generic_container
->type_argc
= count
;
2855 generic_container
->type_params
= (MonoGenericParamFull
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericParamFull
) * count
);
2857 klass
->class_kind
= MONO_CLASS_GTD
;
2858 mono_class_set_generic_container (klass
, generic_container
);
2861 MonoReflectionGenericParamHandle ref_gparam
;
2862 ref_gparam
= MONO_HANDLE_NEW (MonoReflectionGenericParam
, NULL
);
2863 for (int i
= 0; i
< count
; i
++) {
2864 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
2865 MonoType
*param_type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), error
);
2866 goto_if_nok (error
, leave
);
2867 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) param_type
->data
.generic_param
;
2868 generic_container
->type_params
[i
] = *param
;
2869 /*Make sure we are a diferent type instance */
2870 generic_container
->type_params
[i
].owner
= generic_container
;
2871 generic_container
->type_params
[i
].info
.pklass
= NULL
;
2872 generic_container
->type_params
[i
].info
.flags
= MONO_HANDLE_GETVAL (ref_gparam
, attrs
);
2874 g_assert (generic_container
->type_params
[i
].owner
);
2877 generic_container
->context
.class_inst
= mono_get_shared_generic_inst (generic_container
);
2878 MonoGenericContext
* context
;
2879 context
= &generic_container
->context
;
2880 MonoType
*canonical_inst
;
2881 canonical_inst
= &((MonoClassGtd
*)klass
)->canonical_inst
;
2882 canonical_inst
->type
= MONO_TYPE_GENERICINST
;
2883 canonical_inst
->data
.generic_class
= mono_metadata_lookup_generic_class (klass
, context
->class_inst
, FALSE
);
2886 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2889 static MonoMarshalSpec
*
2890 mono_marshal_spec_from_builder (MonoImage
*image
, MonoAssembly
*assembly
,
2891 MonoReflectionMarshal
*minfo
, MonoError
*error
)
2893 MonoMarshalSpec
*res
;
2897 res
= image_g_new0 (image
, MonoMarshalSpec
, 1);
2898 res
->native
= (MonoMarshalNative
)minfo
->type
;
2900 switch (minfo
->type
) {
2901 case MONO_NATIVE_LPARRAY
:
2902 res
->data
.array_data
.elem_type
= (MonoMarshalNative
)minfo
->eltype
;
2903 if (minfo
->has_size
) {
2904 res
->data
.array_data
.param_num
= minfo
->param_num
;
2905 res
->data
.array_data
.num_elem
= minfo
->count
;
2906 res
->data
.array_data
.elem_mult
= minfo
->param_num
== -1 ? 0 : 1;
2909 res
->data
.array_data
.param_num
= -1;
2910 res
->data
.array_data
.num_elem
= -1;
2911 res
->data
.array_data
.elem_mult
= -1;
2915 case MONO_NATIVE_BYVALTSTR
:
2916 case MONO_NATIVE_BYVALARRAY
:
2917 res
->data
.array_data
.num_elem
= minfo
->count
;
2920 case MONO_NATIVE_CUSTOM
:
2921 if (minfo
->marshaltyperef
) {
2922 MonoType
*marshaltyperef
= mono_reflection_type_get_handle ((MonoReflectionType
*)minfo
->marshaltyperef
, error
);
2923 if (!is_ok (error
)) {
2924 image_g_free (image
, res
);
2927 res
->data
.custom_data
.custom_name
=
2928 type_get_fully_qualified_name (marshaltyperef
);
2930 if (minfo
->mcookie
) {
2931 res
->data
.custom_data
.cookie
= mono_string_to_utf8_checked_internal (minfo
->mcookie
, error
);
2932 if (!is_ok (error
)) {
2933 image_g_free (image
, res
);
2945 #endif /* !DISABLE_REFLECTION_EMIT */
2947 MonoReflectionMarshalAsAttributeHandle
2948 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain
*domain
, MonoClass
*klass
,
2949 MonoMarshalSpec
*spec
, MonoError
*error
)
2953 MonoAssemblyLoadContext
*alc
= mono_domain_ambient_alc (domain
);
2954 MonoReflectionMarshalAsAttributeHandle minfo
= MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, mono_object_new_handle (domain
, mono_class_get_marshal_as_attribute_class (), error
));
2955 goto_if_nok (error
, fail
);
2957 utype
= spec
->native
;
2958 MONO_HANDLE_SETVAL (minfo
, utype
, guint32
, utype
);
2961 case MONO_NATIVE_LPARRAY
:
2962 MONO_HANDLE_SETVAL (minfo
, array_subtype
, guint32
, spec
->data
.array_data
.elem_type
);
2963 if (spec
->data
.array_data
.num_elem
!= -1)
2964 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2965 if (spec
->data
.array_data
.param_num
!= -1)
2966 MONO_HANDLE_SETVAL (minfo
, size_param_index
, gint16
, spec
->data
.array_data
.param_num
);
2969 case MONO_NATIVE_BYVALTSTR
:
2970 case MONO_NATIVE_BYVALARRAY
:
2971 if (spec
->data
.array_data
.num_elem
!= -1)
2972 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2975 case MONO_NATIVE_CUSTOM
:
2976 if (spec
->data
.custom_data
.custom_name
) {
2977 MonoType
*mtype
= mono_reflection_type_from_name_checked (spec
->data
.custom_data
.custom_name
, alc
, klass
->image
, error
);
2978 goto_if_nok (error
, fail
);
2981 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, mtype
, error
);
2982 goto_if_nok (error
, fail
);
2984 MONO_HANDLE_SET (minfo
, marshal_type_ref
, rt
);
2987 MonoStringHandle custom_name
= mono_string_new_handle (domain
, spec
->data
.custom_data
.custom_name
, error
);
2988 goto_if_nok (error
, fail
);
2989 MONO_HANDLE_SET (minfo
, marshal_type
, custom_name
);
2991 if (spec
->data
.custom_data
.cookie
) {
2992 MonoStringHandle cookie
= mono_string_new_handle (domain
, spec
->data
.custom_data
.cookie
, error
);
2993 goto_if_nok (error
, fail
);
2994 MONO_HANDLE_SET (minfo
, marshal_cookie
, cookie
);
3004 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, NULL
);
3007 #ifndef DISABLE_REFLECTION_EMIT
3009 reflection_methodbuilder_to_mono_method (MonoClass
*klass
,
3010 ReflectionMethodBuilder
*rmb
,
3011 MonoMethodSignature
*sig
,
3015 MonoMethodWrapper
*wrapperm
;
3016 MonoMarshalSpec
**specs
= NULL
;
3017 MonoReflectionMethodAux
*method_aux
;
3024 * Methods created using a MethodBuilder should have their memory allocated
3025 * inside the image mempool, while dynamic methods should have their memory
3028 dynamic
= rmb
->refs
!= NULL
;
3029 image
= dynamic
? NULL
: klass
->image
;
3032 g_assert (!mono_class_is_ginst (klass
));
3034 mono_loader_lock ();
3036 if ((rmb
->attrs
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
3037 (rmb
->iattrs
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
3038 m
= (MonoMethod
*)image_g_new0 (image
, MonoMethodPInvoke
, 1);
3040 m
= (MonoMethod
*)image_g_new0 (image
, MonoDynamicMethod
, 1);
3042 wrapperm
= (MonoMethodWrapper
*)m
;
3044 m
->dynamic
= dynamic
;
3046 m
->flags
= rmb
->attrs
;
3047 m
->iflags
= rmb
->iattrs
;
3048 m
->name
= string_to_utf8_image_raw (image
, rmb
->name
, error
);
3049 goto_if_nok (error
, fail
);
3052 m
->sre_method
= TRUE
;
3053 m
->skip_visibility
= rmb
->skip_visibility
;
3055 m
->token
= MONO_TOKEN_METHOD_DEF
| (*rmb
->table_idx
);
3057 if (m
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) {
3058 if (klass
== mono_defaults
.string_class
&& !strcmp (m
->name
, ".ctor"))
3061 m
->signature
->pinvoke
= 1;
3062 } else if (m
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) {
3063 m
->signature
->pinvoke
= 1;
3065 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3067 method_aux
->dllentry
= rmb
->dllentry
? string_to_utf8_image_raw (image
, rmb
->dllentry
, error
) : image_strdup (image
, m
->name
);
3068 mono_error_assert_ok (error
);
3069 method_aux
->dll
= string_to_utf8_image_raw (image
, rmb
->dll
, error
);
3070 mono_error_assert_ok (error
);
3072 ((MonoMethodPInvoke
*)m
)->piflags
= (rmb
->native_cc
<< 8) | (rmb
->charset
? (rmb
->charset
- 1) * 2 : 0) | rmb
->extra_flags
;
3074 if (image_is_dynamic (klass
->image
))
3075 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
3079 } else if (!(m
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) &&
3080 !(m
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
)) {
3081 MonoMethodHeader
*header
;
3083 gint32 max_stack
, i
;
3084 gint32 num_locals
= 0;
3085 gint32 num_clauses
= 0;
3089 code
= mono_array_addr_internal (rmb
->ilgen
->code
, guint8
, 0);
3090 code_size
= rmb
->ilgen
->code_len
;
3091 max_stack
= rmb
->ilgen
->max_stack
;
3092 num_locals
= rmb
->ilgen
->locals
? mono_array_length_internal (rmb
->ilgen
->locals
) : 0;
3093 if (rmb
->ilgen
->ex_handlers
)
3094 num_clauses
= mono_reflection_method_count_clauses (rmb
->ilgen
);
3097 code
= mono_array_addr_internal (rmb
->code
, guint8
, 0);
3098 code_size
= mono_array_length_internal (rmb
->code
);
3099 /* we probably need to run a verifier on the code... */
3109 header
= (MonoMethodHeader
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_HEADER
+ num_locals
* sizeof (MonoType
*));
3110 header
->code_size
= code_size
;
3111 header
->code
= (const unsigned char *)image_g_malloc (image
, code_size
);
3112 memcpy ((char*)header
->code
, code
, code_size
);
3113 header
->max_stack
= max_stack
;
3114 header
->init_locals
= rmb
->init_locals
;
3115 header
->num_locals
= num_locals
;
3117 for (i
= 0; i
< num_locals
; ++i
) {
3118 MonoReflectionLocalBuilder
*lb
=
3119 mono_array_get_internal (rmb
->ilgen
->locals
, MonoReflectionLocalBuilder
*, i
);
3121 header
->locals
[i
] = image_g_new0 (image
, MonoType
, 1);
3122 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)lb
->type
, error
);
3123 mono_error_assert_ok (error
);
3124 memcpy (header
->locals
[i
], type
, mono_sizeof_type (type
));
3127 header
->num_clauses
= num_clauses
;
3129 header
->clauses
= method_encode_clauses (image
, (MonoDynamicImage
*)klass
->image
,
3130 rmb
->ilgen
, num_clauses
, error
);
3131 mono_error_assert_ok (error
);
3134 wrapperm
->header
= header
;
3135 MonoDynamicMethod
*dm
= (MonoDynamicMethod
*)wrapperm
;
3136 dm
->assembly
= klass
->image
->assembly
;
3139 if (rmb
->generic_params
) {
3140 int count
= mono_array_length_internal (rmb
->generic_params
);
3141 MonoGenericContainer
*container
;
3143 container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
3144 container
->is_method
= TRUE
;
3145 container
->is_anonymous
= FALSE
;
3146 container
->type_argc
= count
;
3147 container
->type_params
= image_g_new0 (image
, MonoGenericParamFull
, count
);
3148 container
->owner
.method
= m
;
3150 m
->is_generic
= TRUE
;
3151 mono_method_set_generic_container (m
, container
);
3153 for (i
= 0; i
< count
; i
++) {
3154 MonoReflectionGenericParam
*gp
=
3155 mono_array_get_internal (rmb
->generic_params
, MonoReflectionGenericParam
*, i
);
3156 MonoType
*gp_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gp
, error
);
3157 mono_error_assert_ok (error
);
3158 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) gp_type
->data
.generic_param
;
3159 container
->type_params
[i
] = *param
;
3160 container
->type_params
[i
].owner
= container
;
3162 gp
->type
.type
->data
.generic_param
= (MonoGenericParam
*)&container
->type_params
[i
];
3164 MonoClass
*gklass
= mono_class_from_mono_type_internal (gp_type
);
3165 gklass
->wastypebuilder
= TRUE
;
3169 * The method signature might have pointers to generic parameters that belong to other methods.
3170 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3171 * generic parameters.
3173 for (i
= 0; i
< m
->signature
->param_count
; ++i
) {
3174 MonoType
*t
= m
->signature
->params
[i
];
3175 if (t
->type
== MONO_TYPE_MVAR
) {
3176 MonoGenericParam
*gparam
= t
->data
.generic_param
;
3177 if (gparam
->num
< count
) {
3178 m
->signature
->params
[i
] = mono_metadata_type_dup (image
, m
->signature
->params
[i
]);
3179 m
->signature
->params
[i
]->data
.generic_param
= mono_generic_container_get_param (container
, gparam
->num
);
3185 if (mono_class_is_gtd (klass
)) {
3186 container
->parent
= mono_class_get_generic_container (klass
);
3187 container
->context
.class_inst
= mono_class_get_generic_container (klass
)->context
.class_inst
;
3189 container
->context
.method_inst
= mono_get_shared_generic_inst (container
);
3193 MonoMethodWrapper
*mw
= (MonoMethodWrapper
*)m
;
3197 m
->wrapper_type
= MONO_WRAPPER_DYNAMIC_METHOD
;
3199 mw
->method_data
= data
= image_g_new (image
, gpointer
, rmb
->nrefs
+ 1);
3200 data
[0] = GUINT_TO_POINTER (rmb
->nrefs
);
3201 for (i
= 0; i
< rmb
->nrefs
; ++i
)
3202 data
[i
+ 1] = rmb
->refs
[i
];
3207 /* Parameter info */
3210 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3211 method_aux
->param_names
= image_g_new0 (image
, char *, mono_method_signature_internal (m
)->param_count
+ 1);
3212 for (i
= 0; i
<= m
->signature
->param_count
; ++i
) {
3213 MonoReflectionParamBuilder
*pb
;
3214 if ((pb
= mono_array_get_internal (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3215 if ((i
> 0) && (pb
->attrs
)) {
3216 /* Make a copy since it might point to a shared type structure */
3217 m
->signature
->params
[i
- 1] = mono_metadata_type_dup (klass
->image
, m
->signature
->params
[i
- 1]);
3218 m
->signature
->params
[i
- 1]->attrs
= pb
->attrs
;
3221 if (pb
->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
) {
3222 MonoDynamicImage
*assembly
;
3224 MonoTypeEnum def_type
;
3228 if (!method_aux
->param_defaults
) {
3229 method_aux
->param_defaults
= image_g_new0 (image
, guint8
*, m
->signature
->param_count
+ 1);
3230 method_aux
->param_default_types
= image_g_new0 (image
, guint32
, m
->signature
->param_count
+ 1);
3232 assembly
= (MonoDynamicImage
*)klass
->image
;
3233 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &def_type
);
3234 /* Copy the data from the blob since it might get realloc-ed */
3235 p
= assembly
->blob
.data
+ idx
;
3236 len
= mono_metadata_decode_blob_size (p
, &p2
);
3238 method_aux
->param_defaults
[i
] = (uint8_t *)image_g_malloc (image
, len
);
3239 method_aux
->param_default_types
[i
] = def_type
;
3240 memcpy ((gpointer
)method_aux
->param_defaults
[i
], p
, len
);
3244 method_aux
->param_names
[i
] = string_to_utf8_image_raw (image
, pb
->name
, error
);
3245 mono_error_assert_ok (error
);
3248 if (!method_aux
->param_cattr
)
3249 method_aux
->param_cattr
= image_g_new0 (image
, MonoCustomAttrInfo
*, m
->signature
->param_count
+ 1);
3250 method_aux
->param_cattr
[i
] = mono_custom_attrs_from_builders (image
, klass
->image
, pb
->cattrs
);
3256 /* Parameter marshalling */
3258 for (i
= 0; i
< mono_array_length_internal (rmb
->pinfo
); ++i
) {
3259 MonoReflectionParamBuilder
*pb
;
3260 if ((pb
= mono_array_get_internal (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3261 if (pb
->marshal_info
) {
3263 specs
= image_g_new0 (image
, MonoMarshalSpec
*, sig
->param_count
+ 1);
3264 specs
[pb
->position
] =
3265 mono_marshal_spec_from_builder (image
, klass
->image
->assembly
, pb
->marshal_info
, error
);
3266 goto_if_nok (error
, fail
);
3270 if (specs
!= NULL
) {
3272 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3273 method_aux
->param_marshall
= specs
;
3276 if (image_is_dynamic (klass
->image
) && method_aux
)
3277 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
3280 mono_loader_unlock ();
3281 if (!m
) // FIXME: This leaks if image is not NULL.
3282 image_g_free (image
, specs
);
3291 ctorbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionCtorBuilder
* mb
, MonoError
*error
)
3293 /* We need to clear handles for rmb fields created in mono_reflection_methodbuilder_from_ctor_builder */
3294 HANDLE_FUNCTION_ENTER ();
3295 ReflectionMethodBuilder rmb
;
3296 MonoMethodSignature
*sig
;
3299 mono_loader_lock ();
3301 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb
, mb
, error
)) {
3302 mono_loader_unlock ();
3306 g_assert (klass
->image
!= NULL
);
3307 sig
= ctor_builder_to_signature_raw (klass
->image
, mb
, error
); /* FIXME use handles */
3308 mono_loader_unlock ();
3309 goto_if_nok (error
, exit_null
);
3311 mb
->mhandle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3312 goto_if_nok (error
, exit_null
);
3313 mono_save_custom_attrs (klass
->image
, mb
->mhandle
, mb
->cattrs
);
3315 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
) {
3316 /* ilgen is no longer needed */
3325 HANDLE_FUNCTION_RETURN_VAL (ret
);
3329 methodbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionMethodBuilderHandle ref_mb
, MonoError
*error
)
3331 /* We need to clear handles for rmb fields created in mono_reflection_methodbuilder_from_method_builder */
3332 HANDLE_FUNCTION_ENTER ();
3333 ReflectionMethodBuilder rmb
;
3334 MonoMethodSignature
*sig
;
3335 MonoMethod
*ret
, *method
;
3339 mono_loader_lock ();
3341 MonoReflectionMethodBuilder
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME use handles */
3342 if (!mono_reflection_methodbuilder_from_method_builder (&rmb
, mb
, error
)) {
3343 mono_loader_unlock ();
3347 g_assert (klass
->image
!= NULL
);
3348 sig
= method_builder_to_signature (klass
->image
, ref_mb
, error
);
3349 mono_loader_unlock ();
3350 goto_if_nok (error
, exit_null
);
3352 method
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3353 goto_if_nok (error
, exit_null
);
3354 MONO_HANDLE_SETVAL (ref_mb
, mhandle
, MonoMethod
*, method
);
3355 mono_save_custom_attrs (klass
->image
, method
, mb
->cattrs
);
3357 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
)
3358 /* ilgen is no longer needed */
3365 HANDLE_FUNCTION_RETURN_VAL (ret
);
3369 methodbuilder_to_mono_method_raw (MonoClass
*klass
, MonoReflectionMethodBuilder
* mb_raw
, MonoError
*error
)
3371 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3373 MONO_HANDLE_DCL (MonoReflectionMethodBuilder
, mb
);
3374 MonoMethod
* const result
= methodbuilder_to_mono_method (klass
, mb
, error
);
3375 HANDLE_FUNCTION_RETURN_VAL (result
);
3380 #ifndef DISABLE_REFLECTION_EMIT
3383 * fix_partial_generic_class:
3384 * @klass: a generic instantiation MonoClass
3385 * @error: set on error
3387 * Assumes that the generic container of @klass has its vtable
3388 * initialized, and updates the parent class, interfaces, methods and
3389 * fields of @klass by inflating the types using the generic context.
3391 * On success returns TRUE, on failure returns FALSE and sets @error.
3395 fix_partial_generic_class (MonoClass
*klass
, MonoError
*error
)
3397 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3402 if (klass
->wastypebuilder
)
3405 if (klass
->parent
!= gklass
->parent
) {
3406 MonoType
*parent_type
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (m_class_get_parent (gklass
)), &mono_class_get_generic_class (klass
)->context
, error
);
3407 if (is_ok (error
)) {
3408 MonoClass
*parent
= mono_class_from_mono_type_internal (parent_type
);
3409 mono_metadata_free_type (parent_type
);
3410 if (parent
!= klass
->parent
) {
3411 /*fool mono_class_setup_parent*/
3412 klass
->supertypes
= NULL
;
3413 mono_class_setup_parent (klass
, parent
);
3416 if (gklass
->wastypebuilder
)
3417 klass
->wastypebuilder
= TRUE
;
3422 if (!mono_class_get_generic_class (klass
)->need_sync
)
3425 int mcount
= mono_class_get_method_count (klass
);
3426 int gmcount
= mono_class_get_method_count (gklass
);
3427 if (mcount
!= gmcount
) {
3428 mono_class_set_method_count (klass
, gmcount
);
3429 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * (gmcount
+ 1));
3431 for (i
= 0; i
< gmcount
; i
++) {
3432 klass
->methods
[i
] = mono_class_inflate_generic_method_full_checked (
3433 gklass
->methods
[i
], klass
, mono_class_get_context (klass
), error
);
3434 mono_error_assert_ok (error
);
3438 if (klass
->interface_count
&& klass
->interface_count
!= gklass
->interface_count
) {
3439 klass
->interface_count
= gklass
->interface_count
;
3440 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * gklass
->interface_count
);
3441 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3443 MonoClass
**gklass_interfaces
= m_class_get_interfaces (gklass
);
3444 for (i
= 0; i
< gklass
->interface_count
; ++i
) {
3445 MonoType
*iface_type
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (gklass_interfaces
[i
]), mono_class_get_context (klass
), error
);
3446 return_val_if_nok (error
, FALSE
);
3448 klass
->interfaces
[i
] = mono_class_from_mono_type_internal (iface_type
);
3449 mono_metadata_free_type (iface_type
);
3451 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3454 klass
->interfaces_inited
= 1;
3457 int fcount
= mono_class_get_field_count (klass
);
3458 int gfcount
= mono_class_get_field_count (gklass
);
3459 if (fcount
!= gfcount
) {
3460 mono_class_set_field_count (klass
, gfcount
);
3461 klass
->fields
= image_g_new0 (klass
->image
, MonoClassField
, gfcount
);
3463 for (i
= 0; i
< gfcount
; i
++) {
3464 klass
->fields
[i
] = gklass
->fields
[i
];
3465 klass
->fields
[i
].parent
= klass
;
3466 klass
->fields
[i
].type
= mono_class_inflate_generic_type_checked (gklass
->fields
[i
].type
, mono_class_get_context (klass
), error
);
3467 return_val_if_nok (error
, FALSE
);
3471 /*We can only finish with this klass once it's parent has as well*/
3472 if (gklass
->wastypebuilder
)
3473 klass
->wastypebuilder
= TRUE
;
3478 * ensure_generic_class_runtime_vtable:
3479 * @klass a generic class
3480 * @error set on error
3482 * Ensures that the generic container of @klass has a vtable and
3483 * returns TRUE on success. On error returns FALSE and sets @error.
3486 ensure_generic_class_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3488 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3492 if (!ensure_runtime_vtable (gklass
, error
))
3495 return fix_partial_generic_class (klass
, error
);
3499 * ensure_runtime_vtable:
3501 * @error set on error
3503 * Ensures that @klass has a vtable and returns TRUE on success. On
3504 * error returns FALSE and sets @error.
3507 ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3509 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3514 if (!image_is_dynamic (klass
->image
) || (!tb
&& !mono_class_is_ginst (klass
)) || klass
->wastypebuilder
)
3517 if (!ensure_runtime_vtable (klass
->parent
, error
))
3521 num
= tb
->ctors
? mono_array_length_internal (tb
->ctors
): 0;
3522 num
+= tb
->num_methods
;
3523 mono_class_set_method_count (klass
, num
);
3524 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * num
);
3525 num
= tb
->ctors
? mono_array_length_internal (tb
->ctors
): 0;
3526 for (i
= 0; i
< num
; ++i
) {
3527 MonoMethod
*ctor
= ctorbuilder_to_mono_method (klass
, mono_array_get_internal (tb
->ctors
, MonoReflectionCtorBuilder
*, i
), error
);
3530 klass
->methods
[i
] = ctor
;
3532 num
= tb
->num_methods
;
3534 for (i
= 0; i
< num
; ++i
) {
3535 MonoMethod
*meth
= methodbuilder_to_mono_method_raw (klass
, mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
), error
); /* FIXME use handles */
3538 klass
->methods
[j
++] = meth
;
3541 if (tb
->interfaces
) {
3542 klass
->interface_count
= mono_array_length_internal (tb
->interfaces
);
3543 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * klass
->interface_count
);
3544 for (i
= 0; i
< klass
->interface_count
; ++i
) {
3545 MonoType
*iface
= mono_type_array_get_and_resolve_raw (tb
->interfaces
, i
, error
); /* FIXME use handles */
3546 return_val_if_nok (error
, FALSE
);
3547 klass
->interfaces
[i
] = mono_class_from_mono_type_internal (iface
);
3548 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3551 klass
->interfaces_inited
= 1;
3553 } else if (mono_class_is_ginst (klass
)){
3554 if (!ensure_generic_class_runtime_vtable (klass
, error
)) {
3555 mono_class_set_type_load_failure (klass
, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error
));
3560 if (mono_class_is_interface (klass
) && !mono_class_is_ginst (klass
)) {
3562 int mcount
= mono_class_get_method_count (klass
);
3563 for (i
= 0; i
< mcount
; ++i
) {
3564 MonoMethod
*im
= klass
->methods
[i
];
3565 if (!(im
->flags
& METHOD_ATTRIBUTE_STATIC
))
3566 im
->slot
= slot_num
++;
3569 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3570 mono_class_setup_interface_offsets (klass
);
3571 mono_class_setup_interface_id (klass
);
3575 * The generic vtable is needed even if image->run is not set since some
3576 * runtime code like ves_icall_Type_GetMethodsByName depends on
3577 * method->slot being defined.
3581 * tb->methods could not be freed since it is used for determining
3582 * overrides during dynamic vtable construction.
3589 mono_reflection_method_get_handle (MonoObject
*method
, MonoError
*error
)
3592 MonoClass
*klass
= mono_object_class (method
);
3593 if (is_sr_mono_method (klass
)) {
3594 MonoReflectionMethod
*sr_method
= (MonoReflectionMethod
*)method
;
3595 return sr_method
->method
;
3597 if (is_sre_method_builder (klass
)) {
3598 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)method
;
3601 if (mono_is_sre_method_on_tb_inst (klass
)) {
3602 MonoClass
*handle_class
;
3604 MonoMethod
*result
= (MonoMethod
*)mono_reflection_resolve_object (NULL
, method
, &handle_class
, NULL
, error
);
3605 return_val_if_nok (error
, NULL
);
3610 g_error ("Can't handle methods of type %s:%s", klass
->name_space
, klass
->name
);
3615 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
3617 MonoReflectionTypeBuilder
*tb
;
3619 MonoReflectionMethod
*m
;
3625 g_assert (image_is_dynamic (klass
->image
));
3627 if (!mono_class_has_ref_info (klass
))
3630 tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3631 g_assert (strcmp (mono_object_class (tb
)->name
, "TypeBuilder") == 0);
3635 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3636 MonoReflectionMethodBuilder
*mb
=
3637 mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3638 if (mb
->override_methods
)
3639 onum
+= mono_array_length_internal (mb
->override_methods
);
3644 *overrides
= g_new0 (MonoMethod
*, onum
* 2);
3647 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3648 MonoReflectionMethodBuilder
*mb
=
3649 mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3650 if (mb
->override_methods
) {
3651 for (j
= 0; j
< mono_array_length_internal (mb
->override_methods
); ++j
) {
3652 m
= mono_array_get_internal (mb
->override_methods
, MonoReflectionMethod
*, j
);
3654 (*overrides
) [onum
* 2] = mono_reflection_method_get_handle ((MonoObject
*)m
, error
);
3655 return_if_nok (error
);
3656 (*overrides
) [onum
* 2 + 1] = mb
->mhandle
;
3658 g_assert (mb
->mhandle
);
3666 *num_overrides
= onum
;
3670 modulebuilder_get_next_table_index (MonoReflectionModuleBuilder
*mb
, gint32 table
, gint32 num_fields
, MonoError
*error
)
3674 if (mb
->table_indexes
== NULL
) {
3675 MonoArray
*arr
= mono_array_new_checked (mono_object_domain (&mb
->module
.obj
), mono_defaults
.int_class
, 64, error
);
3676 return_val_if_nok (error
, 0);
3677 for (int i
= 0; i
< 64; i
++) {
3678 mono_array_set_internal (arr
, int, i
, 1);
3680 MONO_OBJECT_SETREF_INTERNAL (mb
, table_indexes
, arr
);
3682 gint32 index
= mono_array_get_internal (mb
->table_indexes
, gint32
, table
);
3683 gint32 next_index
= index
+ num_fields
;
3684 mono_array_set_internal (mb
->table_indexes
, gint32
, table
, next_index
);
3689 typebuilder_setup_one_field (MonoDynamicImage
*dynamic_image
, MonoClass
*klass
, int32_t first_idx
, MonoArray
*tb_fields
, int i
, MonoFieldDefaultValue
*def_value_out
, MonoError
*error
)
3691 HANDLE_FUNCTION_ENTER ();
3693 MonoImage
*image
= klass
->image
;
3694 MonoReflectionFieldBuilder
*fb
;
3695 MonoClassField
*field
;
3696 MonoArray
*rva_data
;
3698 fb
= (MonoReflectionFieldBuilder
*)mono_array_get_internal (tb_fields
, gpointer
, i
);
3699 field
= &klass
->fields
[i
];
3700 field
->parent
= klass
;
3701 field
->name
= string_to_utf8_image_raw (image
, fb
->name
, error
); /* FIXME use handles */
3702 goto_if_nok (error
, leave
);
3704 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3705 goto_if_nok (error
, leave
);
3706 field
->type
= mono_metadata_type_dup (klass
->image
, type
);
3707 field
->type
->attrs
= fb
->attrs
;
3709 field
->type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3710 goto_if_nok (error
, leave
);
3712 if (klass
->enumtype
&& strcmp (field
->name
, "value__") == 0) // used by enum classes to store the instance value
3713 field
->type
->attrs
|= FIELD_ATTRIBUTE_RT_SPECIAL_NAME
;
3715 if (!mono_type_get_underlying_type (field
->type
)) {
3716 if (!(klass
->enumtype
&& mono_metadata_type_equal (field
->type
, m_class_get_byval_arg (klass
)))) {
3717 mono_class_set_type_load_failure (klass
, "Field '%s' is an enum type with a bad underlying type", field
->name
);
3722 if ((fb
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
) && (rva_data
= fb
->rva_data
)) {
3723 char *base
= mono_array_addr_internal (rva_data
, char, 0);
3724 size_t size
= mono_array_length_internal (rva_data
);
3725 char *data
= (char *)mono_image_alloc (klass
->image
, size
);
3726 memcpy (data
, base
, size
);
3727 def_value_out
->data
= data
;
3729 if (fb
->offset
!= -1)
3730 field
->offset
= fb
->offset
;
3732 mono_save_custom_attrs (klass
->image
, field
, fb
->cattrs
);
3734 if (fb
->def_value
) {
3737 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3738 field
->type
->attrs
|= FIELD_ATTRIBUTE_HAS_DEFAULT
;
3739 idx
= mono_dynimage_encode_constant (assembly
, fb
->def_value
, &def_value_out
->def_type
);
3740 /* Copy the data from the blob since it might get realloc-ed */
3741 p
= assembly
->blob
.data
+ idx
;
3742 len
= mono_metadata_decode_blob_size (p
, &p2
);
3744 def_value_out
->data
= (const char *)mono_image_alloc (image
, len
);
3745 memcpy ((gpointer
)def_value_out
->data
, p
, len
);
3748 MonoObjectHandle field_builder_handle
= MONO_HANDLE_CAST (MonoObject
, MONO_HANDLE_NEW (MonoReflectionFieldBuilder
, fb
));
3749 mono_dynamic_image_register_token (dynamic_image
, mono_metadata_make_token (MONO_TABLE_FIELD
, first_idx
+ i
), field_builder_handle
, MONO_DYN_IMAGE_TOK_NEW
);
3752 HANDLE_FUNCTION_RETURN ();
3755 /* This initializes the same data as mono_class_setup_fields () */
3757 typebuilder_setup_fields (MonoClass
*klass
, MonoError
*error
)
3759 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3760 MonoFieldDefaultValue
*def_values
;
3761 MonoImage
*image
= klass
->image
;
3762 int i
, instance_size
, packing_size
= 0;
3766 if (klass
->parent
) {
3767 if (!klass
->parent
->size_inited
)
3768 mono_class_init_internal (klass
->parent
);
3769 instance_size
= klass
->parent
->instance_size
;
3771 instance_size
= MONO_ABI_SIZEOF (MonoObject
);
3774 int fcount
= tb
->num_fields
;
3775 mono_class_set_field_count (klass
, fcount
);
3777 gint32 first_idx
= 0;
3778 if (tb
->num_fields
> 0) {
3779 first_idx
= modulebuilder_get_next_table_index (tb
->module
, MONO_TABLE_FIELD
, (gint32
)tb
->num_fields
, error
);
3780 return_if_nok (error
);
3782 mono_class_set_first_field_idx (klass
, first_idx
- 1); /* Why do we subtract 1? because mono_class_create_from_typedef does it, too. */
3784 if (tb
->class_size
) {
3785 packing_size
= tb
->packing_size
;
3786 instance_size
+= tb
->class_size
;
3789 klass
->fields
= image_g_new0 (image
, MonoClassField
, fcount
);
3790 def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, fcount
);
3791 mono_class_set_field_def_values (klass
, def_values
);
3793 This is, guess what, a hack.
3794 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3795 On the static path no field class is resolved, only types are built. This is the right thing to do
3797 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3799 klass
->size_inited
= 1;
3801 for (i
= 0; i
< fcount
; ++i
) {
3802 typebuilder_setup_one_field (tb
->module
->dynamic_image
, klass
, first_idx
, tb
->fields
, i
, &def_values
[i
], error
);
3807 if (!mono_class_has_failure (klass
))
3808 mono_class_layout_fields (klass
, instance_size
, packing_size
, tb
->class_size
, TRUE
);
3812 typebuilder_setup_properties (MonoClass
*klass
, MonoError
*error
)
3814 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3815 MonoReflectionPropertyBuilder
*pb
;
3816 MonoImage
*image
= klass
->image
;
3817 MonoProperty
*properties
;
3818 MonoClassPropertyInfo
*info
;
3823 info
= (MonoClassPropertyInfo
*)mono_class_get_property_info (klass
);
3825 info
= mono_class_alloc0 (klass
, sizeof (MonoClassPropertyInfo
));
3826 mono_class_set_property_info (klass
, info
);
3829 info
->count
= tb
->properties
? mono_array_length_internal (tb
->properties
) : 0;
3832 properties
= image_g_new0 (image
, MonoProperty
, info
->count
);
3833 info
->properties
= properties
;
3834 for (i
= 0; i
< info
->count
; ++i
) {
3835 pb
= mono_array_get_internal (tb
->properties
, MonoReflectionPropertyBuilder
*, i
);
3836 properties
[i
].parent
= klass
;
3837 properties
[i
].attrs
= pb
->attrs
;
3838 properties
[i
].name
= string_to_utf8_image_raw (image
, pb
->name
, error
); /* FIXME use handles */
3842 properties
[i
].get
= pb
->get_method
->mhandle
;
3844 properties
[i
].set
= pb
->set_method
->mhandle
;
3846 mono_save_custom_attrs (klass
->image
, &properties
[i
], pb
->cattrs
);
3847 if (pb
->def_value
) {
3850 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3851 if (!info
->def_values
)
3852 info
->def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, info
->count
);
3853 properties
[i
].attrs
|= PROPERTY_ATTRIBUTE_HAS_DEFAULT
;
3854 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &info
->def_values
[i
].def_type
);
3855 /* Copy the data from the blob since it might get realloc-ed */
3856 p
= assembly
->blob
.data
+ idx
;
3857 len
= mono_metadata_decode_blob_size (p
, &p2
);
3859 info
->def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3860 memcpy ((gpointer
)info
->def_values
[i
].data
, p
, len
);
3866 typebuilder_setup_events (MonoClass
*klass
, MonoError
*error
)
3868 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3869 MonoReflectionEventBuilder
*eb
;
3870 MonoImage
*image
= klass
->image
;
3872 MonoClassEventInfo
*info
;
3877 info
= mono_class_alloc0 (klass
, sizeof (MonoClassEventInfo
));
3878 mono_class_set_event_info (klass
, info
);
3880 info
->count
= tb
->events
? mono_array_length_internal (tb
->events
) : 0;
3883 events
= image_g_new0 (image
, MonoEvent
, info
->count
);
3884 info
->events
= events
;
3885 for (i
= 0; i
< info
->count
; ++i
) {
3886 eb
= mono_array_get_internal (tb
->events
, MonoReflectionEventBuilder
*, i
);
3887 events
[i
].parent
= klass
;
3888 events
[i
].attrs
= eb
->attrs
;
3889 events
[i
].name
= string_to_utf8_image_raw (image
, eb
->name
, error
); /* FIXME use handles */
3893 events
[i
].add
= eb
->add_method
->mhandle
;
3894 if (eb
->remove_method
)
3895 events
[i
].remove
= eb
->remove_method
->mhandle
;
3896 if (eb
->raise_method
)
3897 events
[i
].raise
= eb
->raise_method
->mhandle
;
3899 #ifndef MONO_SMALL_CONFIG
3900 if (eb
->other_methods
) {
3902 events
[i
].other
= image_g_new0 (image
, MonoMethod
*, mono_array_length_internal (eb
->other_methods
) + 1);
3903 for (j
= 0; j
< mono_array_length_internal (eb
->other_methods
); ++j
) {
3904 MonoReflectionMethodBuilder
*mb
=
3905 mono_array_get_internal (eb
->other_methods
,
3906 MonoReflectionMethodBuilder
*, j
);
3907 events
[i
].other
[j
] = mb
->mhandle
;
3911 mono_save_custom_attrs (klass
->image
, &events
[i
], eb
->cattrs
);
3915 struct remove_instantiations_user_data
3922 remove_instantiations_of_and_ensure_contents (gpointer key
,
3926 struct remove_instantiations_user_data
*data
= (struct remove_instantiations_user_data
*)user_data
;
3927 MonoType
*type
= (MonoType
*)key
;
3928 MonoClass
*klass
= data
->klass
;
3929 gboolean already_failed
= !is_ok (data
->error
);
3930 ERROR_DECL (lerror
);
3931 MonoError
*error
= already_failed
? lerror
: data
->error
;
3933 if ((type
->type
== MONO_TYPE_GENERICINST
) && (type
->data
.generic_class
->container_class
== klass
)) {
3934 MonoClass
*inst_klass
= mono_class_from_mono_type_internal (type
);
3935 //Ensure it's safe to use it.
3936 if (!fix_partial_generic_class (inst_klass
, error
)) {
3937 mono_class_set_type_load_failure (inst_klass
, "Could not initialized generic type instance due to: %s", mono_error_get_message (error
));
3938 // Marked the class with failure, but since some other instantiation already failed,
3939 // just report that one, and swallow the error from this one.
3941 mono_error_cleanup (error
);
3949 * reflection_setup_internal_class:
3950 * @tb: a TypeBuilder object
3951 * @error: set on error
3953 * Creates a MonoClass that represents the TypeBuilder.
3954 * This is a trick that lets us simplify a lot of reflection code
3955 * (and will allow us to support Build and Run assemblies easier).
3957 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3960 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3962 HANDLE_FUNCTION_ENTER ();
3964 MonoReflectionModuleBuilderHandle module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
3965 GHashTable
*unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
3968 if (unparented_classes
) {
3969 ret_val
= reflection_setup_internal_class_internal (ref_tb
, error
);
3971 // If we're not being called recursively
3972 unparented_classes
= g_hash_table_new (NULL
, NULL
);
3973 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, unparented_classes
);
3975 ret_val
= reflection_setup_internal_class_internal (ref_tb
, error
);
3976 mono_error_assert_ok (error
);
3978 // Fix the relationship between the created classes and their parents
3979 reflection_setup_class_hierarchy (unparented_classes
, error
);
3980 mono_error_assert_ok (error
);
3982 g_hash_table_destroy (unparented_classes
);
3983 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, NULL
);
3986 HANDLE_FUNCTION_RETURN_VAL (ret_val
);
3989 MonoReflectionTypeHandle
3990 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3994 reflection_setup_internal_class (ref_tb
, error
);
3995 mono_error_assert_ok (error
);
3997 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_tb
);
3998 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
3999 MonoClass
*klass
= mono_class_from_mono_type_internal (type
);
4001 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, cattrs
);
4002 mono_save_custom_attrs (klass
->image
, klass
, MONO_HANDLE_RAW (cattrs
)); /* FIXME use handles */
4005 * we need to lock the domain because the lock will be taken inside
4006 * So, we need to keep the locking order correct.
4008 mono_loader_lock ();
4009 mono_domain_lock (domain
);
4010 if (klass
->wastypebuilder
) {
4011 mono_domain_unlock (domain
);
4012 mono_loader_unlock ();
4014 return mono_type_get_object_handle (domain
, m_class_get_byval_arg (klass
), error
);
4017 * Fields to set in klass:
4018 * the various flags: delegate/unicode/contextbound etc.
4020 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
4021 klass
->has_cctor
= 1;
4023 mono_class_setup_parent (klass
, klass
->parent
);
4024 /* fool mono_class_setup_supertypes */
4025 klass
->supertypes
= NULL
;
4026 mono_class_setup_supertypes (klass
);
4027 mono_class_setup_mono_type (klass
);
4029 /* enums are done right away */
4030 if (!klass
->enumtype
)
4031 if (!ensure_runtime_vtable (klass
, error
))
4034 MonoArrayHandle nested_types
;
4035 nested_types
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, subtypes
);
4036 if (!MONO_HANDLE_IS_NULL (nested_types
)) {
4037 GList
*nested
= NULL
;
4038 int num_nested
= mono_array_handle_length (nested_types
);
4039 MonoReflectionTypeHandle nested_tb
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
4040 for (int i
= 0; i
< num_nested
; ++i
) {
4041 MONO_HANDLE_ARRAY_GETREF (nested_tb
, nested_types
, i
);
4043 if (MONO_HANDLE_GETVAL (nested_tb
, type
) == NULL
) {
4044 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, nested_tb
), error
);
4045 mono_error_assert_ok (error
);
4048 MonoType
*subtype
= mono_reflection_type_handle_mono_type (nested_tb
, error
);
4049 goto_if_nok (error
, failure
);
4050 nested
= mono_g_list_prepend_image (klass
->image
, nested
, mono_class_from_mono_type_internal (subtype
));
4052 mono_class_set_nested_classes_property (klass
, nested
);
4055 klass
->nested_classes_inited
= TRUE
;
4057 typebuilder_setup_fields (klass
, error
);
4058 goto_if_nok (error
, failure
);
4059 typebuilder_setup_properties (klass
, error
);
4060 goto_if_nok (error
, failure
);
4062 typebuilder_setup_events (klass
, error
);
4063 goto_if_nok (error
, failure
);
4065 klass
->wastypebuilder
= TRUE
;
4067 MonoArrayHandle generic_params
;
4068 generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
4069 if (!MONO_HANDLE_IS_NULL (generic_params
)) {
4070 int num_params
= mono_array_handle_length (generic_params
);
4071 MonoReflectionTypeHandle ref_gparam
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
4072 for (int i
= 0; i
< num_params
; i
++) {
4073 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
4074 MonoType
*param_type
= mono_reflection_type_handle_mono_type (ref_gparam
, error
);
4075 goto_if_nok (error
, failure
);
4076 MonoClass
*gklass
= mono_class_from_mono_type_internal (param_type
);
4078 gklass
->wastypebuilder
= TRUE
;
4083 * If we are a generic TypeBuilder, there might be instantiations in the type cache
4084 * which have type System.Reflection.MonoGenericClass, but after the type is created,
4085 * we want to return normal System.MonoType objects, so clear these out from the cache.
4087 * Together with this we must ensure the contents of all instances to match the created type.
4089 if (mono_class_is_gtd (klass
)) {
4090 MonoMemoryManager
*memory_manager
= mono_domain_ambient_memory_manager (domain
);
4091 struct remove_instantiations_user_data data
;
4094 mono_error_assert_ok (error
);
4095 mono_mem_manager_lock (memory_manager
);
4096 mono_g_hash_table_foreach_remove (memory_manager
->type_hash
, remove_instantiations_of_and_ensure_contents
, &data
);
4097 mono_mem_manager_unlock (memory_manager
);
4098 goto_if_nok (error
, failure
);
4101 mono_domain_unlock (domain
);
4102 mono_loader_unlock ();
4104 if (klass
->enumtype
&& !mono_class_is_valid_enum (klass
)) {
4105 mono_class_set_type_load_failure (klass
, "Not a valid enumeration");
4106 mono_error_set_type_load_class (error
, klass
, "Not a valid enumeration");
4107 goto failure_unlocked
;
4110 MonoReflectionTypeHandle res
;
4111 res
= mono_type_get_object_handle (domain
, m_class_get_byval_arg (klass
), error
);
4112 goto_if_nok (error
, failure_unlocked
);
4117 mono_class_set_type_load_failure (klass
, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error
));
4118 klass
->wastypebuilder
= TRUE
;
4119 mono_domain_unlock (domain
);
4120 mono_loader_unlock ();
4122 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4128 } DynamicMethodReleaseData
;
4131 * The runtime automatically clean up those after finalization.
4133 static MonoReferenceQueue
*dynamic_method_queue
;
4136 free_dynamic_method (void *dynamic_method
)
4138 DynamicMethodReleaseData
*data
= (DynamicMethodReleaseData
*)dynamic_method
;
4139 MonoDomain
*domain
= data
->domain
;
4140 MonoMethod
*method
= data
->handle
;
4141 MonoGCHandle dis_link
;
4143 mono_domain_lock (domain
);
4144 dis_link
= g_hash_table_lookup (domain
->method_to_dyn_method
, method
);
4145 g_hash_table_remove (domain
->method_to_dyn_method
, method
);
4146 mono_domain_unlock (domain
);
4147 g_assert (dis_link
);
4148 mono_gchandle_free_internal (dis_link
);
4150 mono_runtime_free_method (domain
, method
);
4155 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb
, MonoError
*error
)
4157 /* We need to clear handles for rmb fields created in reflection_methodbuilder_from_dynamic_method */
4158 HANDLE_FUNCTION_ENTER ();
4159 MonoReferenceQueue
*queue
;
4161 DynamicMethodReleaseData
*release_data
;
4162 ReflectionMethodBuilder rmb
;
4163 MonoMethodSignature
*sig
;
4168 gboolean ret
= TRUE
;
4169 MonoReflectionDynamicMethod
*mb
;
4170 MonoAssembly
*ass
= NULL
;
4174 if (!(queue
= dynamic_method_queue
)) {
4175 mono_loader_lock ();
4176 if (!(queue
= dynamic_method_queue
))
4177 queue
= dynamic_method_queue
= mono_gc_reference_queue_new_internal (free_dynamic_method
);
4178 mono_loader_unlock ();
4181 sig
= dynamic_method_to_signature (ref_mb
, error
);
4182 goto_if_nok (error
, exit_false
);
4184 mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME convert reflection_create_dynamic_method to use handles */
4185 reflection_methodbuilder_from_dynamic_method (&rmb
, mb
);
4188 * Resolve references.
4191 * Every second entry in the refs array is reserved for storing handle_class,
4192 * which is needed by the ldtoken implementation in the JIT.
4194 rmb
.nrefs
= mb
->nrefs
;
4195 rmb
.refs
= g_new0 (gpointer
, mb
->nrefs
+ 1);
4196 for (i
= 0; i
< mb
->nrefs
; i
+= 2) {
4197 MonoClass
*handle_class
;
4199 MonoObject
*obj
= mono_array_get_internal (mb
->refs
, MonoObject
*, i
);
4200 MONO_HANDLE_PIN (obj
);
4202 if (strcmp (obj
->vtable
->klass
->name
, "DynamicMethod") == 0) {
4203 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4205 * The referenced DynamicMethod should already be created by the managed
4206 * code, except in the case of circular references. In that case, we store
4207 * method in the refs array, and fix it up later when the referenced
4208 * DynamicMethod is created.
4210 if (method
->mhandle
) {
4211 ref
= method
->mhandle
;
4215 method
->referenced_by
= g_slist_append (method
->referenced_by
, mb
);
4217 handle_class
= mono_defaults
.methodhandle_class
;
4219 MonoException
*ex
= NULL
;
4220 ref
= mono_reflection_resolve_object (mb
->module
->image
, obj
, &handle_class
, NULL
, error
);
4221 /* ref should not be a reference. Otherwise we would need a handle for it */
4222 if (!is_ok (error
)) {
4227 ex
= mono_get_exception_type_load (NULL
, NULL
);
4228 else if (mono_security_core_clr_enabled ())
4229 ex
= mono_security_core_clr_ensure_dynamic_method_resolved_object (ref
, handle_class
);
4233 mono_error_set_exception_instance (error
, ex
);
4239 rmb
.refs
[i
+ 1] = handle_class
;
4243 MonoType
*owner_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)mb
->owner
, error
);
4244 if (!is_ok (error
)) {
4248 klass
= mono_class_from_mono_type_internal (owner_type
);
4249 ass
= klass
->image
->assembly
;
4251 klass
= mono_defaults
.object_class
;
4252 ass
= (mb
->module
&& mb
->module
->image
) ? mb
->module
->image
->assembly
: NULL
;
4255 mb
->mhandle
= handle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
4256 ((MonoDynamicMethod
*)handle
)->assembly
= ass
;
4258 goto_if_nok (error
, exit_false
);
4260 release_data
= g_new (DynamicMethodReleaseData
, 1);
4261 release_data
->handle
= handle
;
4262 release_data
->domain
= mono_object_get_domain_internal ((MonoObject
*)mb
);
4263 if (!mono_gc_reference_queue_add_internal (queue
, (MonoObject
*)mb
, release_data
))
4264 g_free (release_data
);
4266 /* Fix up refs entries pointing at us */
4267 for (l
= mb
->referenced_by
; l
; l
= l
->next
) {
4268 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)l
->data
;
4269 MonoMethodWrapper
*wrapper
= (MonoMethodWrapper
*)method
->mhandle
;
4272 g_assert (method
->mhandle
);
4274 data
= (gpointer
*)wrapper
->method_data
;
4275 for (i
= 0; i
< GPOINTER_TO_UINT (data
[0]); i
+= 2) {
4276 if ((data
[i
+ 1] == mb
) && (data
[i
+ 1 + 1] == mono_defaults
.methodhandle_class
))
4277 data
[i
+ 1] = mb
->mhandle
;
4280 g_slist_free (mb
->referenced_by
);
4282 domain
= mono_domain_get ();
4283 mono_domain_lock (domain
);
4284 if (!domain
->method_to_dyn_method
)
4285 domain
->method_to_dyn_method
= g_hash_table_new (NULL
, NULL
);
4286 g_hash_table_insert (domain
->method_to_dyn_method
, handle
, mono_gchandle_new_weakref_internal ((MonoObject
*)mb
, TRUE
));
4287 mono_domain_unlock (domain
);
4293 HANDLE_FUNCTION_RETURN_VAL (ret
);
4297 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4299 (void) reflection_create_dynamic_method (mb
, error
);
4302 #endif /* DISABLE_REFLECTION_EMIT */
4304 MonoMethodSignature
*
4305 mono_reflection_lookup_signature (MonoImage
*image
, MonoMethod
*method
, guint32 token
, MonoError
*error
)
4307 MonoMethodSignature
*sig
;
4308 g_assert (image_is_dynamic (image
));
4312 sig
= (MonoMethodSignature
*)g_hash_table_lookup (((MonoDynamicImage
*)image
)->vararg_aux_hash
, GUINT_TO_POINTER (token
));
4316 return mono_method_signature_checked (method
, error
);
4319 #ifndef DISABLE_REFLECTION_EMIT
4322 * ensure_complete_type:
4324 * Ensure that KLASS is completed if it is a dynamic type, or references
4328 ensure_complete_type (MonoClass
*klass
, MonoError
*error
)
4330 HANDLE_FUNCTION_ENTER ();
4334 if (image_is_dynamic (klass
->image
) && !klass
->wastypebuilder
&& mono_class_has_ref_info (klass
)) {
4335 #ifndef ENABLE_NETCORE
4336 MonoReflectionTypeBuilderHandle tb
= mono_class_get_ref_info (klass
);
4338 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4339 goto_if_nok (error
, exit
);
4341 // Asserting here could break a lot of code
4342 //g_assert (klass->wastypebuilder);
4344 // TODO: make this work on netcore when working on SRE.TypeBuilder
4345 g_assert_not_reached ();
4349 if (mono_class_is_ginst (klass
)) {
4350 MonoGenericInst
*inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
4353 for (i
= 0; i
< inst
->type_argc
; ++i
) {
4354 ensure_complete_type (mono_class_from_mono_type_internal (inst
->type_argv
[i
]), error
);
4355 goto_if_nok (error
, exit
);
4360 HANDLE_FUNCTION_RETURN ();
4364 mono_reflection_resolve_object (MonoImage
*image
, MonoObject
*obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4366 HANDLE_FUNCTION_ENTER ();
4368 MonoClass
*oklass
= obj
->vtable
->klass
;
4369 gpointer result
= NULL
;
4373 if (strcmp (oklass
->name
, "String") == 0) {
4374 result
= MONO_HANDLE_RAW (mono_string_intern_checked (MONO_HANDLE_NEW (MonoString
, (MonoString
*)obj
), error
));
4375 goto_if_nok (error
, return_null
);
4376 *handle_class
= mono_defaults
.string_class
;
4378 } else if (strcmp (oklass
->name
, "RuntimeType") == 0) {
4379 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
4380 goto_if_nok (error
, return_null
);
4381 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
4382 if (!mono_class_init_internal (mc
)) {
4383 mono_error_set_for_class_failure (error
, mc
);
4388 MonoType
*inflated
= mono_class_inflate_generic_type_checked (type
, context
, error
);
4389 goto_if_nok (error
, return_null
);
4391 result
= mono_class_from_mono_type_internal (inflated
);
4392 mono_metadata_free_type (inflated
);
4394 result
= mono_class_from_mono_type_internal (type
);
4396 *handle_class
= mono_defaults
.typehandle_class
;
4398 } else if (strcmp (oklass
->name
, "RuntimeMethodInfo") == 0 ||
4399 strcmp (oklass
->name
, "RuntimeConstructorInfo") == 0) {
4400 result
= ((MonoReflectionMethod
*)obj
)->method
;
4402 result
= mono_class_inflate_generic_method_checked ((MonoMethod
*)result
, context
, error
);
4403 mono_error_assert_ok (error
);
4405 *handle_class
= mono_defaults
.methodhandle_class
;
4407 } else if (strcmp (oklass
->name
, "RuntimeFieldInfo") == 0) {
4408 MonoClassField
*field
= ((MonoReflectionField
*)obj
)->field
;
4410 ensure_complete_type (field
->parent
, error
);
4411 goto_if_nok (error
, return_null
);
4414 MonoType
*inflated
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (field
->parent
), context
, error
);
4415 goto_if_nok (error
, return_null
);
4418 klass
= mono_class_from_mono_type_internal (inflated
);
4419 MonoClassField
*inflated_field
;
4420 gpointer iter
= NULL
;
4421 mono_metadata_free_type (inflated
);
4422 while ((inflated_field
= mono_class_get_fields_internal (klass
, &iter
))) {
4423 if (!strcmp (field
->name
, inflated_field
->name
))
4426 g_assert (inflated_field
&& !strcmp (field
->name
, inflated_field
->name
));
4427 result
= inflated_field
;
4431 *handle_class
= mono_defaults
.fieldhandle_class
;
4433 } else if (strcmp (oklass
->name
, "TypeBuilder") == 0) {
4434 MonoReflectionTypeBuilderHandle tb
= MONO_HANDLE_NEW (MonoReflectionTypeBuilder
, (MonoReflectionTypeBuilder
*)obj
);
4435 MonoType
*type
= mono_reflection_type_get_handle (&MONO_HANDLE_RAW (tb
)->type
, error
);
4436 goto_if_nok (error
, return_null
);
4439 klass
= type
->data
.klass
;
4440 if (klass
->wastypebuilder
) {
4441 /* Already created */
4444 #ifndef ENABLE_NETCORE
4445 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4446 goto_if_nok (error
, return_null
);
4447 result
= type
->data
.klass
;
4450 // TODO: make this work on netcore when working on SRE.TypeBuilder
4451 g_assert_not_reached();
4455 *handle_class
= mono_defaults
.typehandle_class
;
4456 } else if (strcmp (oklass
->name
, "SignatureHelper") == 0) {
4457 MonoReflectionSigHelper
*helper
= (MonoReflectionSigHelper
*)obj
;
4458 MonoMethodSignature
*sig
;
4461 if (helper
->arguments
)
4462 nargs
= mono_array_length_internal (helper
->arguments
);
4466 sig
= mono_metadata_signature_alloc (image
, nargs
);
4467 sig
->explicit_this
= helper
->call_conv
& 64 ? 1 : 0;
4468 sig
->hasthis
= helper
->call_conv
& 32 ? 1 : 0;
4470 if (helper
->unmanaged_call_conv
) { /* unmanaged */
4471 sig
->call_convention
= helper
->unmanaged_call_conv
- 1;
4472 sig
->pinvoke
= TRUE
;
4473 } else if (helper
->call_conv
& 0x02) {
4474 sig
->call_convention
= MONO_CALL_VARARG
;
4476 sig
->call_convention
= MONO_CALL_DEFAULT
;
4479 sig
->param_count
= nargs
;
4480 /* TODO: Copy type ? */
4481 sig
->ret
= helper
->return_type
->type
;
4482 for (i
= 0; i
< nargs
; ++i
) {
4483 sig
->params
[i
] = mono_type_array_get_and_resolve_raw (helper
->arguments
, i
, error
); /* FIXME use handles */
4484 if (!is_ok (error
)) {
4485 image_g_free (image
, sig
);
4491 *handle_class
= NULL
;
4492 } else if (strcmp (oklass
->name
, "DynamicMethod") == 0) {
4493 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4494 /* Already created by the managed code */
4495 g_assert (method
->mhandle
);
4496 result
= method
->mhandle
;
4497 *handle_class
= mono_defaults
.methodhandle_class
;
4498 } else if (strcmp (oklass
->name
, "MonoArrayMethod") == 0) {
4499 MonoReflectionArrayMethod
*m
= (MonoReflectionArrayMethod
*)obj
;
4506 mtype
= mono_reflection_type_get_handle (m
->parent
, error
);
4507 goto_if_nok (error
, return_null
);
4508 klass
= mono_class_from_mono_type_internal (mtype
);
4510 /* Find the method */
4512 name
= mono_string_to_utf8_checked_internal (m
->name
, error
);
4513 goto_if_nok (error
, return_null
);
4515 while ((method
= mono_class_get_methods (klass
, &iter
))) {
4516 if (!strcmp (method
->name
, name
))
4523 // FIXME: Check parameters/return value etc. match
4526 *handle_class
= mono_defaults
.methodhandle_class
;
4527 } else if (is_sre_method_builder (oklass
) ||
4528 mono_is_sre_ctor_builder (oklass
) ||
4529 is_sre_field_builder (oklass
) ||
4530 is_sre_gparam_builder (oklass
) ||
4531 is_sre_generic_instance (oklass
) ||
4532 is_sre_array (oklass
) ||
4533 is_sre_byref (oklass
) ||
4534 is_sre_pointer (oklass
) ||
4535 !strcmp (oklass
->name
, "FieldOnTypeBuilderInst") ||
4536 !strcmp (oklass
->name
, "MethodOnTypeBuilderInst") ||
4537 !strcmp (oklass
->name
, "ConstructorOnTypeBuilderInst")) {
4538 static MonoMethod
*resolve_method
;
4539 if (!resolve_method
) {
4540 MonoMethod
*m
= mono_class_get_method_from_name_checked (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0, error
);
4541 mono_error_assert_ok (error
);
4543 mono_memory_barrier ();
4546 void *args
[ ] = { obj
};
4547 obj
= mono_runtime_invoke_checked (resolve_method
, NULL
, args
, error
);
4548 goto_if_nok (error
, return_null
);
4550 result
= mono_reflection_resolve_object (image
, obj
, handle_class
, context
, error
);
4553 g_print ("%s\n", obj
->vtable
->klass
->name
);
4554 g_assert_not_reached ();
4562 HANDLE_FUNCTION_RETURN_VAL (result
);
4566 mono_reflection_resolve_object_handle (MonoImage
*image
, MonoObjectHandle obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4568 return mono_reflection_resolve_object (image
, MONO_HANDLE_RAW (obj
), handle_class
, context
, error
);
4571 #else /* DISABLE_REFLECTION_EMIT */
4574 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4576 g_assert_not_reached ();
4581 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
, MonoError
*error
)
4583 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4587 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4589 g_assert_not_reached ();
4594 mono_image_insert_string (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4596 g_assert_not_reached ();
4601 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
4603 g_assert_not_reached ();
4608 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
4609 gboolean create_open_instance
, gboolean register_token
, MonoError
*error
)
4611 g_assert_not_reached ();
4616 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
4623 MonoReflectionTypeHandle
4624 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
)
4626 g_assert_not_reached ();
4627 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4631 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4637 mono_reflection_type_get_handle (MonoReflectionType
* ref
, MonoError
*error
)
4646 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
4649 if (MONO_HANDLE_IS_NULL (ref
))
4651 return MONO_HANDLE_GETVAL (ref
, type
);
4655 #endif /* DISABLE_REFLECTION_EMIT */
4658 mono_sre_generic_param_table_entry_free (GenericParamTableEntry
*entry
)
4660 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry
->gparam
);
4665 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, MonoBoolean create_open_instance
, MonoError
*error
)
4667 if (MONO_HANDLE_IS_NULL (obj
)) {
4668 mono_error_set_argument_null (error
, "obj", "");
4671 return mono_image_create_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), obj
, create_open_instance
, TRUE
, error
);
4675 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb
,
4676 MonoReflectionMethodHandle method
,
4677 MonoArrayHandle opt_param_types
,
4680 if (MONO_HANDLE_IS_NULL (method
)) {
4681 mono_error_set_argument_null (error
, "method", "");
4685 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), MONO_HANDLE_CAST (MonoObject
, method
), opt_param_types
, error
);
4688 #ifndef ENABLE_NETCORE
4690 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilderHandle mb
, HANDLE file
, MonoError
* error
)
4692 mono_image_create_pefile (MONO_HANDLE_RAW (mb
), file
, error
);
4696 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilderHandle mb
, MonoError
* error
)
4698 mono_image_build_metadata (MONO_HANDLE_RAW (mb
), error
);
4703 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, guint32 token
, MonoError
*error
)
4705 /* This function may be called by ModuleBuilder.FixupTokens to update
4706 * an existing token, so replace is okay here. */
4707 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), token
, obj
, MONO_DYN_IMAGE_TOK_REPLACE
);
4711 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb
, guint32 token
, MonoError
*error
)
4713 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
4714 return mono_dynamic_image_get_registered_token (dynamic_image
, token
, error
);
4717 #ifndef DISABLE_REFLECTION_EMIT
4720 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssemblyHandle assembly
, MonoObjectHandle ctor
,
4721 MonoArrayHandle ctorArgs
, MonoArrayHandle properties
,
4722 MonoArrayHandle propValues
, MonoArrayHandle fields
,
4723 MonoArrayHandle fieldValues
, MonoError
* error
)
4725 return mono_reflection_get_custom_attrs_blob_checked (MONO_HANDLE_RAW (assembly
), MONO_HANDLE_RAW (ctor
),
4726 MONO_HANDLE_RAW (ctorArgs
), MONO_HANDLE_RAW (properties
),
4727 MONO_HANDLE_RAW (propValues
), MONO_HANDLE_RAW (fields
),
4728 MONO_HANDLE_RAW (fieldValues
), error
);
4734 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilderHandle assemblyb
, MonoError
*error
)
4736 MonoGCHandle gchandle
= mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject
, assemblyb
), TRUE
);
4737 mono_reflection_dynimage_basic_init (MONO_HANDLE_RAW (assemblyb
), error
);
4738 mono_gchandle_free_internal (gchandle
);
4742 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb
, MonoError
*error
)
4744 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, assemblyb
, cattrs
);
4746 MonoReflectionAssemblyHandle assembly_handle
= MONO_HANDLE_CAST (MonoReflectionAssembly
, assemblyb
);
4747 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_handle
, assembly
);
4748 g_assert (assembly
);
4750 mono_save_custom_attrs (assembly
->image
, assembly
, MONO_HANDLE_RAW (cattrs
));
4754 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype
,
4755 MonoReflectionTypeHandle t
,
4758 MONO_HANDLE_SETVAL (enumtype
, type
, MonoType
*, MONO_HANDLE_GETVAL (t
, type
));
4762 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4764 mono_image_module_basic_init (moduleb
, error
);
4768 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4770 return mono_image_insert_string (module
, str
, error
);
4774 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb
, MonoReflectionTypeHandle ref_type
, MonoError
*error
)
4776 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
4777 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4780 image
->wrappers_type
= mono_class_from_mono_type_internal (type
);