2 * sre.c: Routines for creating an image at runtime
3 * and related System.Reflection.Emit icalls
7 * Paolo Molaro (lupus@ximian.com)
9 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
11 * Copyright 2011 Rodrigo Kumpera
12 * Copyright 2016 Microsoft
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
18 #include "mono/metadata/assembly.h"
19 #include "mono/metadata/debug-helpers.h"
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/exception.h"
23 #include "mono/metadata/gc-internals.h"
24 #include "mono/metadata/mono-ptr-array.h"
25 #include "mono/metadata/object-internals.h"
26 #include "mono/metadata/profiler-private.h"
27 #include "mono/metadata/reflection-internals.h"
28 #include "mono/metadata/reflection-cache.h"
29 #include "mono/metadata/sre-internals.h"
30 #include "mono/metadata/custom-attrs-internals.h"
31 #include "mono/metadata/security-manager.h"
32 #include "mono/metadata/security-core-clr.h"
33 #include "mono/metadata/tabledefs.h"
34 #include "mono/metadata/tokentype.h"
35 #include "mono/utils/checked-build.h"
36 #include "mono/utils/mono-digest.h"
39 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
41 mono_gc_deregister_root ((char*) &entry->gparam);
47 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
49 #ifndef DISABLE_REFLECTION_EMIT
50 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
51 static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
52 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
53 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
54 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
55 static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
56 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
58 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
61 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
62 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
63 static gboolean is_sre_array (MonoClass *klass);
64 static gboolean is_sre_byref (MonoClass *klass);
65 static gboolean is_sre_pointer (MonoClass *klass);
66 static gboolean is_sre_type_builder (MonoClass *klass);
67 static gboolean is_sre_method_builder (MonoClass *klass);
68 static gboolean is_sre_field_builder (MonoClass *klass);
69 static gboolean is_sr_mono_method (MonoClass *klass);
70 static gboolean is_sr_mono_generic_method (MonoClass *klass);
71 static gboolean is_sr_mono_generic_cmethod (MonoClass *klass);
72 static gboolean is_sr_mono_field (MonoClass *klass);
74 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
75 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
76 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
78 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
80 #define RESOLVE_TYPE(type, error) do { \
81 type = (MonoObject *)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type, error); \
83 #define RESOLVE_ARRAY_TYPE_ELEMENT(array, index, error) do { \
84 MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
85 __type = mono_reflection_type_resolve_user_types (__type, error); \
86 if (mono_error_ok (error)) \
87 mono_array_set (arr, MonoReflectionType*, index, __type); \
90 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
92 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
95 mono_reflection_emit_init (void)
97 mono_dynamic_images_init ();
101 type_get_fully_qualified_name (MonoType *type)
103 MONO_REQ_GC_NEUTRAL_MODE;
105 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
109 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
111 MONO_REQ_GC_UNSAFE_MODE;
116 klass = mono_class_from_mono_type (type);
118 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
119 ta = klass->image->assembly;
120 if (assembly_is_dynamic (ta) || (ta == ass)) {
121 if (klass->generic_class || klass->generic_container)
122 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
123 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
125 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
128 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
131 #ifndef DISABLE_REFLECTION_EMIT
135 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
139 image_g_malloc (MonoImage *image, guint size)
141 MONO_REQ_GC_NEUTRAL_MODE;
144 return mono_image_alloc (image, size);
146 return g_malloc (size);
148 #endif /* !DISABLE_REFLECTION_EMIT */
153 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
157 mono_image_g_malloc0 (MonoImage *image, guint size)
159 MONO_REQ_GC_NEUTRAL_MODE;
162 return mono_image_alloc0 (image, size);
164 return g_malloc0 (size);
169 * @image: a MonoImage
172 * If @image is NULL, free @ptr, otherwise do nothing.
175 image_g_free (MonoImage *image, gpointer ptr)
181 #ifndef DISABLE_REFLECTION_EMIT
183 image_strdup (MonoImage *image, const char *s)
185 MONO_REQ_GC_NEUTRAL_MODE;
188 return mono_image_strdup (image, s);
194 #define image_g_new(image,struct_type, n_structs) \
195 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
197 #define image_g_new0(image,struct_type, n_structs) \
198 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
202 alloc_table (MonoDynamicTable *table, guint nrows)
204 mono_dynimage_alloc_table (table, nrows);
208 string_heap_insert (MonoDynamicStream *sh, const char *str)
210 return mono_dynstream_insert_string (sh, str);
214 string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
216 return mono_dynstream_insert_mstring (sh, str, error);
220 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
222 return mono_dynstream_add_data (stream, data, len);
226 mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
228 return mono_dynstream_add_zero (stream, len);
232 stream_data_align (MonoDynamicStream *stream)
234 mono_dynstream_data_align (stream);
238 * Despite the name, we handle also TypeSpec (with the above helper).
241 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
243 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
247 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
248 * dest may be misaligned.
251 swap_with_size (char *dest, const char* val, int len, int nelem) {
252 MONO_REQ_GC_NEUTRAL_MODE;
253 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
256 for (elem = 0; elem < nelem; ++elem) {
282 g_assert_not_reached ();
288 memcpy (dest, val, len * nelem);
292 #ifndef DISABLE_REFLECTION_EMIT
294 default_class_from_mono_type (MonoType *type)
296 MONO_REQ_GC_NEUTRAL_MODE;
298 switch (type->type) {
299 case MONO_TYPE_OBJECT:
300 return mono_defaults.object_class;
302 return mono_defaults.void_class;
303 case MONO_TYPE_BOOLEAN:
304 return mono_defaults.boolean_class;
306 return mono_defaults.char_class;
308 return mono_defaults.sbyte_class;
310 return mono_defaults.byte_class;
312 return mono_defaults.int16_class;
314 return mono_defaults.uint16_class;
316 return mono_defaults.int32_class;
318 return mono_defaults.uint32_class;
320 return mono_defaults.int_class;
322 return mono_defaults.uint_class;
324 return mono_defaults.int64_class;
326 return mono_defaults.uint64_class;
328 return mono_defaults.single_class;
330 return mono_defaults.double_class;
331 case MONO_TYPE_STRING:
332 return mono_defaults.string_class;
334 g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
335 g_assert_not_reached ();
343 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
345 MONO_REQ_GC_UNSAFE_MODE;
347 guint32 num_clauses = 0;
350 MonoILExceptionInfo *ex_info;
351 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
352 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
353 if (ex_info->handlers)
354 num_clauses += mono_array_length (ex_info->handlers);
362 #ifndef DISABLE_REFLECTION_EMIT
363 static MonoExceptionClause*
364 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
366 MONO_REQ_GC_UNSAFE_MODE;
368 mono_error_init (error);
370 MonoExceptionClause *clauses;
371 MonoExceptionClause *clause;
372 MonoILExceptionInfo *ex_info;
373 MonoILExceptionBlock *ex_block;
374 guint32 finally_start;
375 int i, j, clause_index;;
377 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
380 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
381 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
382 finally_start = ex_info->start + ex_info->len;
383 if (!ex_info->handlers)
385 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
386 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
387 clause = &(clauses [clause_index]);
389 clause->flags = ex_block->type;
390 clause->try_offset = ex_info->start;
392 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
393 clause->try_len = finally_start - ex_info->start;
395 clause->try_len = ex_info->len;
396 clause->handler_offset = ex_block->start;
397 clause->handler_len = ex_block->len;
398 if (ex_block->extype) {
399 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
401 if (!is_ok (error)) {
402 image_g_free (image, clauses);
405 clause->data.catch_class = mono_class_from_mono_type (extype);
407 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
408 clause->data.filter_offset = ex_block->filter_offset;
410 clause->data.filter_offset = 0;
412 finally_start = ex_block->start + ex_block->len;
420 #endif /* !DISABLE_REFLECTION_EMIT */
422 #ifndef DISABLE_REFLECTION_EMIT
424 * LOCKING: Acquires the loader lock.
427 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
429 MONO_REQ_GC_UNSAFE_MODE;
431 MonoCustomAttrInfo *ainfo, *tmp;
433 if (!cattrs || !mono_array_length (cattrs))
436 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
439 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
441 mono_custom_attrs_free (tmp);
442 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
443 mono_loader_unlock ();
450 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
452 MONO_REQ_GC_UNSAFE_MODE;
454 MonoDynamicTable *table;
457 guint32 cols [MONO_ASSEMBLY_SIZE];
461 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
464 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
465 table = &assembly->tables [MONO_TABLE_MODULEREF];
466 token = table->next_idx ++;
468 alloc_table (table, table->rows);
469 values = table->values + token * MONO_MODULEREF_SIZE;
470 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
472 token <<= MONO_RESOLUTION_SCOPE_BITS;
473 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
474 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
479 if (assembly_is_dynamic (image->assembly))
481 memset (cols, 0, sizeof (cols));
483 /* image->assembly->image is the manifest module */
484 image = image->assembly->image;
485 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
488 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
489 token = table->next_idx ++;
491 alloc_table (table, table->rows);
492 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
493 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
494 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
495 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
496 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
497 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
498 values [MONO_ASSEMBLYREF_FLAGS] = 0;
499 values [MONO_ASSEMBLYREF_CULTURE] = 0;
500 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
502 if (strcmp ("", image->assembly->aname.culture)) {
503 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
504 image->assembly->aname.culture);
507 if ((pubkey = mono_image_get_public_key (image, &publen))) {
510 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
511 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
513 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
515 token <<= MONO_RESOLUTION_SCOPE_BITS;
516 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
517 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
521 #ifndef DISABLE_REFLECTION_EMIT
523 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
525 MONO_REQ_GC_UNSAFE_MODE;
527 mono_error_init (error);
528 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
530 rmb->ilgen = mb->ilgen;
531 rmb->rtype = mono_reflection_type_resolve_user_types ((MonoReflectionType*)mb->rtype, error);
532 return_val_if_nok (error, FALSE);
533 rmb->parameters = mb->parameters;
534 rmb->generic_params = mb->generic_params;
535 rmb->generic_container = mb->generic_container;
536 rmb->opt_types = NULL;
537 rmb->pinfo = mb->pinfo;
538 rmb->attrs = mb->attrs;
539 rmb->iattrs = mb->iattrs;
540 rmb->call_conv = mb->call_conv;
541 rmb->code = mb->code;
542 rmb->type = mb->type;
543 rmb->name = mb->name;
544 rmb->table_idx = &mb->table_idx;
545 rmb->init_locals = mb->init_locals;
546 rmb->skip_visibility = FALSE;
547 rmb->return_modreq = mb->return_modreq;
548 rmb->return_modopt = mb->return_modopt;
549 rmb->param_modreq = mb->param_modreq;
550 rmb->param_modopt = mb->param_modopt;
551 rmb->permissions = mb->permissions;
552 rmb->mhandle = mb->mhandle;
557 rmb->charset = mb->charset;
558 rmb->extra_flags = mb->extra_flags;
559 rmb->native_cc = mb->native_cc;
560 rmb->dllentry = mb->dllentry;
568 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
570 MONO_REQ_GC_UNSAFE_MODE;
572 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
574 mono_error_init (error);
576 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
578 rmb->ilgen = mb->ilgen;
579 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
580 return_val_if_nok (error, FALSE);
581 rmb->parameters = mb->parameters;
582 rmb->generic_params = NULL;
583 rmb->generic_container = NULL;
584 rmb->opt_types = NULL;
585 rmb->pinfo = mb->pinfo;
586 rmb->attrs = mb->attrs;
587 rmb->iattrs = mb->iattrs;
588 rmb->call_conv = mb->call_conv;
590 rmb->type = mb->type;
591 rmb->name = mono_string_new (mono_domain_get (), name);
592 rmb->table_idx = &mb->table_idx;
593 rmb->init_locals = mb->init_locals;
594 rmb->skip_visibility = FALSE;
595 rmb->return_modreq = NULL;
596 rmb->return_modopt = NULL;
597 rmb->param_modreq = mb->param_modreq;
598 rmb->param_modopt = mb->param_modopt;
599 rmb->permissions = mb->permissions;
600 rmb->mhandle = mb->mhandle;
608 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
610 MONO_REQ_GC_UNSAFE_MODE;
612 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
614 rmb->ilgen = mb->ilgen;
615 rmb->rtype = mb->rtype;
616 rmb->parameters = mb->parameters;
617 rmb->generic_params = NULL;
618 rmb->generic_container = NULL;
619 rmb->opt_types = NULL;
621 rmb->attrs = mb->attrs;
623 rmb->call_conv = mb->call_conv;
625 rmb->type = (MonoObject *) mb->owner;
626 rmb->name = mb->name;
627 rmb->table_idx = NULL;
628 rmb->init_locals = mb->init_locals;
629 rmb->skip_visibility = mb->skip_visibility;
630 rmb->return_modreq = NULL;
631 rmb->return_modopt = NULL;
632 rmb->param_modreq = NULL;
633 rmb->param_modopt = NULL;
634 rmb->permissions = NULL;
635 rmb->mhandle = mb->mhandle;
639 #else /* DISABLE_REFLECTION_EMIT */
641 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
642 g_assert_not_reached ();
646 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
648 g_assert_not_reached ();
651 #endif /* DISABLE_REFLECTION_EMIT */
653 #ifndef DISABLE_REFLECTION_EMIT
655 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
657 MONO_REQ_GC_NEUTRAL_MODE;
659 MonoDynamicTable *table;
661 guint32 token, pclass;
663 switch (parent & MONO_TYPEDEFORREF_MASK) {
664 case MONO_TYPEDEFORREF_TYPEREF:
665 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
667 case MONO_TYPEDEFORREF_TYPESPEC:
668 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
670 case MONO_TYPEDEFORREF_TYPEDEF:
671 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
674 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
677 /* extract the index */
678 parent >>= MONO_TYPEDEFORREF_BITS;
680 table = &assembly->tables [MONO_TABLE_MEMBERREF];
682 if (assembly->save) {
683 alloc_table (table, table->rows + 1);
684 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
685 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
686 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
687 values [MONO_MEMBERREF_SIGNATURE] = sig;
690 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
697 * Insert a memberef row into the metadata: the token that point to the memberref
698 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
699 * mono_image_get_fieldref_token()).
700 * The sig param is an index to an already built signature.
703 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
705 MONO_REQ_GC_NEUTRAL_MODE;
707 guint32 parent = mono_image_typedef_or_ref (assembly, type);
708 return mono_image_add_memberef_row (assembly, parent, name, sig);
713 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
715 MONO_REQ_GC_NEUTRAL_MODE;
718 MonoMethodSignature *sig;
720 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
722 if (create_typespec) {
723 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
728 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
729 if (token && !create_typespec)
732 g_assert (!method->is_inflated);
735 * A methodref signature can't contain an unmanaged calling convention.
737 sig = mono_metadata_signature_dup (mono_method_signature (method));
738 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
739 sig->call_convention = MONO_CALL_DEFAULT;
740 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
741 method->name, mono_dynimage_encode_method_signature (assembly, sig));
743 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
746 if (create_typespec) {
747 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
748 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
749 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
751 if (assembly->save) {
754 alloc_table (table, table->rows + 1);
755 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
756 values [MONO_METHODSPEC_METHOD] = token;
757 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
760 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
762 /*methodspec and memberef tokens are diferent, */
763 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
770 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
772 guint32 token, parent, sig;
773 ReflectionMethodBuilder rmb;
774 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
776 mono_error_init (error);
777 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
781 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
785 * A methodref signature can't contain an unmanaged calling convention.
786 * Since some flags are encoded as part of call_conv, we need to check against it.
788 if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
789 rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
791 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
792 return_val_if_nok (error, 0);
794 if (tb->generic_params) {
795 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
796 return_val_if_nok (error, 0);
798 MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
799 return_val_if_nok (error, 0);
801 parent = mono_image_typedef_or_ref (assembly, t);
804 char *name = mono_string_to_utf8_checked (method->name, error);
805 return_val_if_nok (error, 0);
807 token = mono_image_add_memberef_row (assembly, parent, name, sig);
810 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
816 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
817 const gchar *name, guint32 sig)
819 MonoDynamicTable *table;
823 table = &assembly->tables [MONO_TABLE_MEMBERREF];
825 if (assembly->save) {
826 alloc_table (table, table->rows + 1);
827 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
828 values [MONO_MEMBERREF_CLASS] = original;
829 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
830 values [MONO_MEMBERREF_SIGNATURE] = sig;
833 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
840 mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
842 MonoDynamicTable *table;
844 guint32 token, mtoken = 0;
846 mono_error_init (error);
847 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
851 table = &assembly->tables [MONO_TABLE_METHODSPEC];
853 mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
854 if (!mono_error_ok (error))
857 switch (mono_metadata_token_table (mtoken)) {
858 case MONO_TABLE_MEMBERREF:
859 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
861 case MONO_TABLE_METHOD:
862 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
865 g_assert_not_reached ();
868 if (assembly->save) {
869 alloc_table (table, table->rows + 1);
870 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
871 values [MONO_METHODSPEC_METHOD] = mtoken;
872 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
875 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
878 mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
883 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
887 mono_error_init (error);
889 if (mb->generic_params && create_methodspec)
890 return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
892 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
896 token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
897 if (!mono_error_ok (error))
899 mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
904 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
906 guint32 token, parent, sig;
907 ReflectionMethodBuilder rmb;
909 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
911 mono_error_init (error);
913 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
917 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
920 if (tb->generic_params) {
921 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
922 return_val_if_nok (error, 0);
924 MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
925 return_val_if_nok (error, 0);
926 parent = mono_image_typedef_or_ref (assembly, type);
929 name = mono_string_to_utf8_checked (rmb.name, error);
930 return_val_if_nok (error, 0);
931 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
932 return_val_if_nok (error, 0);
934 token = mono_image_add_memberef_row (assembly, parent, name, sig);
937 mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
943 is_field_on_inst (MonoClassField *field)
945 return field->parent->generic_class && field->parent->generic_class->is_dynamic;
948 #ifndef DISABLE_REFLECTION_EMIT
950 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
956 g_assert (field->parent);
958 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
962 if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
963 int index = field - field->parent->fields;
964 type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
966 type = mono_field_get_type (field);
968 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
969 mono_field_get_name (field),
970 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
971 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
976 mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
980 MonoGenericClass *gclass;
984 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
987 if (is_sre_field_builder (mono_object_class (f->fb))) {
988 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
989 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
990 return_val_if_nok (error, 0);
991 klass = mono_class_from_mono_type (type);
992 gclass = type->data.generic_class;
993 g_assert (gclass->is_dynamic);
995 guint32 sig_token = mono_dynimage_encode_field_signature (assembly, fb, error);
996 return_val_if_nok (error, 0);
997 name = mono_string_to_utf8_checked (fb->name, error);
998 return_val_if_nok (error, 0);
999 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
1001 } else if (is_sr_mono_field (mono_object_class (f->fb))) {
1003 MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
1005 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
1006 return_val_if_nok (error, 0);
1007 klass = mono_class_from_mono_type (type);
1009 sig = mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, field->type);
1010 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
1012 char *name = mono_type_get_full_name (mono_object_class (f->fb));
1013 g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
1016 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
1021 mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
1025 MonoGenericClass *gclass;
1028 mono_error_init (error);
1030 /* A ctor cannot be a generic method, so we can ignore create_methodspec */
1032 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
1036 if (mono_is_sre_ctor_builder (mono_object_class (c->cb))) {
1037 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
1038 ReflectionMethodBuilder rmb;
1041 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
1042 return_val_if_nok (error, 0);
1043 klass = mono_class_from_mono_type (type);
1045 gclass = type->data.generic_class;
1046 g_assert (gclass->is_dynamic);
1048 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
1051 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1052 return_val_if_nok (error, 0);
1054 name = mono_string_to_utf8_checked (rmb.name, error);
1055 return_val_if_nok (error, 0);
1057 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1059 } else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb))) {
1060 MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
1062 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
1063 return_val_if_nok (error, 0);
1064 klass = mono_class_from_mono_type (type);
1066 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1067 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1069 char *name = mono_type_get_full_name (mono_object_class (c->cb));
1070 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1074 mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
1079 mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
1082 MonoGenericContext tmp_context;
1083 MonoType **type_argv;
1084 MonoGenericInst *ginst;
1085 MonoMethod *method, *inflated;
1088 mono_error_init (error);
1090 mono_reflection_init_type_builder_generics ((MonoObject*)m->inst, error);
1091 return_val_if_nok (error, NULL);
1093 method = inflate_method (m->inst, (MonoObject*)m->mb, error);
1094 return_val_if_nok (error, NULL);
1096 klass = method->klass;
1098 if (m->method_args == NULL)
1101 if (method->is_inflated)
1102 method = ((MonoMethodInflated *) method)->declaring;
1104 count = mono_array_length (m->method_args);
1106 type_argv = g_new0 (MonoType *, count);
1107 for (i = 0; i < count; i++) {
1108 MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
1109 type_argv [i] = mono_reflection_type_get_handle (garg, error);
1110 return_val_if_nok (error, NULL);
1112 ginst = mono_metadata_get_generic_inst (count, type_argv);
1115 tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
1116 tmp_context.method_inst = ginst;
1118 inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
1119 mono_error_assert_ok (error);
1124 mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
1126 guint32 sig, token = 0;
1130 mono_error_init (error);
1132 if (m->method_args) {
1133 MonoMethod *inflated;
1135 inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
1136 return_val_if_nok (error, 0);
1138 if (create_methodspec)
1139 token = mono_image_get_methodspec_token (assembly, inflated);
1141 token = mono_image_get_inflated_method_token (assembly, inflated);
1145 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
1149 if (is_sre_method_builder (mono_object_class (m->mb))) {
1150 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
1151 MonoGenericClass *gclass;
1152 ReflectionMethodBuilder rmb;
1155 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1156 return_val_if_nok (error, 0);
1157 klass = mono_class_from_mono_type (type);
1158 gclass = type->data.generic_class;
1159 g_assert (gclass->is_dynamic);
1161 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1164 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1165 return_val_if_nok (error, 0);
1167 name = mono_string_to_utf8_checked (rmb.name, error);
1168 return_val_if_nok (error, 0);
1170 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1172 } else if (is_sr_mono_method (mono_object_class (m->mb))) {
1173 MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
1175 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1176 return_val_if_nok (error, 0);
1177 klass = mono_class_from_mono_type (type);
1179 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1180 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1182 char *name = mono_type_get_full_name (mono_object_class (m->mb));
1183 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1186 mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
1191 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
1193 MonoDynamicTable *table;
1195 guint32 token, mtoken = 0, sig;
1196 MonoMethodInflated *imethod;
1197 MonoMethod *declaring;
1199 table = &assembly->tables [MONO_TABLE_METHODSPEC];
1201 g_assert (method->is_inflated);
1202 imethod = (MonoMethodInflated *) method;
1203 declaring = imethod->declaring;
1205 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
1206 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
1208 if (!mono_method_signature (declaring)->generic_param_count)
1211 switch (mono_metadata_token_table (mtoken)) {
1212 case MONO_TABLE_MEMBERREF:
1213 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
1215 case MONO_TABLE_METHOD:
1216 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
1219 g_assert_not_reached ();
1222 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
1224 if (assembly->save) {
1225 alloc_table (table, table->rows + 1);
1226 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
1227 values [MONO_METHODSPEC_METHOD] = mtoken;
1228 values [MONO_METHODSPEC_SIGNATURE] = sig;
1231 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
1238 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
1240 MonoMethodInflated *imethod;
1243 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
1247 g_assert (method->is_inflated);
1248 imethod = (MonoMethodInflated *) method;
1250 if (mono_method_signature (imethod->declaring)->generic_param_count) {
1251 token = method_encode_methodspec (assembly, method);
1253 guint32 sig = mono_dynimage_encode_method_signature (
1254 assembly, mono_method_signature (imethod->declaring));
1255 token = mono_image_get_memberref_token (
1256 assembly, &method->klass->byval_arg, method->name, sig);
1259 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
1264 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
1266 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
1269 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
1270 token = mono_image_get_memberref_token (
1271 assembly, &m->klass->byval_arg, m->name, sig);
1277 * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
1280 add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
1282 int i, count, len, pos;
1285 mono_error_init (error);
1289 count += mono_array_length (modreq);
1291 count += mono_array_length (modopt);
1294 return mono_metadata_type_dup (NULL, type);
1296 len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
1297 t = (MonoType *)g_malloc (len);
1298 memcpy (t, type, MONO_SIZEOF_TYPE);
1300 t->num_mods = count;
1303 for (i = 0; i < mono_array_length (modreq); ++i) {
1304 MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
1307 t->modifiers [pos].required = 1;
1308 t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1313 for (i = 0; i < mono_array_length (modopt); ++i) {
1314 MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
1317 t->modifiers [pos].required = 0;
1318 t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1330 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
1332 MonoReflectionTypeBuilder *tb;
1334 mono_error_init (error);
1336 if (!is_sre_type_builder(mono_object_class (type)))
1338 tb = (MonoReflectionTypeBuilder *)type;
1340 if (tb && tb->generic_container)
1341 mono_reflection_create_generic_class (tb, error);
1345 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
1347 MonoDynamicTable *table;
1348 MonoType *custom = NULL, *type;
1350 guint32 token, pclass, parent, sig;
1353 mono_error_init (error);
1355 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
1359 MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
1360 return_val_if_nok (error, 0);
1361 /* FIXME: is this call necessary? */
1362 mono_class_from_mono_type (typeb);
1364 /*FIXME this is one more layer of ugliness due how types are created.*/
1365 mono_reflection_init_type_builder_generics (fb->type, error);
1366 return_val_if_nok (error, 0);
1368 /* fb->type does not include the custom modifiers */
1369 /* FIXME: We should do this in one place when a fieldbuilder is created */
1370 type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1371 return_val_if_nok (error, 0);
1373 if (fb->modreq || fb->modopt) {
1374 type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
1375 return_val_if_nok (error, 0);
1378 sig = mono_dynimage_encode_fieldref_signature (assembly, NULL, type);
1381 parent = mono_dynimage_encode_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
1382 return_val_if_nok (error, 0);
1383 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
1385 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
1386 parent >>= MONO_TYPEDEFORREF_BITS;
1388 table = &assembly->tables [MONO_TABLE_MEMBERREF];
1390 name = mono_string_to_utf8_checked (fb->name, error);
1391 return_val_if_nok (error, 0);
1393 if (assembly->save) {
1394 alloc_table (table, table->rows + 1);
1395 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
1396 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
1397 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
1398 values [MONO_MEMBERREF_SIGNATURE] = sig;
1401 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
1403 mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
1409 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
1412 MonoDynamicTable *table;
1415 mono_error_init (error);
1417 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
1418 idx = table->next_idx ++;
1420 alloc_table (table, table->rows);
1421 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
1423 values [MONO_STAND_ALONE_SIGNATURE] =
1424 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
1425 return_val_if_nok (error, 0);
1431 reflection_cc_to_file (int call_conv) {
1432 switch (call_conv & 0x3) {
1434 case 1: return MONO_CALL_DEFAULT;
1435 case 2: return MONO_CALL_VARARG;
1437 g_assert_not_reached ();
1441 #endif /* !DISABLE_REFLECTION_EMIT */
1443 struct _ArrayMethod {
1445 MonoMethodSignature *sig;
1451 mono_sre_array_method_free (ArrayMethod *am)
1458 #ifndef DISABLE_REFLECTION_EMIT
1460 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
1465 MonoMethodSignature *sig;
1466 ArrayMethod *am = NULL;
1469 mono_error_init (error);
1471 nparams = mono_array_length (m->parameters);
1472 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
1474 sig->sentinelpos = -1;
1475 sig->call_convention = reflection_cc_to_file (m->call_conv);
1476 sig->param_count = nparams;
1478 sig->ret = mono_reflection_type_get_handle (m->ret, error);
1482 sig->ret = &mono_defaults.void_class->byval_arg;
1484 mtype = mono_reflection_type_get_handle (m->parent, error);
1488 for (i = 0; i < nparams; ++i) {
1489 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
1494 name = mono_string_to_utf8_checked (m->name, error);
1497 for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
1498 am = (ArrayMethod *)tmp->data;
1499 if (strcmp (name, am->name) == 0 &&
1500 mono_metadata_type_equal (am->parent, mtype) &&
1501 mono_metadata_signature_equal (am->sig, sig)) {
1504 m->table_idx = am->token & 0xffffff;
1508 am = g_new0 (ArrayMethod, 1);
1512 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
1513 mono_dynimage_encode_method_signature (assembly, sig));
1514 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
1515 m->table_idx = am->token & 0xffffff;
1526 #ifndef DISABLE_REFLECTION_EMIT
1529 * mono_image_insert_string:
1530 * @module: module builder object
1533 * Insert @str into the user string stream of @module.
1536 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
1538 MonoDynamicImage *assembly;
1543 if (!module->dynamic_image)
1544 mono_image_module_basic_init (module);
1546 assembly = module->dynamic_image;
1548 if (assembly->save) {
1549 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
1550 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1551 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1553 char *swapped = g_malloc (2 * mono_string_length (str));
1554 const char *p = (const char*)mono_string_chars (str);
1556 swap_with_size (swapped, p, 2, mono_string_length (str));
1557 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
1561 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
1563 mono_image_add_stream_data (&assembly->us, "", 1);
1565 idx = assembly->us.index ++;
1568 mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
1570 return MONO_TOKEN_STRING | idx;
1574 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
1578 MonoMethodSignature *sig;
1580 mono_error_init (error);
1582 klass = obj->vtable->klass;
1583 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1584 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1585 MonoMethodSignature *old;
1586 guint32 sig_token, parent;
1589 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1591 nargs = mono_array_length (opt_param_types);
1592 old = mono_method_signature (method);
1593 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1595 sig->hasthis = old->hasthis;
1596 sig->explicit_this = old->explicit_this;
1597 sig->call_convention = old->call_convention;
1598 sig->generic_param_count = old->generic_param_count;
1599 sig->param_count = old->param_count + nargs;
1600 sig->sentinelpos = old->param_count;
1601 sig->ret = old->ret;
1603 for (i = 0; i < old->param_count; i++)
1604 sig->params [i] = old->params [i];
1606 for (i = 0; i < nargs; i++) {
1607 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1608 sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1609 if (!is_ok (error)) goto fail;
1612 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1613 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1614 parent >>= MONO_TYPEDEFORREF_BITS;
1616 parent <<= MONO_MEMBERREF_PARENT_BITS;
1617 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1619 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1620 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1621 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1622 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1623 ReflectionMethodBuilder rmb;
1624 guint32 parent, sig_token;
1625 int nopt_args, nparams, ngparams, i;
1627 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1630 rmb.opt_types = opt_param_types;
1631 nopt_args = mono_array_length (opt_param_types);
1633 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1634 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1635 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1637 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1638 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1639 sig->call_convention = rmb.call_conv;
1640 sig->generic_param_count = ngparams;
1641 sig->param_count = nparams + nopt_args;
1642 sig->sentinelpos = nparams;
1643 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1644 if (!is_ok (error)) goto fail;
1646 for (i = 0; i < nparams; i++) {
1647 MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1648 sig->params [i] = mono_reflection_type_get_handle (rt, error);
1649 if (!is_ok (error)) goto fail;
1652 for (i = 0; i < nopt_args; i++) {
1653 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1654 sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1655 if (!is_ok (error)) goto fail;
1658 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1662 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1663 if (!mono_error_ok (error))
1665 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1667 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1668 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1670 char *name = mono_string_to_utf8_checked (rmb.name, error);
1671 if (!is_ok (error)) goto fail;
1672 token = mono_image_get_varargs_method_token (
1673 assembly, parent, name, sig_token);
1676 g_error ("requested method token for %s\n", klass->name);
1679 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1680 mono_dynamic_image_register_token (assembly, token, obj);
1683 g_assert (!mono_error_ok (error));
1688 * mono_image_create_token:
1689 * @assembly: a dynamic assembly
1691 * @register_token: Whenever to register the token in the assembly->tokens hash.
1693 * Get a token to insert in the IL code stream for the given MemberInfo.
1694 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1695 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1699 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
1700 gboolean create_open_instance, gboolean register_token,
1706 mono_error_init (error);
1708 klass = obj->vtable->klass;
1710 /* Check for user defined reflection objects */
1711 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1712 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1713 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1717 if (strcmp (klass->name, "MethodBuilder") == 0) {
1718 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1719 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1721 if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
1722 token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1724 token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
1725 if (!mono_error_ok (error))
1728 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1729 } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
1730 MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
1731 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1733 if (tb->module->dynamic_image == assembly && !tb->generic_params)
1734 token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1736 token = mono_image_get_ctorbuilder_token (assembly, mb, error);
1737 if (!mono_error_ok (error))
1740 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1741 } else if (strcmp (klass->name, "FieldBuilder") == 0) {
1742 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
1743 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
1744 if (tb->generic_params) {
1745 token = mono_image_get_generic_field_token (assembly, fb, error);
1746 return_val_if_nok (error, 0);
1748 if (tb->module->dynamic_image == assembly) {
1749 token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
1751 token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
1754 } else if (strcmp (klass->name, "TypeBuilder") == 0) {
1755 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
1756 if (create_open_instance && tb->generic_params) {
1758 mono_reflection_init_type_builder_generics (obj, error);
1759 return_val_if_nok (error, 0);
1760 type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1761 return_val_if_nok (error, 0);
1762 token = mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
1763 token = mono_metadata_token_from_dor (token);
1764 } else if (tb->module->dynamic_image == assembly) {
1765 token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
1768 type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1769 return_val_if_nok (error, 0);
1770 token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
1772 } else if (strcmp (klass->name, "RuntimeType") == 0) {
1773 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1774 return_val_if_nok (error, 0);
1775 MonoClass *mc = mono_class_from_mono_type (type);
1776 token = mono_metadata_token_from_dor (
1777 mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
1778 } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
1779 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1780 return_val_if_nok (error, 0);
1781 token = mono_metadata_token_from_dor (
1782 mono_image_typedef_or_ref (assembly, type));
1783 } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
1784 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1785 return_val_if_nok (error, 0);
1786 token = mono_metadata_token_from_dor (
1787 mono_image_typedef_or_ref (assembly, type));
1788 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1789 strcmp (klass->name, "MonoMethod") == 0 ||
1790 strcmp (klass->name, "MonoGenericMethod") == 0 ||
1791 strcmp (klass->name, "MonoGenericCMethod") == 0) {
1792 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1793 if (m->method->is_inflated) {
1794 if (create_open_instance)
1795 token = mono_image_get_methodspec_token (assembly, m->method);
1797 token = mono_image_get_inflated_method_token (assembly, m->method);
1798 } else if ((m->method->klass->image == &assembly->image) &&
1799 !m->method->klass->generic_class) {
1800 static guint32 method_table_idx = 0xffffff;
1801 if (m->method->klass->wastypebuilder) {
1802 /* we use the same token as the one that was assigned
1803 * to the Methodbuilder.
1804 * FIXME: do the equivalent for Fields.
1806 token = m->method->token;
1809 * Each token should have a unique index, but the indexes are
1810 * assigned by managed code, so we don't know about them. An
1811 * easy solution is to count backwards...
1813 method_table_idx --;
1814 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1817 token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1819 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1820 } else if (strcmp (klass->name, "MonoField") == 0) {
1821 MonoReflectionField *f = (MonoReflectionField *)obj;
1822 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1823 static guint32 field_table_idx = 0xffffff;
1825 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1827 token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1829 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1830 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1831 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1832 token = mono_image_get_array_token (assembly, m, error);
1833 return_val_if_nok (error, 0);
1834 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1835 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1836 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1837 return_val_if_nok (error, 0);
1838 } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1839 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1840 return_val_if_nok (error, 0);
1841 token = mono_metadata_token_from_dor (
1842 mono_image_typedef_or_ref (assembly, type));
1843 } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
1844 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
1845 token = mono_image_get_field_on_inst_token (assembly, f, error);
1846 return_val_if_nok (error, 0);
1847 } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
1848 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
1849 token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
1850 if (!mono_error_ok (error))
1852 } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
1853 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
1854 token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
1855 if (!mono_error_ok (error))
1857 } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
1858 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1859 return_val_if_nok (error, 0);
1860 token = mono_metadata_token_from_dor (
1861 mono_image_typedef_or_ref (assembly, type));
1863 g_error ("requested token for %s\n", klass->name);
1867 mono_image_register_token (assembly, token, obj);
1875 #ifndef DISABLE_REFLECTION_EMIT
1878 * mono_reflection_dynimage_basic_init:
1879 * @assembly: an assembly builder object
1881 * Create the MonoImage that represents the assembly builder and setup some
1882 * of the helper hash table and the basic metadata streams.
1885 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1888 MonoDynamicAssembly *assembly;
1889 MonoDynamicImage *image;
1890 MonoDomain *domain = mono_object_domain (assemblyb);
1892 if (assemblyb->dynamic_assembly)
1896 /* assembly->assembly.image might be GC allocated */
1897 assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1899 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1902 mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1904 assembly->assembly.ref_count = 1;
1905 assembly->assembly.dynamic = TRUE;
1906 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1907 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1908 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1909 if (mono_error_set_pending_exception (&error))
1911 if (assemblyb->culture) {
1912 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1913 if (mono_error_set_pending_exception (&error))
1916 assembly->assembly.aname.culture = g_strdup ("");
1918 if (assemblyb->version) {
1919 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1920 if (mono_error_set_pending_exception (&error))
1922 char **version = g_strsplit (vstr, ".", 4);
1923 char **parts = version;
1924 assembly->assembly.aname.major = atoi (*parts++);
1925 assembly->assembly.aname.minor = atoi (*parts++);
1926 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1927 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1929 g_strfreev (version);
1932 assembly->assembly.aname.major = 0;
1933 assembly->assembly.aname.minor = 0;
1934 assembly->assembly.aname.build = 0;
1935 assembly->assembly.aname.revision = 0;
1938 assembly->run = assemblyb->access != 2;
1939 assembly->save = assemblyb->access != 1;
1940 assembly->domain = domain;
1942 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1943 if (mono_error_set_pending_exception (&error))
1945 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1946 image->initial_image = TRUE;
1947 assembly->assembly.aname.name = image->image.name;
1948 assembly->assembly.image = &image->image;
1949 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1950 /* -1 to correct for the trailing NULL byte */
1951 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1952 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1954 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1957 mono_domain_assemblies_lock (domain);
1958 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1959 mono_domain_assemblies_unlock (domain);
1961 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1963 mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1965 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1968 #endif /* !DISABLE_REFLECTION_EMIT */
1970 #ifndef DISABLE_REFLECTION_EMIT
1972 MonoReflectionModule *
1973 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
1977 MonoImageOpenStatus status;
1978 MonoDynamicAssembly *assembly;
1979 guint32 module_count;
1980 MonoImage **new_modules;
1981 gboolean *new_modules_loaded;
1983 mono_error_init (error);
1985 name = mono_string_to_utf8_checked (fileName, error);
1986 return_val_if_nok (error, NULL);
1988 image = mono_image_open (name, &status);
1990 if (status == MONO_IMAGE_ERROR_ERRNO)
1991 mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
1993 mono_error_set_bad_image_name (error, name, NULL);
2000 assembly = ab->dynamic_assembly;
2001 image->assembly = (MonoAssembly*)assembly;
2003 module_count = image->assembly->image->module_count;
2004 new_modules = g_new0 (MonoImage *, module_count + 1);
2005 new_modules_loaded = g_new0 (gboolean, module_count + 1);
2007 if (image->assembly->image->modules)
2008 memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
2009 if (image->assembly->image->modules_loaded)
2010 memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
2011 new_modules [module_count] = image;
2012 new_modules_loaded [module_count] = TRUE;
2013 mono_image_addref (image);
2015 g_free (image->assembly->image->modules);
2016 image->assembly->image->modules = new_modules;
2017 image->assembly->image->modules_loaded = new_modules_loaded;
2018 image->assembly->image->module_count ++;
2020 mono_assembly_load_references (image, &status);
2022 mono_image_close (image);
2023 mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
2027 return mono_module_get_object_checked (mono_domain_get (), image, error);
2030 #endif /* DISABLE_REFLECTION_EMIT */
2032 #ifndef DISABLE_REFLECTION_EMIT
2034 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
2036 CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
2040 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
2042 CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
2046 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
2048 MonoDynamicImage *image = moduleb->dynamic_image;
2049 MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
2050 mono_error_init (error);
2053 MonoImage **new_modules;
2055 char *name, *fqname;
2057 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
2058 * we don't know which module it belongs to, since that is only
2059 * determined at assembly save time.
2061 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
2062 name = mono_string_to_utf8_checked (ab->name, error);
2063 return_val_if_nok (error, FALSE);
2064 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
2065 if (!is_ok (error)) {
2069 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
2071 moduleb->module.image = &image->image;
2072 moduleb->dynamic_image = image;
2073 register_module (mono_object_domain (moduleb), moduleb, image);
2075 /* register the module with the assembly */
2076 ass = ab->dynamic_assembly->assembly.image;
2077 module_count = ass->module_count;
2078 new_modules = g_new0 (MonoImage *, module_count + 1);
2081 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
2082 new_modules [module_count] = &image->image;
2083 mono_image_addref (&image->image);
2085 g_free (ass->modules);
2086 ass->modules = new_modules;
2087 ass->module_count ++;
2093 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
2096 (void) image_module_basic_init (moduleb, &error);
2097 mono_error_set_pending_exception (&error);
2103 is_corlib_type (MonoClass *klass)
2105 return klass->image == mono_defaults.corlib;
2108 #define check_corlib_type_cached(_class, _namespace, _name) do { \
2109 static MonoClass *cached_class; \
2111 return cached_class == _class; \
2112 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
2113 cached_class = _class; \
2121 #ifndef DISABLE_REFLECTION_EMIT
2123 is_sre_array (MonoClass *klass)
2125 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
2129 is_sre_byref (MonoClass *klass)
2131 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
2135 is_sre_pointer (MonoClass *klass)
2137 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
2141 is_sre_generic_instance (MonoClass *klass)
2143 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
2147 is_sre_type_builder (MonoClass *klass)
2149 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
2153 is_sre_method_builder (MonoClass *klass)
2155 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
2159 mono_is_sre_ctor_builder (MonoClass *klass)
2161 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
2165 is_sre_field_builder (MonoClass *klass)
2167 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
2171 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2173 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
2177 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2179 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
2182 static MonoReflectionType*
2183 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
2185 static MonoMethod *method_get_underlying_system_type = NULL;
2186 MonoReflectionType *rt;
2187 MonoMethod *usertype_method;
2189 mono_error_init (error);
2191 if (!method_get_underlying_system_type)
2192 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
2194 usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
2196 rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
2202 mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error)
2204 mono_error_init (error);
2205 if (!type || type->type)
2208 if (mono_reflection_is_usertype (type)) {
2209 type = mono_reflection_type_get_underlying_system_type (type, error);
2210 return_val_if_nok (error, NULL);
2211 if (mono_reflection_is_usertype (type)) {
2212 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
2222 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
2225 mono_error_init (error);
2232 if (mono_reflection_is_usertype (ref)) {
2233 ref = mono_reflection_type_get_underlying_system_type (ref, error);
2234 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
2240 klass = mono_object_class (ref);
2242 if (is_sre_array (klass)) {
2244 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
2245 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
2246 return_val_if_nok (error, NULL);
2248 if (sre_array->rank == 0) //single dimentional array
2249 res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
2251 res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
2252 sre_array->type.type = res;
2254 } else if (is_sre_byref (klass)) {
2256 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
2257 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
2258 return_val_if_nok (error, NULL);
2260 res = &mono_class_from_mono_type (base)->this_arg;
2261 sre_byref->type.type = res;
2263 } else if (is_sre_pointer (klass)) {
2265 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
2266 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
2267 return_val_if_nok (error, NULL);
2269 res = &mono_ptr_class_get (base)->byval_arg;
2270 sre_pointer->type.type = res;
2272 } else if (is_sre_generic_instance (klass)) {
2273 MonoType *res, **types;
2274 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
2277 count = mono_array_length (gclass->type_arguments);
2278 types = g_new0 (MonoType*, count);
2279 for (i = 0; i < count; ++i) {
2280 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
2281 types [i] = mono_reflection_type_get_handle (t, error);
2282 if (!types[i] || !is_ok (error)) {
2288 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
2291 gclass->type.type = res;
2295 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
2300 ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
2303 mono_reflection_type_get_handle (type, &error);
2304 mono_error_set_pending_exception (&error);
2308 reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
2310 MonoDomain *domain = mono_object_domain ((MonoObject*)type);
2313 mono_error_init (error);
2315 MonoType *res = mono_reflection_type_get_handle (type, error);
2317 if (!res && is_ok (error)) {
2318 mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
2320 return_val_if_nok (error, FALSE);
2322 klass = mono_class_from_mono_type (res);
2324 mono_loader_lock (); /*same locking as mono_type_get_object_checked */
2325 mono_domain_lock (domain);
2327 if (!image_is_dynamic (klass->image)) {
2328 mono_class_setup_supertypes (klass);
2330 if (!domain->type_hash)
2331 domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash,
2332 (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
2333 mono_g_hash_table_insert (domain->type_hash, res, type);
2335 mono_domain_unlock (domain);
2336 mono_loader_unlock ();
2342 mono_reflection_register_with_runtime (MonoReflectionType *type)
2345 (void) reflection_register_with_runtime (type, &error);
2346 mono_error_set_pending_exception (&error);
2350 * LOCKING: Assumes the loader lock is held.
2352 static MonoMethodSignature*
2353 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
2354 MonoMethodSignature *sig;
2357 mono_error_init (error);
2359 count = parameters? mono_array_length (parameters): 0;
2361 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
2362 sig->param_count = count;
2363 sig->sentinelpos = -1; /* FIXME */
2364 for (i = 0; i < count; ++i) {
2365 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
2366 if (!is_ok (error)) {
2367 image_g_free (image, sig);
2375 * LOCKING: Assumes the loader lock is held.
2377 static MonoMethodSignature*
2378 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
2379 MonoMethodSignature *sig;
2381 mono_error_init (error);
2383 sig = parameters_to_signature (image, ctor->parameters, error);
2384 return_val_if_nok (error, NULL);
2385 sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2386 sig->ret = &mono_defaults.void_class->byval_arg;
2391 * LOCKING: Assumes the loader lock is held.
2393 static MonoMethodSignature*
2394 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
2395 MonoMethodSignature *sig;
2397 mono_error_init (error);
2399 sig = parameters_to_signature (image, method->parameters, error);
2400 return_val_if_nok (error, NULL);
2401 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2402 if (method->rtype) {
2403 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
2404 if (!is_ok (error)) {
2405 image_g_free (image, sig);
2409 sig->ret = &mono_defaults.void_class->byval_arg;
2411 sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
2415 static MonoMethodSignature*
2416 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
2417 MonoMethodSignature *sig;
2419 mono_error_init (error);
2421 sig = parameters_to_signature (NULL, method->parameters, error);
2422 return_val_if_nok (error, NULL);
2423 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2424 if (method->rtype) {
2425 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
2426 if (!is_ok (error)) {
2431 sig->ret = &mono_defaults.void_class->byval_arg;
2433 sig->generic_param_count = 0;
2438 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
2440 mono_error_init (error);
2441 MonoClass *klass = mono_object_class (prop);
2442 if (strcmp (klass->name, "PropertyBuilder") == 0) {
2443 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
2444 *name = mono_string_to_utf8_checked (pb->name, error);
2445 return_if_nok (error);
2446 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
2448 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
2449 *name = g_strdup (p->property->name);
2450 if (p->property->get)
2451 *type = mono_method_signature (p->property->get)->ret;
2453 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
2458 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
2460 mono_error_init (error);
2461 MonoClass *klass = mono_object_class (field);
2462 if (strcmp (klass->name, "FieldBuilder") == 0) {
2463 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
2464 *name = mono_string_to_utf8_checked (fb->name, error);
2465 return_if_nok (error);
2466 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
2468 MonoReflectionField *f = (MonoReflectionField *)field;
2469 *name = g_strdup (mono_field_get_name (f->field));
2470 *type = f->field->type;
2474 #else /* DISABLE_REFLECTION_EMIT */
2477 mono_reflection_register_with_runtime (MonoReflectionType *type)
2483 is_sre_type_builder (MonoClass *klass)
2489 is_sre_generic_instance (MonoClass *klass)
2495 mono_is_sre_ctor_builder (MonoClass *klass)
2501 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2507 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2513 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
2515 mono_error_init (error);
2518 #endif /* !DISABLE_REFLECTION_EMIT */
2522 is_sr_mono_field (MonoClass *klass)
2524 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
2528 mono_is_sr_mono_property (MonoClass *klass)
2530 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
2534 is_sr_mono_method (MonoClass *klass)
2536 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
2540 mono_is_sr_mono_cmethod (MonoClass *klass)
2542 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
2546 is_sr_mono_generic_method (MonoClass *klass)
2548 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
2552 is_sr_mono_generic_cmethod (MonoClass *klass)
2554 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
2558 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
2560 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
2564 mono_is_sre_type_builder (MonoClass *klass)
2566 return is_sre_type_builder (klass);
2570 mono_is_sre_generic_instance (MonoClass *klass)
2572 return is_sre_generic_instance (klass);
2578 * encode_cattr_value:
2579 * Encode a value in a custom attribute stream of bytes.
2580 * The value to encode is either supplied as an object in argument val
2581 * (valuetypes are boxed), or as a pointer to the data in the
2583 * @type represents the type of the value
2584 * @buffer is the start of the buffer
2585 * @p the current position in the buffer
2586 * @buflen contains the size of the buffer and is used to return the new buffer size
2587 * if this needs to be realloced.
2588 * @retbuffer and @retp return the start and the position of the buffer
2589 * @error set on error.
2592 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2594 MonoTypeEnum simple_type;
2596 mono_error_init (error);
2597 if ((p-buffer) + 10 >= *buflen) {
2600 newbuf = (char *)g_realloc (buffer, *buflen);
2601 p = newbuf + (p-buffer);
2605 argval = ((char*)arg + sizeof (MonoObject));
2606 simple_type = type->type;
2608 switch (simple_type) {
2609 case MONO_TYPE_BOOLEAN:
2614 case MONO_TYPE_CHAR:
2617 swap_with_size (p, argval, 2, 1);
2623 swap_with_size (p, argval, 4, 1);
2627 swap_with_size (p, argval, 8, 1);
2632 swap_with_size (p, argval, 8, 1);
2635 case MONO_TYPE_VALUETYPE:
2636 if (type->data.klass->enumtype) {
2637 simple_type = mono_class_enum_basetype (type->data.klass)->type;
2640 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2643 case MONO_TYPE_STRING: {
2650 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2651 return_if_nok (error);
2652 slen = strlen (str);
2653 if ((p-buffer) + 10 + slen >= *buflen) {
2657 newbuf = (char *)g_realloc (buffer, *buflen);
2658 p = newbuf + (p-buffer);
2661 mono_metadata_encode_value (slen, p, &p);
2662 memcpy (p, str, slen);
2667 case MONO_TYPE_CLASS: {
2676 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2677 return_if_nok (error);
2679 str = type_get_qualified_name (arg_type, NULL);
2680 slen = strlen (str);
2681 if ((p-buffer) + 10 + slen >= *buflen) {
2685 newbuf = (char *)g_realloc (buffer, *buflen);
2686 p = newbuf + (p-buffer);
2689 mono_metadata_encode_value (slen, p, &p);
2690 memcpy (p, str, slen);
2695 case MONO_TYPE_SZARRAY: {
2697 MonoClass *eclass, *arg_eclass;
2700 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2703 len = mono_array_length ((MonoArray*)arg);
2705 *p++ = (len >> 8) & 0xff;
2706 *p++ = (len >> 16) & 0xff;
2707 *p++ = (len >> 24) & 0xff;
2709 *retbuffer = buffer;
2710 eclass = type->data.klass;
2711 arg_eclass = mono_object_class (arg)->element_class;
2714 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2715 eclass = mono_defaults.object_class;
2717 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2718 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2719 int elsize = mono_class_array_element_size (arg_eclass);
2720 for (i = 0; i < len; ++i) {
2721 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2722 return_if_nok (error);
2725 } else if (eclass->valuetype && arg_eclass->valuetype) {
2726 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2727 int elsize = mono_class_array_element_size (eclass);
2728 for (i = 0; i < len; ++i) {
2729 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2730 return_if_nok (error);
2734 for (i = 0; i < len; ++i) {
2735 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2736 return_if_nok (error);
2741 case MONO_TYPE_OBJECT: {
2747 * The parameter type is 'object' but the type of the actual
2748 * argument is not. So we have to add type information to the blob
2749 * too. This is completely undocumented in the spec.
2753 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2758 klass = mono_object_class (arg);
2760 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2764 return_if_nok (error);
2767 if (klass->enumtype) {
2769 } else if (klass == mono_defaults.string_class) {
2770 simple_type = MONO_TYPE_STRING;
2773 } else if (klass->rank == 1) {
2775 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2776 /* See Partition II, Appendix B3 */
2779 *p++ = klass->element_class->byval_arg.type;
2780 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2781 return_if_nok (error);
2783 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2784 *p++ = simple_type = klass->byval_arg.type;
2787 g_error ("unhandled type in custom attr");
2789 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2790 slen = strlen (str);
2791 if ((p-buffer) + 10 + slen >= *buflen) {
2795 newbuf = (char *)g_realloc (buffer, *buflen);
2796 p = newbuf + (p-buffer);
2799 mono_metadata_encode_value (slen, p, &p);
2800 memcpy (p, str, slen);
2803 simple_type = mono_class_enum_basetype (klass)->type;
2807 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2810 *retbuffer = buffer;
2814 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2816 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2817 char *str = type_get_qualified_name (type, NULL);
2818 int slen = strlen (str);
2822 * This seems to be optional...
2825 mono_metadata_encode_value (slen, p, &p);
2826 memcpy (p, str, slen);
2829 } else if (type->type == MONO_TYPE_OBJECT) {
2831 } else if (type->type == MONO_TYPE_CLASS) {
2832 /* it should be a type: encode_cattr_value () has the check */
2835 mono_metadata_encode_value (type->type, p, &p);
2836 if (type->type == MONO_TYPE_SZARRAY)
2837 /* See the examples in Partition VI, Annex B */
2838 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2844 #ifndef DISABLE_REFLECTION_EMIT
2846 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2850 mono_error_init (error);
2852 /* Preallocate a large enough buffer */
2853 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2854 char *str = type_get_qualified_name (type, NULL);
2857 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2858 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2864 len += strlen (name);
2866 if ((p-buffer) + 20 + len >= *buflen) {
2870 newbuf = (char *)g_realloc (buffer, *buflen);
2871 p = newbuf + (p-buffer);
2875 encode_field_or_prop_type (type, p, &p);
2877 len = strlen (name);
2878 mono_metadata_encode_value (len, p, &p);
2879 memcpy (p, name, len);
2881 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2882 return_if_nok (error);
2884 *retbuffer = buffer;
2888 * mono_reflection_get_custom_attrs_blob:
2889 * @ctor: custom attribute constructor
2890 * @ctorArgs: arguments o the constructor
2896 * Creates the blob of data that needs to be saved in the metadata and that represents
2897 * the custom attributed described by @ctor, @ctorArgs etc.
2898 * Returns: a Byte array representing the blob of data.
2901 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2904 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2905 mono_error_cleanup (&error);
2910 * mono_reflection_get_custom_attrs_blob_checked:
2911 * @ctor: custom attribute constructor
2912 * @ctorArgs: arguments o the constructor
2917 * @error: set on error
2919 * Creates the blob of data that needs to be saved in the metadata and that represents
2920 * the custom attributed described by @ctor, @ctorArgs etc.
2921 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2924 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2926 MonoArray *result = NULL;
2927 MonoMethodSignature *sig;
2932 mono_error_init (error);
2934 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2935 /* sig is freed later so allocate it in the heap */
2936 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2937 if (!is_ok (error)) {
2942 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2945 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2947 p = buffer = (char *)g_malloc (buflen);
2948 /* write the prolog */
2951 for (i = 0; i < sig->param_count; ++i) {
2952 arg = mono_array_get (ctorArgs, MonoObject*, i);
2953 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2954 if (!is_ok (error)) goto leave;
2958 i += mono_array_length (properties);
2960 i += mono_array_length (fields);
2962 *p++ = (i >> 8) & 0xff;
2965 for (i = 0; i < mono_array_length (properties); ++i) {
2969 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2970 get_prop_name_and_type (prop, &pname, &ptype, error);
2971 if (!is_ok (error)) goto leave;
2972 *p++ = 0x54; /* PROPERTY signature */
2973 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2975 if (!is_ok (error)) goto leave;
2981 for (i = 0; i < mono_array_length (fields); ++i) {
2985 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2986 get_field_name_and_type (field, &fname, &ftype, error);
2987 if (!is_ok (error)) goto leave;
2988 *p++ = 0x53; /* FIELD signature */
2989 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2991 if (!is_ok (error)) goto leave;
2995 g_assert (p - buffer <= buflen);
2996 buflen = p - buffer;
2997 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
3000 p = mono_array_addr (result, char, 0);
3001 memcpy (p, buffer, buflen);
3004 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
3010 * reflection_setup_internal_class:
3011 * @tb: a TypeBuilder object
3012 * @error: set on error
3014 * Creates a MonoClass that represents the TypeBuilder.
3015 * This is a trick that lets us simplify a lot of reflection code
3016 * (and will allow us to support Build and Run assemblies easier).
3018 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3021 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3023 MonoClass *klass, *parent;
3025 mono_error_init (error);
3026 RESOLVE_TYPE (tb->parent, error);
3027 return_val_if_nok (error, FALSE);
3029 mono_loader_lock ();
3032 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
3033 if (!is_ok (error)) {
3034 mono_loader_unlock ();
3037 /* check so we can compile corlib correctly */
3038 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
3039 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
3040 parent = parent_type->data.klass;
3042 parent = mono_class_from_mono_type (parent_type);
3048 /* the type has already being created: it means we just have to change the parent */
3049 if (tb->type.type) {
3050 klass = mono_class_from_mono_type (tb->type.type);
3051 klass->parent = NULL;
3052 /* fool mono_class_setup_parent */
3053 klass->supertypes = NULL;
3054 mono_class_setup_parent (klass, parent);
3055 mono_class_setup_mono_type (klass);
3056 mono_loader_unlock ();
3060 klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
3062 klass->image = &tb->module->dynamic_image->image;
3064 klass->inited = 1; /* we lie to the runtime */
3065 klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
3068 klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
3071 klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
3072 klass->flags = tb->attrs;
3074 mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
3076 klass->element_class = klass;
3078 if (mono_class_get_ref_info (klass) == NULL) {
3080 mono_class_set_ref_info (klass, tb);
3082 /* Put into cache so mono_class_get_checked () will find it.
3083 Skip nested types as those should not be available on the global scope. */
3084 if (!tb->nesting_type)
3085 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
3088 We must register all types as we cannot rely on the name_cache hashtable since we find the class
3089 by performing a mono_class_get which does the full resolution.
3091 Working around this semantics would require us to write a lot of code for no clear advantage.
3093 mono_image_append_class_to_reflection_info_set (klass);
3095 g_assert (mono_class_get_ref_info (klass) == tb);
3098 mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
3100 if (parent != NULL) {
3101 mono_class_setup_parent (klass, parent);
3102 } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
3103 const char *old_n = klass->name;
3104 /* trick to get relative numbering right when compiling corlib */
3105 klass->name = "BuildingObject";
3106 mono_class_setup_parent (klass, mono_defaults.object_class);
3107 klass->name = old_n;
3110 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
3111 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
3112 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
3113 klass->instance_size = sizeof (MonoObject);
3114 klass->size_inited = 1;
3115 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
3118 mono_class_setup_mono_type (klass);
3120 mono_class_setup_supertypes (klass);
3123 * FIXME: handle interfaces.
3126 tb->type.type = &klass->byval_arg;
3128 if (tb->nesting_type) {
3129 g_assert (tb->nesting_type->type);
3130 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
3131 if (!is_ok (error)) goto failure;
3132 klass->nested_in = mono_class_from_mono_type (nesting_type);
3135 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
3137 mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
3139 mono_loader_unlock ();
3143 mono_loader_unlock ();
3148 * ves_icall_TypeBuilder_setup_internal_class:
3149 * @tb: a TypeBuilder object
3152 * Creates a MonoClass that represents the TypeBuilder.
3153 * This is a trick that lets us simplify a lot of reflection code
3154 * (and will allow us to support Build and Run assemblies easier).
3158 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
3161 (void) reflection_setup_internal_class (tb, &error);
3162 mono_error_set_pending_exception (&error);
3166 * ves_icall_TypeBuilder_setup_generic_class:
3167 * @tb: a TypeBuilder object
3169 * Setup the generic class before adding the first generic parameter.
3172 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
3177 * mono_reflection_create_generic_class:
3178 * @tb: a TypeBuilder object
3179 * @error: set on error
3181 * Creates the generic class after all generic parameters have been added.
3182 * On success returns TRUE, on failure returns FALSE and sets @error.
3186 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3192 mono_error_init (error);
3194 klass = mono_class_from_mono_type (tb->type.type);
3196 count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
3198 if (klass->generic_container || (count == 0))
3201 g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
3203 klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3205 klass->generic_container->owner.klass = klass;
3206 klass->generic_container->type_argc = count;
3207 klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
3209 klass->is_generic = 1;
3211 for (i = 0; i < count; i++) {
3212 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3213 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
3214 return_val_if_nok (error, FALSE);
3215 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
3216 klass->generic_container->type_params [i] = *param;
3217 /*Make sure we are a diferent type instance */
3218 klass->generic_container->type_params [i].param.owner = klass->generic_container;
3219 klass->generic_container->type_params [i].info.pklass = NULL;
3220 klass->generic_container->type_params [i].info.flags = gparam->attrs;
3222 g_assert (klass->generic_container->type_params [i].param.owner);
3225 klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
3229 static MonoMarshalSpec*
3230 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
3231 MonoReflectionMarshal *minfo, MonoError *error)
3233 MonoMarshalSpec *res;
3235 mono_error_init (error);
3237 res = image_g_new0 (image, MonoMarshalSpec, 1);
3238 res->native = (MonoMarshalNative)minfo->type;
3240 switch (minfo->type) {
3241 case MONO_NATIVE_LPARRAY:
3242 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
3243 if (minfo->has_size) {
3244 res->data.array_data.param_num = minfo->param_num;
3245 res->data.array_data.num_elem = minfo->count;
3246 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
3249 res->data.array_data.param_num = -1;
3250 res->data.array_data.num_elem = -1;
3251 res->data.array_data.elem_mult = -1;
3255 case MONO_NATIVE_BYVALTSTR:
3256 case MONO_NATIVE_BYVALARRAY:
3257 res->data.array_data.num_elem = minfo->count;
3260 case MONO_NATIVE_CUSTOM:
3261 if (minfo->marshaltyperef) {
3262 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
3263 if (!is_ok (error)) {
3264 image_g_free (image, res);
3267 res->data.custom_data.custom_name =
3268 type_get_fully_qualified_name (marshaltyperef);
3270 if (minfo->mcookie) {
3271 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
3272 if (!is_ok (error)) {
3273 image_g_free (image, res);
3285 #endif /* !DISABLE_REFLECTION_EMIT */
3287 MonoReflectionMarshalAsAttribute*
3288 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
3289 MonoMarshalSpec *spec, MonoError *error)
3291 MonoReflectionType *rt;
3292 MonoReflectionMarshalAsAttribute *minfo;
3295 mono_error_init (error);
3297 minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
3300 minfo->utype = spec->native;
3302 switch (minfo->utype) {
3303 case MONO_NATIVE_LPARRAY:
3304 minfo->array_subtype = spec->data.array_data.elem_type;
3305 minfo->size_const = spec->data.array_data.num_elem;
3306 if (spec->data.array_data.param_num != -1)
3307 minfo->size_param_index = spec->data.array_data.param_num;
3310 case MONO_NATIVE_BYVALTSTR:
3311 case MONO_NATIVE_BYVALARRAY:
3312 minfo->size_const = spec->data.array_data.num_elem;
3315 case MONO_NATIVE_CUSTOM:
3316 if (spec->data.custom_data.custom_name) {
3317 mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
3318 return_val_if_nok (error, NULL);
3321 rt = mono_type_get_object_checked (domain, mtype, error);
3325 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
3328 MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
3330 if (spec->data.custom_data.cookie)
3331 MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
3341 #ifndef DISABLE_REFLECTION_EMIT
3343 reflection_methodbuilder_to_mono_method (MonoClass *klass,
3344 ReflectionMethodBuilder *rmb,
3345 MonoMethodSignature *sig,
3349 MonoMethodWrapper *wrapperm;
3350 MonoMarshalSpec **specs;
3351 MonoReflectionMethodAux *method_aux;
3356 mono_error_init (error);
3358 * Methods created using a MethodBuilder should have their memory allocated
3359 * inside the image mempool, while dynamic methods should have their memory
3362 dynamic = rmb->refs != NULL;
3363 image = dynamic ? NULL : klass->image;
3366 g_assert (!klass->generic_class);
3368 mono_loader_lock ();
3370 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
3371 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
3372 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
3374 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
3376 wrapperm = (MonoMethodWrapper*)m;
3378 m->dynamic = dynamic;
3380 m->flags = rmb->attrs;
3381 m->iflags = rmb->iattrs;
3382 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
3385 m->sre_method = TRUE;
3386 m->skip_visibility = rmb->skip_visibility;
3388 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
3390 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
3391 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
3394 m->signature->pinvoke = 1;
3395 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3396 m->signature->pinvoke = 1;
3398 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3400 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
3401 mono_error_assert_ok (error);
3402 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
3403 mono_error_assert_ok (error);
3405 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
3407 if (image_is_dynamic (klass->image))
3408 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3410 mono_loader_unlock ();
3413 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
3414 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
3415 MonoMethodHeader *header;
3417 gint32 max_stack, i;
3418 gint32 num_locals = 0;
3419 gint32 num_clauses = 0;
3423 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
3424 code_size = rmb->ilgen->code_len;
3425 max_stack = rmb->ilgen->max_stack;
3426 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
3427 if (rmb->ilgen->ex_handlers)
3428 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
3431 code = mono_array_addr (rmb->code, guint8, 0);
3432 code_size = mono_array_length (rmb->code);
3433 /* we probably need to run a verifier on the code... */
3443 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
3444 header->code_size = code_size;
3445 header->code = (const unsigned char *)image_g_malloc (image, code_size);
3446 memcpy ((char*)header->code, code, code_size);
3447 header->max_stack = max_stack;
3448 header->init_locals = rmb->init_locals;
3449 header->num_locals = num_locals;
3451 for (i = 0; i < num_locals; ++i) {
3452 MonoReflectionLocalBuilder *lb =
3453 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
3455 header->locals [i] = image_g_new0 (image, MonoType, 1);
3456 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
3457 mono_error_assert_ok (error);
3458 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
3461 header->num_clauses = num_clauses;
3463 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
3464 rmb->ilgen, num_clauses, error);
3465 mono_error_assert_ok (error);
3468 wrapperm->header = header;
3471 if (rmb->generic_params) {
3472 int count = mono_array_length (rmb->generic_params);
3473 MonoGenericContainer *container = rmb->generic_container;
3475 g_assert (container);
3477 container->type_argc = count;
3478 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
3479 container->owner.method = m;
3480 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
3482 m->is_generic = TRUE;
3483 mono_method_set_generic_container (m, container);
3485 for (i = 0; i < count; i++) {
3486 MonoReflectionGenericParam *gp =
3487 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
3488 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
3489 mono_error_assert_ok (error);
3490 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
3491 container->type_params [i] = *param;
3495 * The method signature might have pointers to generic parameters that belong to other methods.
3496 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3497 * generic parameters.
3499 for (i = 0; i < m->signature->param_count; ++i) {
3500 MonoType *t = m->signature->params [i];
3501 if (t->type == MONO_TYPE_MVAR) {
3502 MonoGenericParam *gparam = t->data.generic_param;
3503 if (gparam->num < count) {
3504 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
3505 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
3511 if (klass->generic_container) {
3512 container->parent = klass->generic_container;
3513 container->context.class_inst = klass->generic_container->context.class_inst;
3515 container->context.method_inst = mono_get_shared_generic_inst (container);
3519 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
3523 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
3525 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
3526 data [0] = GUINT_TO_POINTER (rmb->nrefs);
3527 for (i = 0; i < rmb->nrefs; ++i)
3528 data [i + 1] = rmb->refs [i];
3533 /* Parameter info */
3536 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3537 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
3538 for (i = 0; i <= m->signature->param_count; ++i) {
3539 MonoReflectionParamBuilder *pb;
3540 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3541 if ((i > 0) && (pb->attrs)) {
3542 /* Make a copy since it might point to a shared type structure */
3543 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
3544 m->signature->params [i - 1]->attrs = pb->attrs;
3547 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3548 MonoDynamicImage *assembly;
3550 MonoTypeEnum def_type;
3554 if (!method_aux->param_defaults) {
3555 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3556 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3558 assembly = (MonoDynamicImage*)klass->image;
3559 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3560 /* Copy the data from the blob since it might get realloc-ed */
3561 p = assembly->blob.data + idx;
3562 len = mono_metadata_decode_blob_size (p, &p2);
3564 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3565 method_aux->param_default_types [i] = def_type;
3566 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3570 method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
3571 mono_error_assert_ok (error);
3574 if (!method_aux->param_cattr)
3575 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3576 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3582 /* Parameter marshalling */
3585 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3586 MonoReflectionParamBuilder *pb;
3587 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3588 if (pb->marshal_info) {
3590 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3591 specs [pb->position] =
3592 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3593 if (!is_ok (error)) {
3594 mono_loader_unlock ();
3595 image_g_free (image, specs);
3596 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3602 if (specs != NULL) {
3604 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3605 method_aux->param_marshall = specs;
3608 if (image_is_dynamic (klass->image) && method_aux)
3609 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3611 mono_loader_unlock ();
3617 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3619 ReflectionMethodBuilder rmb;
3620 MonoMethodSignature *sig;
3622 mono_loader_lock ();
3623 g_assert (klass->image != NULL);
3624 sig = ctor_builder_to_signature (klass->image, mb, error);
3625 mono_loader_unlock ();
3626 return_val_if_nok (error, NULL);
3628 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3631 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3632 return_val_if_nok (error, NULL);
3633 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3635 /* If we are in a generic class, we might be called multiple times from inflate_method */
3636 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3637 /* ilgen is no longer needed */
3645 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
3647 ReflectionMethodBuilder rmb;
3648 MonoMethodSignature *sig;
3650 mono_error_init (error);
3652 mono_loader_lock ();
3653 g_assert (klass->image != NULL);
3654 sig = method_builder_to_signature (klass->image, mb, error);
3655 mono_loader_unlock ();
3656 return_val_if_nok (error, NULL);
3658 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3661 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3662 return_val_if_nok (error, NULL);
3663 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3665 /* If we are in a generic class, we might be called multiple times from inflate_method */
3666 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3667 /* ilgen is no longer needed */
3673 static MonoClassField*
3674 fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
3676 MonoClassField *field;
3679 mono_error_init (error);
3681 field = g_new0 (MonoClassField, 1);
3683 field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
3684 mono_error_assert_ok (error);
3685 if (fb->attrs || fb->modreq || fb->modopt) {
3686 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3687 if (!is_ok (error)) {
3691 field->type = mono_metadata_type_dup (NULL, type);
3692 field->type->attrs = fb->attrs;
3694 g_assert (image_is_dynamic (klass->image));
3695 custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
3696 g_free (field->type);
3697 if (!is_ok (error)) {
3701 field->type = mono_metadata_type_dup (klass->image, custom);
3704 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3705 if (!is_ok (error)) {
3710 if (fb->offset != -1)
3711 field->offset = fb->offset;
3712 field->parent = klass;
3713 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3715 // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
3721 #ifndef DISABLE_REFLECTION_EMIT
3724 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
3726 MonoMethodInflated *imethod;
3727 MonoGenericContext *context;
3731 * With generic code sharing the klass might not be inflated.
3732 * This can happen because classes inflated with their own
3733 * type arguments are "normalized" to the uninflated class.
3735 if (!klass->generic_class)
3738 context = mono_class_get_context (klass);
3740 if (klass->method.count && klass->methods) {
3741 /* Find the already created inflated method */
3742 for (i = 0; i < klass->method.count; ++i) {
3743 g_assert (klass->methods [i]->is_inflated);
3744 if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
3747 g_assert (i < klass->method.count);
3748 imethod = (MonoMethodInflated*)klass->methods [i];
3751 imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
3752 mono_error_assert_ok (&error);
3755 if (method->is_generic && image_is_dynamic (method->klass->image)) {
3756 MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
3758 mono_image_lock ((MonoImage*)image);
3759 mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
3760 mono_image_unlock ((MonoImage*)image);
3762 return (MonoMethod *) imethod;
3766 inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
3771 mono_error_init (error);
3773 MonoClass *type_class = mono_object_class (type);
3775 if (is_sre_generic_instance (type_class)) {
3776 MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
3777 MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
3778 return_val_if_nok (error, NULL);
3779 gklass = mono_class_from_mono_type (generic_type);
3780 } else if (is_sre_type_builder (type_class)) {
3781 MonoType *t = mono_reflection_type_get_handle (type, error);
3782 return_val_if_nok (error, NULL);
3783 gklass = mono_class_from_mono_type (t);
3784 } else if (type->type) {
3785 gklass = mono_class_from_mono_type (type->type);
3786 gklass = mono_class_get_generic_type_definition (gklass);
3788 g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
3791 if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
3792 if (((MonoReflectionMethodBuilder*)obj)->mhandle)
3793 method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
3795 method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
3799 else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
3800 method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
3803 } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
3804 method = ((MonoReflectionMethod *) obj)->method;
3806 method = NULL; /* prevent compiler warning */
3807 g_error ("can't handle type %s", obj->vtable->klass->name);
3810 MonoType *t = mono_reflection_type_get_handle (type, error);
3811 return_val_if_nok (error, NULL);
3812 return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
3816 reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoError *error)
3818 MonoGenericClass *gclass;
3819 MonoClass *klass, *gklass;
3822 mono_error_init (error);
3824 gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
3825 return_if_nok (error);
3826 klass = mono_class_from_mono_type (gtype);
3827 g_assert (gtype->type == MONO_TYPE_GENERICINST);
3828 gclass = gtype->data.generic_class;
3830 if (!gclass->is_dynamic)
3833 gklass = gclass->container_class;
3834 mono_class_init (gklass);
3836 /* Mark this as needing synchronization with its generic container */
3837 gclass->need_sync = TRUE;
3841 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
3844 reflection_generic_class_initialize (type, &error);
3845 mono_error_set_pending_exception (&error);
3849 * fix_partial_generic_class:
3850 * @klass: a generic instantiation MonoClass
3851 * @error: set on error
3853 * Assumes that the generic container of @klass has its vtable
3854 * initialized, and updates the parent class, interfaces, methods and
3855 * fields of @klass by inflating the types using the generic context.
3857 * On success returns TRUE, on failure returns FALSE and sets @error.
3861 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3863 MonoClass *gklass = klass->generic_class->container_class;
3866 mono_error_init (error);
3868 if (klass->wastypebuilder)
3871 if (klass->parent != gklass->parent) {
3872 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
3873 if (mono_error_ok (error)) {
3874 MonoClass *parent = mono_class_from_mono_type (parent_type);
3875 mono_metadata_free_type (parent_type);
3876 if (parent != klass->parent) {
3877 /*fool mono_class_setup_parent*/
3878 klass->supertypes = NULL;
3879 mono_class_setup_parent (klass, parent);
3882 if (gklass->wastypebuilder)
3883 klass->wastypebuilder = TRUE;
3888 if (!klass->generic_class->need_sync)
3891 if (klass->method.count != gklass->method.count) {
3892 klass->method.count = gklass->method.count;
3893 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
3895 for (i = 0; i < klass->method.count; i++) {
3896 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3897 gklass->methods [i], klass, mono_class_get_context (klass), error);
3898 mono_error_assert_ok (error);
3902 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3903 klass->interface_count = gklass->interface_count;
3904 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3905 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3907 for (i = 0; i < gklass->interface_count; ++i) {
3908 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3909 return_val_if_nok (error, FALSE);
3911 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3912 mono_metadata_free_type (iface_type);
3914 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3917 klass->interfaces_inited = 1;
3920 if (klass->field.count != gklass->field.count) {
3921 klass->field.count = gklass->field.count;
3922 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
3924 for (i = 0; i < klass->field.count; i++) {
3925 klass->fields [i] = gklass->fields [i];
3926 klass->fields [i].parent = klass;
3927 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3928 return_val_if_nok (error, FALSE);
3932 /*We can only finish with this klass once it's parent has as well*/
3933 if (gklass->wastypebuilder)
3934 klass->wastypebuilder = TRUE;
3939 * ensure_generic_class_runtime_vtable:
3940 * @klass a generic class
3941 * @error set on error
3943 * Ensures that the generic container of @klass has a vtable and
3944 * returns TRUE on success. On error returns FALSE and sets @error.
3947 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3949 MonoClass *gklass = klass->generic_class->container_class;
3951 mono_error_init (error);
3953 if (!ensure_runtime_vtable (gklass, error))
3956 return fix_partial_generic_class (klass, error);
3960 * ensure_runtime_vtable:
3962 * @error set on error
3964 * Ensures that @klass has a vtable and returns TRUE on success. On
3965 * error returns FALSE and sets @error.
3968 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3970 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3973 mono_error_init (error);
3975 if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
3978 if (!ensure_runtime_vtable (klass->parent, error))
3982 num = tb->ctors? mono_array_length (tb->ctors): 0;
3983 num += tb->num_methods;
3984 klass->method.count = num;
3985 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3986 num = tb->ctors? mono_array_length (tb->ctors): 0;
3987 for (i = 0; i < num; ++i) {
3988 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3991 klass->methods [i] = ctor;
3993 num = tb->num_methods;
3995 for (i = 0; i < num; ++i) {
3996 MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3999 klass->methods [j++] = meth;
4002 if (tb->interfaces) {
4003 klass->interface_count = mono_array_length (tb->interfaces);
4004 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
4005 for (i = 0; i < klass->interface_count; ++i) {
4006 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
4007 return_val_if_nok (error, FALSE);
4008 klass->interfaces [i] = mono_class_from_mono_type (iface);
4009 if (!ensure_runtime_vtable (klass->interfaces [i], error))
4012 klass->interfaces_inited = 1;
4014 } else if (klass->generic_class){
4015 if (!ensure_generic_class_runtime_vtable (klass, error)) {
4016 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4021 if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
4023 for (i = 0; i < klass->method.count; ++i) {
4024 MonoMethod *im = klass->methods [i];
4025 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
4026 im->slot = slot_num++;
4029 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
4030 mono_class_setup_interface_offsets (klass);
4031 mono_class_setup_interface_id (klass);
4035 * The generic vtable is needed even if image->run is not set since some
4036 * runtime code like ves_icall_Type_GetMethodsByName depends on
4037 * method->slot being defined.
4041 * tb->methods could not be freed since it is used for determining
4042 * overrides during dynamic vtable construction.
4049 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
4051 mono_error_init (error);
4052 MonoClass *klass = mono_object_class (method);
4053 if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
4054 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
4055 return sr_method->method;
4057 if (is_sre_method_builder (klass)) {
4058 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
4061 if (mono_is_sre_method_on_tb_inst (klass)) {
4062 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
4064 /*FIXME move this to a proper method and unify with resolve_object*/
4065 if (m->method_args) {
4066 result = mono_reflection_method_on_tb_inst_get_handle (m, error);
4068 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
4069 return_val_if_nok (error, NULL);
4070 MonoClass *inflated_klass = mono_class_from_mono_type (type);
4071 MonoMethod *mono_method;
4073 if (is_sre_method_builder (mono_object_class (m->mb)))
4074 mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
4075 else if (is_sr_mono_method (mono_object_class (m->mb)))
4076 mono_method = ((MonoReflectionMethod *)m->mb)->method;
4078 g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
4080 result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
4085 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
4090 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4092 MonoReflectionTypeBuilder *tb;
4094 MonoReflectionMethod *m;
4096 mono_error_init (error);
4100 g_assert (image_is_dynamic (klass->image));
4102 if (!mono_class_get_ref_info (klass))
4105 g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
4107 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
4111 for (i = 0; i < tb->num_methods; ++i) {
4112 MonoReflectionMethodBuilder *mb =
4113 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4114 if (mb->override_methods)
4115 onum += mono_array_length (mb->override_methods);
4120 *overrides = g_new0 (MonoMethod*, onum * 2);
4123 for (i = 0; i < tb->num_methods; ++i) {
4124 MonoReflectionMethodBuilder *mb =
4125 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4126 if (mb->override_methods) {
4127 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
4128 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
4130 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
4131 return_if_nok (error);
4132 (*overrides) [onum * 2 + 1] = mb->mhandle;
4134 g_assert (mb->mhandle);
4142 *num_overrides = onum;
4146 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
4148 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4149 MonoReflectionFieldBuilder *fb;
4150 MonoClassField *field;
4151 MonoImage *image = klass->image;
4154 guint32 len, idx, real_size = 0;
4156 klass->field.count = tb->num_fields;
4157 klass->field.first = 0;
4159 mono_error_init (error);
4161 if (tb->class_size) {
4162 if ((tb->packing_size & 0xffffff00) != 0) {
4163 char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
4164 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
4167 klass->packing_size = tb->packing_size;
4168 real_size = klass->instance_size + tb->class_size;
4171 if (!klass->field.count) {
4172 klass->instance_size = MAX (klass->instance_size, real_size);
4176 klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
4177 mono_class_alloc_ext (klass);
4178 klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
4180 This is, guess what, a hack.
4181 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
4182 On the static path no field class is resolved, only types are built. This is the right thing to do
4184 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
4186 klass->size_inited = 1;
4188 for (i = 0; i < klass->field.count; ++i) {
4189 MonoArray *rva_data;
4190 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4191 field = &klass->fields [i];
4192 field->name = mono_string_to_utf8_image (image, fb->name, error);
4193 if (!mono_error_ok (error))
4196 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4197 return_if_nok (error);
4198 field->type = mono_metadata_type_dup (klass->image, type);
4199 field->type->attrs = fb->attrs;
4201 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4202 return_if_nok (error);
4205 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
4206 char *base = mono_array_addr (rva_data, char, 0);
4207 size_t size = mono_array_length (rva_data);
4208 char *data = (char *)mono_image_alloc (klass->image, size);
4209 memcpy (data, base, size);
4210 klass->ext->field_def_values [i].data = data;
4212 if (fb->offset != -1)
4213 field->offset = fb->offset;
4214 field->parent = klass;
4216 mono_save_custom_attrs (klass->image, field, fb->cattrs);
4218 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
4219 klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
4221 if (fb->def_value) {
4222 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4223 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
4224 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
4225 /* Copy the data from the blob since it might get realloc-ed */
4226 p = assembly->blob.data + idx;
4227 len = mono_metadata_decode_blob_size (p, &p2);
4229 klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
4230 memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
4234 klass->instance_size = MAX (klass->instance_size, real_size);
4235 mono_class_layout_fields (klass, klass->instance_size);
4239 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
4241 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4242 MonoReflectionPropertyBuilder *pb;
4243 MonoImage *image = klass->image;
4244 MonoProperty *properties;
4247 mono_error_init (error);
4250 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4252 klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
4253 klass->ext->property.first = 0;
4255 properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
4256 klass->ext->properties = properties;
4257 for (i = 0; i < klass->ext->property.count; ++i) {
4258 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
4259 properties [i].parent = klass;
4260 properties [i].attrs = pb->attrs;
4261 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
4262 if (!mono_error_ok (error))
4265 properties [i].get = pb->get_method->mhandle;
4267 properties [i].set = pb->set_method->mhandle;
4269 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
4270 if (pb->def_value) {
4273 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4274 if (!klass->ext->prop_def_values)
4275 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
4276 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
4277 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
4278 /* Copy the data from the blob since it might get realloc-ed */
4279 p = assembly->blob.data + idx;
4280 len = mono_metadata_decode_blob_size (p, &p2);
4282 klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
4283 memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
4288 static MonoReflectionEvent *
4289 reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
4291 mono_error_init (error);
4293 MonoEvent *event = g_new0 (MonoEvent, 1);
4296 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4297 if (!is_ok (error)) {
4301 klass = mono_class_from_mono_type (type);
4303 event->parent = klass;
4304 event->attrs = eb->attrs;
4305 event->name = mono_string_to_utf8_checked (eb->name, error);
4306 if (!is_ok (error)) {
4311 event->add = eb->add_method->mhandle;
4312 if (eb->remove_method)
4313 event->remove = eb->remove_method->mhandle;
4314 if (eb->raise_method)
4315 event->raise = eb->raise_method->mhandle;
4317 #ifndef MONO_SMALL_CONFIG
4318 if (eb->other_methods) {
4320 event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
4321 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4322 MonoReflectionMethodBuilder *mb =
4323 mono_array_get (eb->other_methods,
4324 MonoReflectionMethodBuilder*, j);
4325 event->other [j] = mb->mhandle;
4330 MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
4331 if (!is_ok (error)) {
4332 #ifndef MONO_SMALL_CONFIG
4333 g_free (event->other);
4341 MonoReflectionEvent *
4342 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
4345 MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
4346 mono_error_set_pending_exception (&error);
4351 typebuilder_setup_events (MonoClass *klass, MonoError *error)
4353 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4354 MonoReflectionEventBuilder *eb;
4355 MonoImage *image = klass->image;
4359 mono_error_init (error);
4362 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4364 klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
4365 klass->ext->event.first = 0;
4367 events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
4368 klass->ext->events = events;
4369 for (i = 0; i < klass->ext->event.count; ++i) {
4370 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
4371 events [i].parent = klass;
4372 events [i].attrs = eb->attrs;
4373 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
4374 if (!mono_error_ok (error))
4377 events [i].add = eb->add_method->mhandle;
4378 if (eb->remove_method)
4379 events [i].remove = eb->remove_method->mhandle;
4380 if (eb->raise_method)
4381 events [i].raise = eb->raise_method->mhandle;
4383 #ifndef MONO_SMALL_CONFIG
4384 if (eb->other_methods) {
4386 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
4387 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4388 MonoReflectionMethodBuilder *mb =
4389 mono_array_get (eb->other_methods,
4390 MonoReflectionMethodBuilder*, j);
4391 events [i].other [j] = mb->mhandle;
4395 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
4399 struct remove_instantiations_user_data
4406 remove_instantiations_of_and_ensure_contents (gpointer key,
4410 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
4411 MonoType *type = (MonoType*)key;
4412 MonoClass *klass = data->klass;
4413 gboolean already_failed = !is_ok (data->error);
4415 MonoError *error = already_failed ? &lerror : data->error;
4417 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
4418 MonoClass *inst_klass = mono_class_from_mono_type (type);
4419 //Ensure it's safe to use it.
4420 if (!fix_partial_generic_class (inst_klass, error)) {
4421 mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4422 // Marked the class with failure, but since some other instantiation already failed,
4423 // just report that one, and swallow the error from this one.
4425 mono_error_cleanup (error);
4433 check_array_for_usertypes (MonoArray *arr, MonoError *error)
4435 mono_error_init (error);
4441 for (i = 0; i < mono_array_length (arr); ++i) {
4442 RESOLVE_ARRAY_TYPE_ELEMENT (arr, i, error);
4443 if (!mono_error_ok (error))
4449 mono_reflection_check_array_for_usertypes (MonoArray *arr, MonoError *error)
4451 check_array_for_usertypes (arr, error);
4455 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4460 MonoReflectionType* res;
4463 mono_error_init (&error);
4465 domain = mono_object_domain (tb);
4466 klass = mono_class_from_mono_type (tb->type.type);
4469 * Check for user defined Type subclasses.
4471 RESOLVE_TYPE (tb->parent, &error);
4472 if (!is_ok (&error))
4473 goto failure_unlocked;
4474 check_array_for_usertypes (tb->interfaces, &error);
4475 if (!is_ok (&error))
4476 goto failure_unlocked;
4478 for (i = 0; i < mono_array_length (tb->fields); ++i) {
4479 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4481 RESOLVE_TYPE (fb->type, &error);
4482 if (!is_ok (&error))
4483 goto failure_unlocked;
4484 check_array_for_usertypes (fb->modreq, &error);
4485 if (!is_ok (&error))
4486 goto failure_unlocked;
4487 check_array_for_usertypes (fb->modopt, &error);
4488 if (!is_ok (&error))
4489 goto failure_unlocked;
4490 if (fb->marshal_info && fb->marshal_info->marshaltyperef) {
4491 RESOLVE_TYPE (fb->marshal_info->marshaltyperef, &error);
4492 if (!is_ok (&error))
4493 goto failure_unlocked;
4499 for (i = 0; i < mono_array_length (tb->methods); ++i) {
4500 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)mono_array_get (tb->methods, gpointer, i);
4502 RESOLVE_TYPE (mb->rtype, &error);
4503 if (!is_ok (&error))
4504 goto failure_unlocked;
4505 check_array_for_usertypes (mb->return_modreq, &error);
4506 if (!is_ok (&error))
4507 goto failure_unlocked;
4508 check_array_for_usertypes (mb->return_modopt, &error);
4509 if (!is_ok (&error))
4510 goto failure_unlocked;
4511 check_array_for_usertypes (mb->parameters, &error);
4512 if (!is_ok (&error))
4513 goto failure_unlocked;
4514 if (mb->param_modreq)
4515 for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
4516 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
4517 if (!is_ok (&error))
4518 goto failure_unlocked;
4520 if (mb->param_modopt)
4521 for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
4522 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
4523 if (!is_ok (&error))
4524 goto failure_unlocked;
4530 for (i = 0; i < mono_array_length (tb->ctors); ++i) {
4531 MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)mono_array_get (tb->ctors, gpointer, i);
4533 check_array_for_usertypes (mb->parameters, &error);
4534 if (!is_ok (&error))
4535 goto failure_unlocked;
4536 if (mb->param_modreq)
4537 for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
4538 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
4539 if (!is_ok (&error))
4540 goto failure_unlocked;
4542 if (mb->param_modopt)
4543 for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
4544 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
4545 if (!is_ok (&error))
4546 goto failure_unlocked;
4552 mono_save_custom_attrs (klass->image, klass, tb->cattrs);
4555 * we need to lock the domain because the lock will be taken inside
4556 * So, we need to keep the locking order correct.
4558 mono_loader_lock ();
4559 mono_domain_lock (domain);
4560 if (klass->wastypebuilder) {
4561 mono_domain_unlock (domain);
4562 mono_loader_unlock ();
4564 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4565 mono_error_set_pending_exception (&error);
4570 * Fields to set in klass:
4571 * the various flags: delegate/unicode/contextbound etc.
4573 klass->flags = tb->attrs;
4574 klass->has_cctor = 1;
4576 mono_class_setup_parent (klass, klass->parent);
4577 /* fool mono_class_setup_supertypes */
4578 klass->supertypes = NULL;
4579 mono_class_setup_supertypes (klass);
4580 mono_class_setup_mono_type (klass);
4583 if (!((MonoDynamicImage*)klass->image)->run) {
4584 if (klass->generic_container) {
4585 /* FIXME: The code below can't handle generic classes */
4586 klass->wastypebuilder = TRUE;
4587 mono_loader_unlock ();
4588 mono_domain_unlock (domain);
4590 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4591 mono_error_set_pending_exception (&error);
4598 /* enums are done right away */
4599 if (!klass->enumtype)
4600 if (!ensure_runtime_vtable (klass, &error))
4604 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
4605 MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
4606 mono_class_alloc_ext (klass);
4607 MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
4608 if (!is_ok (&error)) goto failure;
4609 klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
4613 klass->nested_classes_inited = TRUE;
4615 /* fields and object layout */
4616 if (klass->parent) {
4617 if (!klass->parent->size_inited)
4618 mono_class_init (klass->parent);
4619 klass->instance_size = klass->parent->instance_size;
4620 klass->sizes.class_size = 0;
4621 klass->min_align = klass->parent->min_align;
4622 /* if the type has no fields we won't call the field_setup
4623 * routine which sets up klass->has_references.
4625 klass->has_references |= klass->parent->has_references;
4627 klass->instance_size = sizeof (MonoObject);
4628 klass->min_align = 1;
4631 /* FIXME: handle packing_size and instance_size */
4632 typebuilder_setup_fields (klass, &error);
4633 if (!mono_error_ok (&error))
4635 typebuilder_setup_properties (klass, &error);
4636 if (!mono_error_ok (&error))
4639 typebuilder_setup_events (klass, &error);
4640 if (!mono_error_ok (&error))
4643 klass->wastypebuilder = TRUE;
4646 * If we are a generic TypeBuilder, there might be instantiations in the type cache
4647 * which have type System.Reflection.MonoGenericClass, but after the type is created,
4648 * we want to return normal System.MonoType objects, so clear these out from the cache.
4650 * Together with this we must ensure the contents of all instances to match the created type.
4652 if (domain->type_hash && klass->generic_container) {
4653 struct remove_instantiations_user_data data;
4655 data.error = &error;
4656 mono_error_assert_ok (&error);
4657 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
4658 if (!is_ok (&error))
4662 mono_domain_unlock (domain);
4663 mono_loader_unlock ();
4665 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
4666 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4667 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
4668 goto failure_unlocked;
4671 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4672 if (!is_ok (&error))
4673 goto failure_unlocked;
4675 g_assert (res != (MonoReflectionType*)tb);
4680 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4681 klass->wastypebuilder = TRUE;
4682 mono_domain_unlock (domain);
4683 mono_loader_unlock ();
4685 mono_error_set_pending_exception (&error);
4690 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
4692 MonoGenericParamFull *param;
4696 mono_error_init (error);
4698 image = &gparam->tbuilder->module->dynamic_image->image;
4700 param = mono_image_new0 (image, MonoGenericParamFull, 1);
4702 param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
4703 mono_error_assert_ok (error);
4704 param->param.num = gparam->index;
4706 if (gparam->mbuilder) {
4707 if (!gparam->mbuilder->generic_container) {
4708 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
4709 return_val_if_nok (error, FALSE);
4711 MonoClass *klass = mono_class_from_mono_type (tb);
4712 gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4713 gparam->mbuilder->generic_container->is_method = TRUE;
4715 * Cannot set owner.method, since the MonoMethod is not created yet.
4716 * Set the image field instead, so type_in_image () works.
4718 gparam->mbuilder->generic_container->is_anonymous = TRUE;
4719 gparam->mbuilder->generic_container->owner.image = klass->image;
4721 param->param.owner = gparam->mbuilder->generic_container;
4722 } else if (gparam->tbuilder) {
4723 if (!gparam->tbuilder->generic_container) {
4724 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
4725 return_val_if_nok (error, FALSE);
4726 MonoClass *klass = mono_class_from_mono_type (tb);
4727 gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4728 gparam->tbuilder->generic_container->owner.klass = klass;
4730 param->param.owner = gparam->tbuilder->generic_container;
4733 pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
4735 gparam->type.type = &pklass->byval_arg;
4737 mono_class_set_ref_info (pklass, gparam);
4738 mono_image_append_class_to_reflection_info_set (pklass);
4744 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
4747 (void) reflection_initialize_generic_parameter (gparam, &error);
4748 mono_error_set_pending_exception (&error);
4755 } DynamicMethodReleaseData;
4758 * The runtime automatically clean up those after finalization.
4760 static MonoReferenceQueue *dynamic_method_queue;
4763 free_dynamic_method (void *dynamic_method)
4765 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
4766 MonoDomain *domain = data->domain;
4767 MonoMethod *method = data->handle;
4770 mono_domain_lock (domain);
4771 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
4772 g_hash_table_remove (domain->method_to_dyn_method, method);
4773 mono_domain_unlock (domain);
4774 g_assert (dis_link);
4775 mono_gchandle_free (dis_link);
4777 mono_runtime_free_method (domain, method);
4782 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
4784 MonoReferenceQueue *queue;
4786 DynamicMethodReleaseData *release_data;
4787 ReflectionMethodBuilder rmb;
4788 MonoMethodSignature *sig;
4794 mono_error_init (error);
4796 if (mono_runtime_is_shutting_down ()) {
4797 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
4801 if (!(queue = dynamic_method_queue)) {
4802 mono_loader_lock ();
4803 if (!(queue = dynamic_method_queue))
4804 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
4805 mono_loader_unlock ();
4808 sig = dynamic_method_to_signature (mb, error);
4809 return_val_if_nok (error, FALSE);
4811 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
4814 * Resolve references.
4817 * Every second entry in the refs array is reserved for storing handle_class,
4818 * which is needed by the ldtoken implementation in the JIT.
4820 rmb.nrefs = mb->nrefs;
4821 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
4822 for (i = 0; i < mb->nrefs; i += 2) {
4823 MonoClass *handle_class;
4825 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
4827 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4828 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4830 * The referenced DynamicMethod should already be created by the managed
4831 * code, except in the case of circular references. In that case, we store
4832 * method in the refs array, and fix it up later when the referenced
4833 * DynamicMethod is created.
4835 if (method->mhandle) {
4836 ref = method->mhandle;
4838 /* FIXME: GC object stored in unmanaged memory */
4841 /* FIXME: GC object stored in unmanaged memory */
4842 method->referenced_by = g_slist_append (method->referenced_by, mb);
4844 handle_class = mono_defaults.methodhandle_class;
4846 MonoException *ex = NULL;
4847 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
4848 if (!is_ok (error)) {
4853 ex = mono_get_exception_type_load (NULL, NULL);
4854 else if (mono_security_core_clr_enabled ())
4855 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
4859 mono_error_set_exception_instance (error, ex);
4864 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4865 rmb.refs [i + 1] = handle_class;
4869 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
4870 if (!is_ok (error)) {
4874 klass = mono_class_from_mono_type (owner_type);
4876 klass = mono_defaults.object_class;
4879 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
4881 return_val_if_nok (error, FALSE);
4883 release_data = g_new (DynamicMethodReleaseData, 1);
4884 release_data->handle = handle;
4885 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
4886 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
4887 g_free (release_data);
4889 /* Fix up refs entries pointing at us */
4890 for (l = mb->referenced_by; l; l = l->next) {
4891 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
4892 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
4895 g_assert (method->mhandle);
4897 data = (gpointer*)wrapper->method_data;
4898 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
4899 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
4900 data [i + 1] = mb->mhandle;
4903 g_slist_free (mb->referenced_by);
4905 /* ilgen is no longer needed */
4908 domain = mono_domain_get ();
4909 mono_domain_lock (domain);
4910 if (!domain->method_to_dyn_method)
4911 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4912 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4913 mono_domain_unlock (domain);
4919 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4922 (void) reflection_create_dynamic_method (mb, &error);
4923 mono_error_set_pending_exception (&error);
4926 #endif /* DISABLE_REFLECTION_EMIT */
4928 MonoMethodSignature *
4929 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4931 MonoMethodSignature *sig;
4932 g_assert (image_is_dynamic (image));
4934 mono_error_init (error);
4936 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4940 return mono_method_signature_checked (method, error);
4943 #ifndef DISABLE_REFLECTION_EMIT
4946 * ensure_complete_type:
4948 * Ensure that KLASS is completed if it is a dynamic type, or references
4952 ensure_complete_type (MonoClass *klass, MonoError *error)
4954 mono_error_init (error);
4956 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
4957 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4959 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4960 return_if_nok (error);
4962 // Asserting here could break a lot of code
4963 //g_assert (klass->wastypebuilder);
4966 if (klass->generic_class) {
4967 MonoGenericInst *inst = klass->generic_class->context.class_inst;
4970 for (i = 0; i < inst->type_argc; ++i) {
4971 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4972 return_if_nok (error);
4978 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4980 gpointer result = NULL;
4982 mono_error_init (error);
4984 if (strcmp (obj->vtable->klass->name, "String") == 0) {
4985 result = mono_string_intern_checked ((MonoString*)obj, error);
4986 return_val_if_nok (error, NULL);
4987 *handle_class = mono_defaults.string_class;
4989 } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
4990 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4991 return_val_if_nok (error, NULL);
4992 MonoClass *mc = mono_class_from_mono_type (type);
4993 if (!mono_class_init (mc)) {
4994 mono_error_set_for_class_failure (error, mc);
4999 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
5000 return_val_if_nok (error, NULL);
5002 result = mono_class_from_mono_type (inflated);
5003 mono_metadata_free_type (inflated);
5005 result = mono_class_from_mono_type (type);
5007 *handle_class = mono_defaults.typehandle_class;
5009 } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
5010 strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
5011 strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
5012 strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
5013 result = ((MonoReflectionMethod*)obj)->method;
5015 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5016 mono_error_assert_ok (error);
5018 *handle_class = mono_defaults.methodhandle_class;
5020 } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
5021 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
5022 result = mb->mhandle;
5024 /* Type is not yet created */
5025 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
5027 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5028 return_val_if_nok (error, NULL);
5031 * Hopefully this has been filled in by calling CreateType() on the
5035 * TODO: This won't work if the application finishes another
5036 * TypeBuilder instance instead of this one.
5038 result = mb->mhandle;
5041 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5042 mono_error_assert_ok (error);
5044 *handle_class = mono_defaults.methodhandle_class;
5045 } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
5046 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
5048 result = cb->mhandle;
5050 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
5052 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5053 return_val_if_nok (error, NULL);
5054 result = cb->mhandle;
5057 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5058 mono_error_assert_ok (error);
5060 *handle_class = mono_defaults.methodhandle_class;
5061 } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
5062 MonoClassField *field = ((MonoReflectionField*)obj)->field;
5064 ensure_complete_type (field->parent, error);
5065 return_val_if_nok (error, NULL);
5068 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
5069 return_val_if_nok (error, NULL);
5071 MonoClass *klass = mono_class_from_mono_type (inflated);
5072 MonoClassField *inflated_field;
5073 gpointer iter = NULL;
5074 mono_metadata_free_type (inflated);
5075 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
5076 if (!strcmp (field->name, inflated_field->name))
5079 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
5080 result = inflated_field;
5084 *handle_class = mono_defaults.fieldhandle_class;
5086 } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
5087 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
5088 result = fb->handle;
5091 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
5093 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5094 return_val_if_nok (error, NULL);
5095 result = fb->handle;
5098 if (fb->handle && fb->handle->parent->generic_container) {
5099 MonoClass *klass = fb->handle->parent;
5100 MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
5101 return_val_if_nok (error, NULL);
5103 MonoClass *inflated = mono_class_from_mono_type (type);
5105 result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
5107 mono_metadata_free_type (type);
5109 *handle_class = mono_defaults.fieldhandle_class;
5110 } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
5111 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
5112 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
5113 return_val_if_nok (error, NULL);
5116 klass = type->data.klass;
5117 if (klass->wastypebuilder) {
5118 /* Already created */
5122 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5123 return_val_if_nok (error, NULL);
5124 result = type->data.klass;
5127 *handle_class = mono_defaults.typehandle_class;
5128 } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
5129 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
5130 MonoMethodSignature *sig;
5133 if (helper->arguments)
5134 nargs = mono_array_length (helper->arguments);
5138 sig = mono_metadata_signature_alloc (image, nargs);
5139 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
5140 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
5142 if (helper->unmanaged_call_conv) { /* unmanaged */
5143 sig->call_convention = helper->unmanaged_call_conv - 1;
5144 sig->pinvoke = TRUE;
5145 } else if (helper->call_conv & 0x02) {
5146 sig->call_convention = MONO_CALL_VARARG;
5148 sig->call_convention = MONO_CALL_DEFAULT;
5151 sig->param_count = nargs;
5152 /* TODO: Copy type ? */
5153 sig->ret = helper->return_type->type;
5154 for (i = 0; i < nargs; ++i) {
5155 sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
5156 if (!is_ok (error)) {
5157 image_g_free (image, sig);
5163 *handle_class = NULL;
5164 } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
5165 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
5166 /* Already created by the managed code */
5167 g_assert (method->mhandle);
5168 result = method->mhandle;
5169 *handle_class = mono_defaults.methodhandle_class;
5170 } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
5171 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
5172 return_val_if_nok (error, NULL);
5173 type = mono_class_inflate_generic_type_checked (type, context, error);
5174 return_val_if_nok (error, NULL);
5176 result = mono_class_from_mono_type (type);
5177 *handle_class = mono_defaults.typehandle_class;
5179 mono_metadata_free_type (type);
5180 } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
5181 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
5182 return_val_if_nok (error, NULL);
5183 type = mono_class_inflate_generic_type_checked (type, context, error);
5184 return_val_if_nok (error, NULL);
5186 result = mono_class_from_mono_type (type);
5187 *handle_class = mono_defaults.typehandle_class;
5189 mono_metadata_free_type (type);
5190 } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
5191 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
5192 MonoClass *inflated;
5194 MonoClassField *field;
5196 if (is_sre_field_builder (mono_object_class (f->fb)))
5197 field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
5198 else if (is_sr_mono_field (mono_object_class (f->fb)))
5199 field = ((MonoReflectionField*)f->fb)->field;
5201 g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
5203 MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
5204 return_val_if_nok (error, NULL);
5205 type = mono_class_inflate_generic_type_checked (finst, context, error);
5206 return_val_if_nok (error, NULL);
5208 inflated = mono_class_from_mono_type (type);
5210 result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
5211 ensure_complete_type (field->parent, error);
5212 if (!is_ok (error)) {
5213 mono_metadata_free_type (type);
5218 mono_metadata_free_type (type);
5219 *handle_class = mono_defaults.fieldhandle_class;
5220 } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
5221 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
5222 MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
5223 return_val_if_nok (error, NULL);
5224 MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
5225 return_val_if_nok (error, NULL);
5227 MonoClass *inflated_klass = mono_class_from_mono_type (type);
5230 if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
5231 method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
5232 else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
5233 method = ((MonoReflectionMethod *)c->cb)->method;
5235 g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
5237 result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
5238 *handle_class = mono_defaults.methodhandle_class;
5239 mono_metadata_free_type (type);
5240 } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
5241 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
5242 if (m->method_args) {
5243 result = mono_reflection_method_on_tb_inst_get_handle (m, error);
5244 return_val_if_nok (error, NULL);
5246 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5247 mono_error_assert_ok (error);
5250 MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
5251 return_val_if_nok (error, NULL);
5252 MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
5253 return_val_if_nok (error, NULL);
5255 MonoClass *inflated_klass = mono_class_from_mono_type (type);
5258 if (is_sre_method_builder (mono_object_class (m->mb)))
5259 method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
5260 else if (is_sr_mono_method (mono_object_class (m->mb)))
5261 method = ((MonoReflectionMethod *)m->mb)->method;
5263 g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
5265 result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
5266 mono_metadata_free_type (type);
5268 *handle_class = mono_defaults.methodhandle_class;
5269 } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
5270 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
5277 mtype = mono_reflection_type_get_handle (m->parent, error);
5278 return_val_if_nok (error, NULL);
5279 klass = mono_class_from_mono_type (mtype);
5281 /* Find the method */
5283 name = mono_string_to_utf8_checked (m->name, error);
5284 return_val_if_nok (error, NULL);
5286 while ((method = mono_class_get_methods (klass, &iter))) {
5287 if (!strcmp (method->name, name))
5294 // FIXME: Check parameters/return value etc. match
5297 *handle_class = mono_defaults.methodhandle_class;
5298 } else if (is_sre_array (mono_object_get_class(obj)) ||
5299 is_sre_byref (mono_object_get_class(obj)) ||
5300 is_sre_pointer (mono_object_get_class(obj))) {
5301 MonoReflectionType *ref_type = (MonoReflectionType *)obj;
5302 MonoType *type = mono_reflection_type_get_handle (ref_type, error);
5303 return_val_if_nok (error, NULL);
5306 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
5307 return_val_if_nok (error, NULL);
5309 result = mono_class_from_mono_type (inflated);
5310 mono_metadata_free_type (inflated);
5312 result = mono_class_from_mono_type (type);
5314 *handle_class = mono_defaults.typehandle_class;
5316 g_print ("%s\n", obj->vtable->klass->name);
5317 g_assert_not_reached ();
5322 #else /* DISABLE_REFLECTION_EMIT */
5325 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5327 g_assert_not_reached ();
5332 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
5334 g_assert_not_reached ();
5338 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
5340 g_assert_not_reached ();
5344 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
5346 g_assert_not_reached ();
5351 ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
5353 g_assert_not_reached ();
5357 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5359 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
5363 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
5365 g_assert_not_reached ();
5368 MonoReflectionModule *
5369 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
5371 g_assert_not_reached ();
5376 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
5378 g_assert_not_reached ();
5383 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
5385 g_assert_not_reached ();
5390 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
5391 gboolean create_open_instance, gboolean register_token, MonoError *error)
5393 g_assert_not_reached ();
5398 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
5400 g_assert_not_reached ();
5404 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
5406 mono_error_init (error);
5411 MonoReflectionEvent *
5412 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
5414 g_assert_not_reached ();
5419 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
5421 g_assert_not_reached ();
5426 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
5428 g_assert_not_reached ();
5432 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
5437 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
5439 mono_error_init (error);
5445 #endif /* DISABLE_REFLECTION_EMIT */
5447 #ifndef DISABLE_REFLECTION_EMIT
5449 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5454 tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
5455 return_val_if_nok (error, NULL);
5456 klass = mono_class_from_mono_type (tb);
5458 return methodbuilder_to_mono_method (klass, mb, error);
5460 #else /* DISABLE_REFLECTION_EMIT */
5462 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5464 g_assert_not_reached ();
5467 #endif /* DISABLE_REFLECTION_EMIT */
5470 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
5472 MONO_CHECK_ARG_NULL (obj, 0);
5475 gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
5476 mono_error_set_pending_exception (&error);
5481 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
5482 MonoReflectionMethod *method,
5483 MonoArray *opt_param_types)
5485 MONO_CHECK_ARG_NULL (method, 0);
5488 gint32 result = mono_image_create_method_token (
5489 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
5490 mono_error_set_pending_exception (&error);
5495 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
5498 mono_image_create_pefile (mb, file, &error);
5499 mono_error_set_pending_exception (&error);
5503 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
5506 mono_image_build_metadata (mb, &error);
5507 mono_error_set_pending_exception (&error);
5511 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
5513 mono_image_register_token (mb->dynamic_image, token, obj);
5517 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
5521 mono_loader_lock ();
5522 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
5523 mono_loader_unlock ();
5528 MonoReflectionModule*
5529 ves_icall_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
5532 MonoReflectionModule *result = mono_image_load_module_dynamic (ab, fileName, &error);
5533 mono_error_set_pending_exception (&error);
5538 * ves_icall_TypeBuilder_create_generic_class:
5539 * @tb: a TypeBuilder object
5542 * Creates the generic class after all generic parameters have been added.
5545 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
5548 (void) mono_reflection_create_generic_class (tb, &error);
5549 mono_error_set_pending_exception (&error);
5552 #ifndef DISABLE_REFLECTION_EMIT
5554 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5557 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
5558 mono_error_set_pending_exception (&error);
5564 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5566 mono_reflection_dynimage_basic_init (assemblyb);
5570 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
5572 return mono_type_is_generic_parameter (tb->type.type);
5576 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
5577 MonoReflectionType *t)
5579 enumtype->type = t->type;
5583 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5586 MonoReflectionType *ret;
5588 int isbyref = 0, rank;
5590 char *str = mono_string_to_utf8_checked (smodifiers, &error);
5591 if (mono_error_set_pending_exception (&error))
5594 klass = mono_class_from_mono_type (tb->type.type);
5596 /* logic taken from mono_reflection_parse_type(): keep in sync */
5600 if (isbyref) { /* only one level allowed by the spec */
5609 ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
5610 mono_error_set_pending_exception (&error);
5614 klass = mono_ptr_class_get (&klass->byval_arg);
5615 mono_class_init (klass);
5626 else if (*p != '*') { /* '*' means unknown lower bound */
5637 klass = mono_array_class_get (klass, rank);
5638 mono_class_init (klass);
5647 ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
5648 mono_error_set_pending_exception (&error);
5654 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
5656 mono_image_module_basic_init (moduleb);
5660 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
5662 return mono_image_insert_string (module, str);
5666 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
5668 MonoDynamicImage *image = moduleb->dynamic_image;
5670 g_assert (type->type);
5671 image->wrappers_type = mono_class_from_mono_type (type->type);