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 mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
82 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
85 mono_reflection_emit_init (void)
87 mono_dynamic_images_init ();
91 type_get_fully_qualified_name (MonoType *type)
93 MONO_REQ_GC_NEUTRAL_MODE;
95 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
99 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
101 MONO_REQ_GC_UNSAFE_MODE;
106 klass = mono_class_from_mono_type (type);
108 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
109 ta = klass->image->assembly;
110 if (assembly_is_dynamic (ta) || (ta == ass)) {
111 if (klass->generic_class || klass->generic_container)
112 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
113 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
115 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
118 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
121 #ifndef DISABLE_REFLECTION_EMIT
125 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
129 image_g_malloc (MonoImage *image, guint size)
131 MONO_REQ_GC_NEUTRAL_MODE;
134 return mono_image_alloc (image, size);
136 return g_malloc (size);
138 #endif /* !DISABLE_REFLECTION_EMIT */
143 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
147 mono_image_g_malloc0 (MonoImage *image, guint size)
149 MONO_REQ_GC_NEUTRAL_MODE;
152 return mono_image_alloc0 (image, size);
154 return g_malloc0 (size);
159 * @image: a MonoImage
162 * If @image is NULL, free @ptr, otherwise do nothing.
165 image_g_free (MonoImage *image, gpointer ptr)
171 #ifndef DISABLE_REFLECTION_EMIT
173 image_strdup (MonoImage *image, const char *s)
175 MONO_REQ_GC_NEUTRAL_MODE;
178 return mono_image_strdup (image, s);
184 #define image_g_new(image,struct_type, n_structs) \
185 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
187 #define image_g_new0(image,struct_type, n_structs) \
188 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
192 alloc_table (MonoDynamicTable *table, guint nrows)
194 mono_dynimage_alloc_table (table, nrows);
198 string_heap_insert (MonoDynamicStream *sh, const char *str)
200 return mono_dynstream_insert_string (sh, str);
204 string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
206 return mono_dynstream_insert_mstring (sh, str, error);
210 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
212 return mono_dynstream_add_data (stream, data, len);
216 mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
218 return mono_dynstream_add_zero (stream, len);
222 stream_data_align (MonoDynamicStream *stream)
224 mono_dynstream_data_align (stream);
228 * Despite the name, we handle also TypeSpec (with the above helper).
231 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
233 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
237 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
238 * dest may be misaligned.
241 swap_with_size (char *dest, const char* val, int len, int nelem) {
242 MONO_REQ_GC_NEUTRAL_MODE;
243 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
246 for (elem = 0; elem < nelem; ++elem) {
272 g_assert_not_reached ();
278 memcpy (dest, val, len * nelem);
282 #ifndef DISABLE_REFLECTION_EMIT
284 default_class_from_mono_type (MonoType *type)
286 MONO_REQ_GC_NEUTRAL_MODE;
288 switch (type->type) {
289 case MONO_TYPE_OBJECT:
290 return mono_defaults.object_class;
292 return mono_defaults.void_class;
293 case MONO_TYPE_BOOLEAN:
294 return mono_defaults.boolean_class;
296 return mono_defaults.char_class;
298 return mono_defaults.sbyte_class;
300 return mono_defaults.byte_class;
302 return mono_defaults.int16_class;
304 return mono_defaults.uint16_class;
306 return mono_defaults.int32_class;
308 return mono_defaults.uint32_class;
310 return mono_defaults.int_class;
312 return mono_defaults.uint_class;
314 return mono_defaults.int64_class;
316 return mono_defaults.uint64_class;
318 return mono_defaults.single_class;
320 return mono_defaults.double_class;
321 case MONO_TYPE_STRING:
322 return mono_defaults.string_class;
324 g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
325 g_assert_not_reached ();
333 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
335 MONO_REQ_GC_UNSAFE_MODE;
337 guint32 num_clauses = 0;
340 MonoILExceptionInfo *ex_info;
341 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
342 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
343 if (ex_info->handlers)
344 num_clauses += mono_array_length (ex_info->handlers);
352 #ifndef DISABLE_REFLECTION_EMIT
353 static MonoExceptionClause*
354 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
356 MONO_REQ_GC_UNSAFE_MODE;
358 mono_error_init (error);
360 MonoExceptionClause *clauses;
361 MonoExceptionClause *clause;
362 MonoILExceptionInfo *ex_info;
363 MonoILExceptionBlock *ex_block;
364 guint32 finally_start;
365 int i, j, clause_index;;
367 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
370 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
371 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
372 finally_start = ex_info->start + ex_info->len;
373 if (!ex_info->handlers)
375 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
376 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
377 clause = &(clauses [clause_index]);
379 clause->flags = ex_block->type;
380 clause->try_offset = ex_info->start;
382 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
383 clause->try_len = finally_start - ex_info->start;
385 clause->try_len = ex_info->len;
386 clause->handler_offset = ex_block->start;
387 clause->handler_len = ex_block->len;
388 if (ex_block->extype) {
389 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
391 if (!is_ok (error)) {
392 image_g_free (image, clauses);
395 clause->data.catch_class = mono_class_from_mono_type (extype);
397 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
398 clause->data.filter_offset = ex_block->filter_offset;
400 clause->data.filter_offset = 0;
402 finally_start = ex_block->start + ex_block->len;
410 #endif /* !DISABLE_REFLECTION_EMIT */
412 #ifndef DISABLE_REFLECTION_EMIT
414 * LOCKING: Acquires the loader lock.
417 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
419 MONO_REQ_GC_UNSAFE_MODE;
421 MonoCustomAttrInfo *ainfo, *tmp;
423 if (!cattrs || !mono_array_length (cattrs))
426 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
429 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
431 mono_custom_attrs_free (tmp);
432 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
433 mono_loader_unlock ();
440 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
442 MONO_REQ_GC_UNSAFE_MODE;
444 MonoDynamicTable *table;
447 guint32 cols [MONO_ASSEMBLY_SIZE];
451 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
454 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
455 table = &assembly->tables [MONO_TABLE_MODULEREF];
456 token = table->next_idx ++;
458 alloc_table (table, table->rows);
459 values = table->values + token * MONO_MODULEREF_SIZE;
460 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
462 token <<= MONO_RESOLUTION_SCOPE_BITS;
463 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
464 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
469 if (assembly_is_dynamic (image->assembly))
471 memset (cols, 0, sizeof (cols));
473 /* image->assembly->image is the manifest module */
474 image = image->assembly->image;
475 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
478 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
479 token = table->next_idx ++;
481 alloc_table (table, table->rows);
482 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
483 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
484 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
485 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
486 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
487 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
488 values [MONO_ASSEMBLYREF_FLAGS] = 0;
489 values [MONO_ASSEMBLYREF_CULTURE] = 0;
490 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
492 if (strcmp ("", image->assembly->aname.culture)) {
493 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
494 image->assembly->aname.culture);
497 if ((pubkey = mono_image_get_public_key (image, &publen))) {
500 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
501 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
503 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
505 token <<= MONO_RESOLUTION_SCOPE_BITS;
506 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
507 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
511 #ifndef DISABLE_REFLECTION_EMIT
513 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
515 MONO_REQ_GC_UNSAFE_MODE;
517 mono_error_init (error);
518 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
520 rmb->ilgen = mb->ilgen;
521 rmb->rtype = (MonoReflectionType*)mb->rtype;
522 return_val_if_nok (error, FALSE);
523 rmb->parameters = mb->parameters;
524 rmb->generic_params = mb->generic_params;
525 rmb->generic_container = mb->generic_container;
526 rmb->opt_types = NULL;
527 rmb->pinfo = mb->pinfo;
528 rmb->attrs = mb->attrs;
529 rmb->iattrs = mb->iattrs;
530 rmb->call_conv = mb->call_conv;
531 rmb->code = mb->code;
532 rmb->type = mb->type;
533 rmb->name = mb->name;
534 rmb->table_idx = &mb->table_idx;
535 rmb->init_locals = mb->init_locals;
536 rmb->skip_visibility = FALSE;
537 rmb->return_modreq = mb->return_modreq;
538 rmb->return_modopt = mb->return_modopt;
539 rmb->param_modreq = mb->param_modreq;
540 rmb->param_modopt = mb->param_modopt;
541 rmb->permissions = mb->permissions;
542 rmb->mhandle = mb->mhandle;
547 rmb->charset = mb->charset;
548 rmb->extra_flags = mb->extra_flags;
549 rmb->native_cc = mb->native_cc;
550 rmb->dllentry = mb->dllentry;
558 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
560 MONO_REQ_GC_UNSAFE_MODE;
562 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
564 mono_error_init (error);
566 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
568 rmb->ilgen = mb->ilgen;
569 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
570 return_val_if_nok (error, FALSE);
571 rmb->parameters = mb->parameters;
572 rmb->generic_params = NULL;
573 rmb->generic_container = NULL;
574 rmb->opt_types = NULL;
575 rmb->pinfo = mb->pinfo;
576 rmb->attrs = mb->attrs;
577 rmb->iattrs = mb->iattrs;
578 rmb->call_conv = mb->call_conv;
580 rmb->type = mb->type;
581 rmb->name = mono_string_new (mono_domain_get (), name);
582 rmb->table_idx = &mb->table_idx;
583 rmb->init_locals = mb->init_locals;
584 rmb->skip_visibility = FALSE;
585 rmb->return_modreq = NULL;
586 rmb->return_modopt = NULL;
587 rmb->param_modreq = mb->param_modreq;
588 rmb->param_modopt = mb->param_modopt;
589 rmb->permissions = mb->permissions;
590 rmb->mhandle = mb->mhandle;
598 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
600 MONO_REQ_GC_UNSAFE_MODE;
602 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
604 rmb->ilgen = mb->ilgen;
605 rmb->rtype = mb->rtype;
606 rmb->parameters = mb->parameters;
607 rmb->generic_params = NULL;
608 rmb->generic_container = NULL;
609 rmb->opt_types = NULL;
611 rmb->attrs = mb->attrs;
613 rmb->call_conv = mb->call_conv;
615 rmb->type = (MonoObject *) mb->owner;
616 rmb->name = mb->name;
617 rmb->table_idx = NULL;
618 rmb->init_locals = mb->init_locals;
619 rmb->skip_visibility = mb->skip_visibility;
620 rmb->return_modreq = NULL;
621 rmb->return_modopt = NULL;
622 rmb->param_modreq = NULL;
623 rmb->param_modopt = NULL;
624 rmb->permissions = NULL;
625 rmb->mhandle = mb->mhandle;
629 #else /* DISABLE_REFLECTION_EMIT */
631 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
632 g_assert_not_reached ();
636 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
638 g_assert_not_reached ();
641 #endif /* DISABLE_REFLECTION_EMIT */
643 #ifndef DISABLE_REFLECTION_EMIT
645 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
647 MONO_REQ_GC_NEUTRAL_MODE;
649 MonoDynamicTable *table;
651 guint32 token, pclass;
653 switch (parent & MONO_TYPEDEFORREF_MASK) {
654 case MONO_TYPEDEFORREF_TYPEREF:
655 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
657 case MONO_TYPEDEFORREF_TYPESPEC:
658 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
660 case MONO_TYPEDEFORREF_TYPEDEF:
661 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
664 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
667 /* extract the index */
668 parent >>= MONO_TYPEDEFORREF_BITS;
670 table = &assembly->tables [MONO_TABLE_MEMBERREF];
672 if (assembly->save) {
673 alloc_table (table, table->rows + 1);
674 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
675 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
676 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
677 values [MONO_MEMBERREF_SIGNATURE] = sig;
680 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
687 * Insert a memberef row into the metadata: the token that point to the memberref
688 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
689 * mono_image_get_fieldref_token()).
690 * The sig param is an index to an already built signature.
693 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
695 MONO_REQ_GC_NEUTRAL_MODE;
697 guint32 parent = mono_image_typedef_or_ref (assembly, type);
698 return mono_image_add_memberef_row (assembly, parent, name, sig);
703 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
705 MONO_REQ_GC_NEUTRAL_MODE;
708 MonoMethodSignature *sig;
710 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
712 if (create_typespec) {
713 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
718 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
719 if (token && !create_typespec)
722 g_assert (!method->is_inflated);
725 * A methodref signature can't contain an unmanaged calling convention.
727 sig = mono_metadata_signature_dup (mono_method_signature (method));
728 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
729 sig->call_convention = MONO_CALL_DEFAULT;
730 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
731 method->name, mono_dynimage_encode_method_signature (assembly, sig));
733 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
736 if (create_typespec) {
737 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
738 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
739 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
741 if (assembly->save) {
744 alloc_table (table, table->rows + 1);
745 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
746 values [MONO_METHODSPEC_METHOD] = token;
747 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
750 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
752 /*methodspec and memberef tokens are diferent, */
753 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
760 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
762 guint32 token, parent, sig;
763 ReflectionMethodBuilder rmb;
764 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
766 mono_error_init (error);
767 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
771 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
775 * A methodref signature can't contain an unmanaged calling convention.
776 * Since some flags are encoded as part of call_conv, we need to check against it.
778 if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
779 rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
781 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
782 return_val_if_nok (error, 0);
784 if (tb->generic_params) {
785 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
786 return_val_if_nok (error, 0);
788 MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
789 return_val_if_nok (error, 0);
791 parent = mono_image_typedef_or_ref (assembly, t);
794 char *name = mono_string_to_utf8_checked (method->name, error);
795 return_val_if_nok (error, 0);
797 token = mono_image_add_memberef_row (assembly, parent, name, sig);
800 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
806 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
807 const gchar *name, guint32 sig)
809 MonoDynamicTable *table;
813 table = &assembly->tables [MONO_TABLE_MEMBERREF];
815 if (assembly->save) {
816 alloc_table (table, table->rows + 1);
817 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
818 values [MONO_MEMBERREF_CLASS] = original;
819 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
820 values [MONO_MEMBERREF_SIGNATURE] = sig;
823 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
830 mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
832 MonoDynamicTable *table;
834 guint32 token, mtoken = 0;
836 mono_error_init (error);
837 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
841 table = &assembly->tables [MONO_TABLE_METHODSPEC];
843 mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
844 if (!mono_error_ok (error))
847 switch (mono_metadata_token_table (mtoken)) {
848 case MONO_TABLE_MEMBERREF:
849 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
851 case MONO_TABLE_METHOD:
852 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
855 g_assert_not_reached ();
858 if (assembly->save) {
859 alloc_table (table, table->rows + 1);
860 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
861 values [MONO_METHODSPEC_METHOD] = mtoken;
862 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
865 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
868 mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
873 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
877 mono_error_init (error);
879 if (mb->generic_params && create_methodspec)
880 return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
882 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
886 token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
887 if (!mono_error_ok (error))
889 mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
894 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
896 guint32 token, parent, sig;
897 ReflectionMethodBuilder rmb;
899 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
901 mono_error_init (error);
903 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
907 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
910 if (tb->generic_params) {
911 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
912 return_val_if_nok (error, 0);
914 MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
915 return_val_if_nok (error, 0);
916 parent = mono_image_typedef_or_ref (assembly, type);
919 name = mono_string_to_utf8_checked (rmb.name, error);
920 return_val_if_nok (error, 0);
921 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
922 return_val_if_nok (error, 0);
924 token = mono_image_add_memberef_row (assembly, parent, name, sig);
927 mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
933 is_field_on_inst (MonoClassField *field)
935 return field->parent->generic_class && field->parent->generic_class->is_dynamic;
938 #ifndef DISABLE_REFLECTION_EMIT
940 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
946 g_assert (field->parent);
948 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
952 if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
953 int index = field - field->parent->fields;
954 type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
956 type = mono_field_get_type (field);
958 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
959 mono_field_get_name (field),
960 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
961 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
966 mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
970 MonoGenericClass *gclass;
974 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
977 if (is_sre_field_builder (mono_object_class (f->fb))) {
978 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
979 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
980 return_val_if_nok (error, 0);
981 klass = mono_class_from_mono_type (type);
982 gclass = type->data.generic_class;
983 g_assert (gclass->is_dynamic);
985 guint32 sig_token = mono_dynimage_encode_field_signature (assembly, fb, error);
986 return_val_if_nok (error, 0);
987 name = mono_string_to_utf8_checked (fb->name, error);
988 return_val_if_nok (error, 0);
989 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
991 } else if (is_sr_mono_field (mono_object_class (f->fb))) {
993 MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
995 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
996 return_val_if_nok (error, 0);
997 klass = mono_class_from_mono_type (type);
999 sig = mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, field->type);
1000 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
1002 char *name = mono_type_get_full_name (mono_object_class (f->fb));
1003 g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
1006 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
1011 mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
1015 MonoGenericClass *gclass;
1018 mono_error_init (error);
1020 /* A ctor cannot be a generic method, so we can ignore create_methodspec */
1022 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
1026 if (mono_is_sre_ctor_builder (mono_object_class (c->cb))) {
1027 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
1028 ReflectionMethodBuilder rmb;
1031 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
1032 return_val_if_nok (error, 0);
1033 klass = mono_class_from_mono_type (type);
1035 gclass = type->data.generic_class;
1036 g_assert (gclass->is_dynamic);
1038 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
1041 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1042 return_val_if_nok (error, 0);
1044 name = mono_string_to_utf8_checked (rmb.name, error);
1045 return_val_if_nok (error, 0);
1047 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1049 } else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb))) {
1050 MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
1052 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
1053 return_val_if_nok (error, 0);
1054 klass = mono_class_from_mono_type (type);
1056 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1057 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1059 char *name = mono_type_get_full_name (mono_object_class (c->cb));
1060 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1064 mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
1069 mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
1072 MonoGenericContext tmp_context;
1073 MonoType **type_argv;
1074 MonoGenericInst *ginst;
1075 MonoMethod *method, *inflated;
1078 mono_error_init (error);
1080 mono_reflection_init_type_builder_generics ((MonoObject*)m->inst, error);
1081 return_val_if_nok (error, NULL);
1083 method = inflate_method (m->inst, (MonoObject*)m->mb, error);
1084 return_val_if_nok (error, NULL);
1086 klass = method->klass;
1088 if (m->method_args == NULL)
1091 if (method->is_inflated)
1092 method = ((MonoMethodInflated *) method)->declaring;
1094 count = mono_array_length (m->method_args);
1096 type_argv = g_new0 (MonoType *, count);
1097 for (i = 0; i < count; i++) {
1098 MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
1099 type_argv [i] = mono_reflection_type_get_handle (garg, error);
1100 return_val_if_nok (error, NULL);
1102 ginst = mono_metadata_get_generic_inst (count, type_argv);
1105 tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
1106 tmp_context.method_inst = ginst;
1108 inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
1109 mono_error_assert_ok (error);
1114 mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
1116 guint32 sig, token = 0;
1120 mono_error_init (error);
1122 if (m->method_args) {
1123 MonoMethod *inflated;
1125 inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
1126 return_val_if_nok (error, 0);
1128 if (create_methodspec)
1129 token = mono_image_get_methodspec_token (assembly, inflated);
1131 token = mono_image_get_inflated_method_token (assembly, inflated);
1135 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
1139 if (is_sre_method_builder (mono_object_class (m->mb))) {
1140 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
1141 MonoGenericClass *gclass;
1142 ReflectionMethodBuilder rmb;
1145 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1146 return_val_if_nok (error, 0);
1147 klass = mono_class_from_mono_type (type);
1148 gclass = type->data.generic_class;
1149 g_assert (gclass->is_dynamic);
1151 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1154 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1155 return_val_if_nok (error, 0);
1157 name = mono_string_to_utf8_checked (rmb.name, error);
1158 return_val_if_nok (error, 0);
1160 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1162 } else if (is_sr_mono_method (mono_object_class (m->mb))) {
1163 MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
1165 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1166 return_val_if_nok (error, 0);
1167 klass = mono_class_from_mono_type (type);
1169 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1170 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1172 char *name = mono_type_get_full_name (mono_object_class (m->mb));
1173 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1176 mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
1181 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
1183 MonoDynamicTable *table;
1185 guint32 token, mtoken = 0, sig;
1186 MonoMethodInflated *imethod;
1187 MonoMethod *declaring;
1189 table = &assembly->tables [MONO_TABLE_METHODSPEC];
1191 g_assert (method->is_inflated);
1192 imethod = (MonoMethodInflated *) method;
1193 declaring = imethod->declaring;
1195 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
1196 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
1198 if (!mono_method_signature (declaring)->generic_param_count)
1201 switch (mono_metadata_token_table (mtoken)) {
1202 case MONO_TABLE_MEMBERREF:
1203 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
1205 case MONO_TABLE_METHOD:
1206 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
1209 g_assert_not_reached ();
1212 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
1214 if (assembly->save) {
1215 alloc_table (table, table->rows + 1);
1216 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
1217 values [MONO_METHODSPEC_METHOD] = mtoken;
1218 values [MONO_METHODSPEC_SIGNATURE] = sig;
1221 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
1228 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
1230 MonoMethodInflated *imethod;
1233 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
1237 g_assert (method->is_inflated);
1238 imethod = (MonoMethodInflated *) method;
1240 if (mono_method_signature (imethod->declaring)->generic_param_count) {
1241 token = method_encode_methodspec (assembly, method);
1243 guint32 sig = mono_dynimage_encode_method_signature (
1244 assembly, mono_method_signature (imethod->declaring));
1245 token = mono_image_get_memberref_token (
1246 assembly, &method->klass->byval_arg, method->name, sig);
1249 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
1254 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
1256 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
1259 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
1260 token = mono_image_get_memberref_token (
1261 assembly, &m->klass->byval_arg, m->name, sig);
1267 * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
1270 add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
1272 int i, count, len, pos;
1275 mono_error_init (error);
1279 count += mono_array_length (modreq);
1281 count += mono_array_length (modopt);
1284 return mono_metadata_type_dup (NULL, type);
1286 len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
1287 t = (MonoType *)g_malloc (len);
1288 memcpy (t, type, MONO_SIZEOF_TYPE);
1290 t->num_mods = count;
1293 for (i = 0; i < mono_array_length (modreq); ++i) {
1294 MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
1297 t->modifiers [pos].required = 1;
1298 t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1303 for (i = 0; i < mono_array_length (modopt); ++i) {
1304 MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
1307 t->modifiers [pos].required = 0;
1308 t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1320 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
1322 MonoReflectionTypeBuilder *tb;
1324 mono_error_init (error);
1326 if (!is_sre_type_builder(mono_object_class (type)))
1328 tb = (MonoReflectionTypeBuilder *)type;
1330 if (tb && tb->generic_container)
1331 mono_reflection_create_generic_class (tb, error);
1335 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
1337 MonoDynamicTable *table;
1338 MonoType *custom = NULL, *type;
1340 guint32 token, pclass, parent, sig;
1343 mono_error_init (error);
1345 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
1349 MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
1350 return_val_if_nok (error, 0);
1351 /* FIXME: is this call necessary? */
1352 mono_class_from_mono_type (typeb);
1354 /*FIXME this is one more layer of ugliness due how types are created.*/
1355 mono_reflection_init_type_builder_generics (fb->type, error);
1356 return_val_if_nok (error, 0);
1358 /* fb->type does not include the custom modifiers */
1359 /* FIXME: We should do this in one place when a fieldbuilder is created */
1360 type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1361 return_val_if_nok (error, 0);
1363 if (fb->modreq || fb->modopt) {
1364 type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
1365 return_val_if_nok (error, 0);
1368 sig = mono_dynimage_encode_fieldref_signature (assembly, NULL, type);
1371 parent = mono_dynimage_encode_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
1372 return_val_if_nok (error, 0);
1373 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
1375 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
1376 parent >>= MONO_TYPEDEFORREF_BITS;
1378 table = &assembly->tables [MONO_TABLE_MEMBERREF];
1380 name = mono_string_to_utf8_checked (fb->name, error);
1381 return_val_if_nok (error, 0);
1383 if (assembly->save) {
1384 alloc_table (table, table->rows + 1);
1385 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
1386 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
1387 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
1388 values [MONO_MEMBERREF_SIGNATURE] = sig;
1391 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
1393 mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
1399 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
1402 MonoDynamicTable *table;
1405 mono_error_init (error);
1407 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
1408 idx = table->next_idx ++;
1410 alloc_table (table, table->rows);
1411 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
1413 values [MONO_STAND_ALONE_SIGNATURE] =
1414 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
1415 return_val_if_nok (error, 0);
1421 reflection_cc_to_file (int call_conv) {
1422 switch (call_conv & 0x3) {
1424 case 1: return MONO_CALL_DEFAULT;
1425 case 2: return MONO_CALL_VARARG;
1427 g_assert_not_reached ();
1431 #endif /* !DISABLE_REFLECTION_EMIT */
1433 struct _ArrayMethod {
1435 MonoMethodSignature *sig;
1441 mono_sre_array_method_free (ArrayMethod *am)
1448 #ifndef DISABLE_REFLECTION_EMIT
1450 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
1455 MonoMethodSignature *sig;
1456 ArrayMethod *am = NULL;
1459 mono_error_init (error);
1461 nparams = mono_array_length (m->parameters);
1462 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
1464 sig->sentinelpos = -1;
1465 sig->call_convention = reflection_cc_to_file (m->call_conv);
1466 sig->param_count = nparams;
1468 sig->ret = mono_reflection_type_get_handle (m->ret, error);
1472 sig->ret = &mono_defaults.void_class->byval_arg;
1474 mtype = mono_reflection_type_get_handle (m->parent, error);
1478 for (i = 0; i < nparams; ++i) {
1479 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
1484 name = mono_string_to_utf8_checked (m->name, error);
1487 for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
1488 am = (ArrayMethod *)tmp->data;
1489 if (strcmp (name, am->name) == 0 &&
1490 mono_metadata_type_equal (am->parent, mtype) &&
1491 mono_metadata_signature_equal (am->sig, sig)) {
1494 m->table_idx = am->token & 0xffffff;
1498 am = g_new0 (ArrayMethod, 1);
1502 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
1503 mono_dynimage_encode_method_signature (assembly, sig));
1504 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
1505 m->table_idx = am->token & 0xffffff;
1516 #ifndef DISABLE_REFLECTION_EMIT
1519 * mono_image_insert_string:
1520 * @module: module builder object
1523 * Insert @str into the user string stream of @module.
1526 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
1528 MonoDynamicImage *assembly;
1533 if (!module->dynamic_image)
1534 mono_image_module_basic_init (module);
1536 assembly = module->dynamic_image;
1538 if (assembly->save) {
1539 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
1540 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1541 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1543 char *swapped = g_malloc (2 * mono_string_length (str));
1544 const char *p = (const char*)mono_string_chars (str);
1546 swap_with_size (swapped, p, 2, mono_string_length (str));
1547 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
1551 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
1553 mono_image_add_stream_data (&assembly->us, "", 1);
1555 idx = assembly->us.index ++;
1558 mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
1560 return MONO_TOKEN_STRING | idx;
1564 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
1568 MonoMethodSignature *sig;
1570 mono_error_init (error);
1572 klass = obj->vtable->klass;
1573 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1574 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1575 MonoMethodSignature *old;
1576 guint32 sig_token, parent;
1579 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1581 nargs = mono_array_length (opt_param_types);
1582 old = mono_method_signature (method);
1583 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1585 sig->hasthis = old->hasthis;
1586 sig->explicit_this = old->explicit_this;
1587 sig->call_convention = old->call_convention;
1588 sig->generic_param_count = old->generic_param_count;
1589 sig->param_count = old->param_count + nargs;
1590 sig->sentinelpos = old->param_count;
1591 sig->ret = old->ret;
1593 for (i = 0; i < old->param_count; i++)
1594 sig->params [i] = old->params [i];
1596 for (i = 0; i < nargs; i++) {
1597 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1598 sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1599 if (!is_ok (error)) goto fail;
1602 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1603 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1604 parent >>= MONO_TYPEDEFORREF_BITS;
1606 parent <<= MONO_MEMBERREF_PARENT_BITS;
1607 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1609 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1610 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1611 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1612 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1613 ReflectionMethodBuilder rmb;
1614 guint32 parent, sig_token;
1615 int nopt_args, nparams, ngparams, i;
1617 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1620 rmb.opt_types = opt_param_types;
1621 nopt_args = mono_array_length (opt_param_types);
1623 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1624 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1625 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1627 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1628 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1629 sig->call_convention = rmb.call_conv;
1630 sig->generic_param_count = ngparams;
1631 sig->param_count = nparams + nopt_args;
1632 sig->sentinelpos = nparams;
1633 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1634 if (!is_ok (error)) goto fail;
1636 for (i = 0; i < nparams; i++) {
1637 MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1638 sig->params [i] = mono_reflection_type_get_handle (rt, error);
1639 if (!is_ok (error)) goto fail;
1642 for (i = 0; i < nopt_args; i++) {
1643 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1644 sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1645 if (!is_ok (error)) goto fail;
1648 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1652 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1653 if (!mono_error_ok (error))
1655 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1657 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1658 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1660 char *name = mono_string_to_utf8_checked (rmb.name, error);
1661 if (!is_ok (error)) goto fail;
1662 token = mono_image_get_varargs_method_token (
1663 assembly, parent, name, sig_token);
1666 g_error ("requested method token for %s\n", klass->name);
1669 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1670 mono_dynamic_image_register_token (assembly, token, obj);
1673 g_assert (!mono_error_ok (error));
1678 * mono_image_create_token:
1679 * @assembly: a dynamic assembly
1681 * @register_token: Whenever to register the token in the assembly->tokens hash.
1683 * Get a token to insert in the IL code stream for the given MemberInfo.
1684 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1685 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1689 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
1690 gboolean create_open_instance, gboolean register_token,
1696 mono_error_init (error);
1698 klass = obj->vtable->klass;
1700 /* Check for user defined reflection objects */
1701 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1702 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1703 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1707 if (strcmp (klass->name, "MethodBuilder") == 0) {
1708 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1709 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1711 if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
1712 token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1714 token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
1715 if (!mono_error_ok (error))
1718 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1719 } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
1720 MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
1721 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1723 if (tb->module->dynamic_image == assembly && !tb->generic_params)
1724 token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1726 token = mono_image_get_ctorbuilder_token (assembly, mb, error);
1727 if (!mono_error_ok (error))
1730 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1731 } else if (strcmp (klass->name, "FieldBuilder") == 0) {
1732 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
1733 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
1734 if (tb->generic_params) {
1735 token = mono_image_get_generic_field_token (assembly, fb, error);
1736 return_val_if_nok (error, 0);
1738 if (tb->module->dynamic_image == assembly) {
1739 token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
1741 token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
1744 } else if (strcmp (klass->name, "TypeBuilder") == 0) {
1745 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
1746 if (create_open_instance && tb->generic_params) {
1748 mono_reflection_init_type_builder_generics (obj, error);
1749 return_val_if_nok (error, 0);
1750 type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1751 return_val_if_nok (error, 0);
1752 token = mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
1753 token = mono_metadata_token_from_dor (token);
1754 } else if (tb->module->dynamic_image == assembly) {
1755 token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
1758 type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1759 return_val_if_nok (error, 0);
1760 token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
1762 } else if (strcmp (klass->name, "RuntimeType") == 0) {
1763 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1764 return_val_if_nok (error, 0);
1765 MonoClass *mc = mono_class_from_mono_type (type);
1766 token = mono_metadata_token_from_dor (
1767 mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
1768 } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
1769 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1770 return_val_if_nok (error, 0);
1771 token = mono_metadata_token_from_dor (
1772 mono_image_typedef_or_ref (assembly, type));
1773 } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
1774 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1775 return_val_if_nok (error, 0);
1776 token = mono_metadata_token_from_dor (
1777 mono_image_typedef_or_ref (assembly, type));
1778 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1779 strcmp (klass->name, "MonoMethod") == 0 ||
1780 strcmp (klass->name, "MonoGenericMethod") == 0 ||
1781 strcmp (klass->name, "MonoGenericCMethod") == 0) {
1782 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1783 if (m->method->is_inflated) {
1784 if (create_open_instance)
1785 token = mono_image_get_methodspec_token (assembly, m->method);
1787 token = mono_image_get_inflated_method_token (assembly, m->method);
1788 } else if ((m->method->klass->image == &assembly->image) &&
1789 !m->method->klass->generic_class) {
1790 static guint32 method_table_idx = 0xffffff;
1791 if (m->method->klass->wastypebuilder) {
1792 /* we use the same token as the one that was assigned
1793 * to the Methodbuilder.
1794 * FIXME: do the equivalent for Fields.
1796 token = m->method->token;
1799 * Each token should have a unique index, but the indexes are
1800 * assigned by managed code, so we don't know about them. An
1801 * easy solution is to count backwards...
1803 method_table_idx --;
1804 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1807 token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1809 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1810 } else if (strcmp (klass->name, "MonoField") == 0) {
1811 MonoReflectionField *f = (MonoReflectionField *)obj;
1812 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1813 static guint32 field_table_idx = 0xffffff;
1815 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1817 token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1819 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1820 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1821 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1822 token = mono_image_get_array_token (assembly, m, error);
1823 return_val_if_nok (error, 0);
1824 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1825 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1826 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1827 return_val_if_nok (error, 0);
1828 } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1829 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1830 return_val_if_nok (error, 0);
1831 token = mono_metadata_token_from_dor (
1832 mono_image_typedef_or_ref (assembly, type));
1833 } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
1834 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
1835 token = mono_image_get_field_on_inst_token (assembly, f, error);
1836 return_val_if_nok (error, 0);
1837 } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
1838 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
1839 token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
1840 if (!mono_error_ok (error))
1842 } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
1843 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
1844 token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
1845 if (!mono_error_ok (error))
1847 } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
1848 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1849 return_val_if_nok (error, 0);
1850 token = mono_metadata_token_from_dor (
1851 mono_image_typedef_or_ref (assembly, type));
1853 g_error ("requested token for %s\n", klass->name);
1857 mono_image_register_token (assembly, token, obj);
1865 #ifndef DISABLE_REFLECTION_EMIT
1868 * mono_reflection_dynimage_basic_init:
1869 * @assembly: an assembly builder object
1871 * Create the MonoImage that represents the assembly builder and setup some
1872 * of the helper hash table and the basic metadata streams.
1875 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1878 MonoDynamicAssembly *assembly;
1879 MonoDynamicImage *image;
1880 MonoDomain *domain = mono_object_domain (assemblyb);
1882 if (assemblyb->dynamic_assembly)
1886 /* assembly->assembly.image might be GC allocated */
1887 assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1889 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1892 mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1894 assembly->assembly.ref_count = 1;
1895 assembly->assembly.dynamic = TRUE;
1896 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1897 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1898 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1899 if (mono_error_set_pending_exception (&error))
1901 if (assemblyb->culture) {
1902 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1903 if (mono_error_set_pending_exception (&error))
1906 assembly->assembly.aname.culture = g_strdup ("");
1908 if (assemblyb->version) {
1909 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1910 if (mono_error_set_pending_exception (&error))
1912 char **version = g_strsplit (vstr, ".", 4);
1913 char **parts = version;
1914 assembly->assembly.aname.major = atoi (*parts++);
1915 assembly->assembly.aname.minor = atoi (*parts++);
1916 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1917 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1919 g_strfreev (version);
1922 assembly->assembly.aname.major = 0;
1923 assembly->assembly.aname.minor = 0;
1924 assembly->assembly.aname.build = 0;
1925 assembly->assembly.aname.revision = 0;
1928 assembly->run = assemblyb->access != 2;
1929 assembly->save = assemblyb->access != 1;
1930 assembly->domain = domain;
1932 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1933 if (mono_error_set_pending_exception (&error))
1935 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1936 image->initial_image = TRUE;
1937 assembly->assembly.aname.name = image->image.name;
1938 assembly->assembly.image = &image->image;
1939 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1940 /* -1 to correct for the trailing NULL byte */
1941 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1942 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1944 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1947 mono_domain_assemblies_lock (domain);
1948 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1949 mono_domain_assemblies_unlock (domain);
1951 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1953 mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1955 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1958 #endif /* !DISABLE_REFLECTION_EMIT */
1960 #ifndef DISABLE_REFLECTION_EMIT
1962 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1964 CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
1968 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
1970 CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
1974 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
1976 MonoDynamicImage *image = moduleb->dynamic_image;
1977 MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
1978 mono_error_init (error);
1981 MonoImage **new_modules;
1983 char *name, *fqname;
1985 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1986 * we don't know which module it belongs to, since that is only
1987 * determined at assembly save time.
1989 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1990 name = mono_string_to_utf8_checked (ab->name, error);
1991 return_val_if_nok (error, FALSE);
1992 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
1993 if (!is_ok (error)) {
1997 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
1999 moduleb->module.image = &image->image;
2000 moduleb->dynamic_image = image;
2001 register_module (mono_object_domain (moduleb), moduleb, image);
2003 /* register the module with the assembly */
2004 ass = ab->dynamic_assembly->assembly.image;
2005 module_count = ass->module_count;
2006 new_modules = g_new0 (MonoImage *, module_count + 1);
2009 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
2010 new_modules [module_count] = &image->image;
2011 mono_image_addref (&image->image);
2013 g_free (ass->modules);
2014 ass->modules = new_modules;
2015 ass->module_count ++;
2021 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
2024 (void) image_module_basic_init (moduleb, &error);
2025 mono_error_set_pending_exception (&error);
2031 is_corlib_type (MonoClass *klass)
2033 return klass->image == mono_defaults.corlib;
2036 #define check_corlib_type_cached(_class, _namespace, _name) do { \
2037 static MonoClass *cached_class; \
2039 return cached_class == _class; \
2040 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
2041 cached_class = _class; \
2049 #ifndef DISABLE_REFLECTION_EMIT
2051 is_sre_array (MonoClass *klass)
2053 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
2057 is_sre_byref (MonoClass *klass)
2059 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
2063 is_sre_pointer (MonoClass *klass)
2065 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
2069 is_sre_generic_instance (MonoClass *klass)
2071 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
2075 is_sre_type_builder (MonoClass *klass)
2077 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
2081 is_sre_method_builder (MonoClass *klass)
2083 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
2087 mono_is_sre_ctor_builder (MonoClass *klass)
2089 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
2093 is_sre_field_builder (MonoClass *klass)
2095 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
2099 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2101 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
2105 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2107 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
2110 static MonoReflectionType*
2111 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
2113 static MonoMethod *method_get_underlying_system_type = NULL;
2114 MonoReflectionType *rt;
2115 MonoMethod *usertype_method;
2117 mono_error_init (error);
2119 if (!method_get_underlying_system_type)
2120 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
2122 usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
2124 rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
2130 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
2133 mono_error_init (error);
2140 if (mono_reflection_is_usertype (ref)) {
2141 ref = mono_reflection_type_get_underlying_system_type (ref, error);
2142 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
2148 klass = mono_object_class (ref);
2150 if (is_sre_array (klass)) {
2152 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
2153 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
2154 return_val_if_nok (error, NULL);
2156 if (sre_array->rank == 0) //single dimentional array
2157 res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
2159 res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
2160 sre_array->type.type = res;
2162 } else if (is_sre_byref (klass)) {
2164 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
2165 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
2166 return_val_if_nok (error, NULL);
2168 res = &mono_class_from_mono_type (base)->this_arg;
2169 sre_byref->type.type = res;
2171 } else if (is_sre_pointer (klass)) {
2173 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
2174 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
2175 return_val_if_nok (error, NULL);
2177 res = &mono_ptr_class_get (base)->byval_arg;
2178 sre_pointer->type.type = res;
2180 } else if (is_sre_generic_instance (klass)) {
2181 MonoType *res, **types;
2182 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
2185 count = mono_array_length (gclass->type_arguments);
2186 types = g_new0 (MonoType*, count);
2187 for (i = 0; i < count; ++i) {
2188 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
2189 types [i] = mono_reflection_type_get_handle (t, error);
2190 if (!types[i] || !is_ok (error)) {
2196 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
2199 gclass->type.type = res;
2203 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
2208 ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
2211 mono_reflection_type_get_handle (type, &error);
2212 mono_error_set_pending_exception (&error);
2216 reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
2218 MonoDomain *domain = mono_object_domain ((MonoObject*)type);
2221 mono_error_init (error);
2223 MonoType *res = mono_reflection_type_get_handle (type, error);
2225 if (!res && is_ok (error)) {
2226 mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
2228 return_val_if_nok (error, FALSE);
2230 klass = mono_class_from_mono_type (res);
2232 mono_loader_lock (); /*same locking as mono_type_get_object_checked */
2233 mono_domain_lock (domain);
2235 if (!image_is_dynamic (klass->image)) {
2236 mono_class_setup_supertypes (klass);
2238 if (!domain->type_hash)
2239 domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash,
2240 (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
2241 mono_g_hash_table_insert (domain->type_hash, res, type);
2243 mono_domain_unlock (domain);
2244 mono_loader_unlock ();
2250 mono_reflection_register_with_runtime (MonoReflectionType *type)
2253 (void) reflection_register_with_runtime (type, &error);
2254 mono_error_set_pending_exception (&error);
2258 * LOCKING: Assumes the loader lock is held.
2260 static MonoMethodSignature*
2261 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
2262 MonoMethodSignature *sig;
2265 mono_error_init (error);
2267 count = parameters? mono_array_length (parameters): 0;
2269 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
2270 sig->param_count = count;
2271 sig->sentinelpos = -1; /* FIXME */
2272 for (i = 0; i < count; ++i) {
2273 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
2274 if (!is_ok (error)) {
2275 image_g_free (image, sig);
2283 * LOCKING: Assumes the loader lock is held.
2285 static MonoMethodSignature*
2286 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
2287 MonoMethodSignature *sig;
2289 mono_error_init (error);
2291 sig = parameters_to_signature (image, ctor->parameters, error);
2292 return_val_if_nok (error, NULL);
2293 sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2294 sig->ret = &mono_defaults.void_class->byval_arg;
2299 * LOCKING: Assumes the loader lock is held.
2301 static MonoMethodSignature*
2302 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
2303 MonoMethodSignature *sig;
2305 mono_error_init (error);
2307 sig = parameters_to_signature (image, method->parameters, error);
2308 return_val_if_nok (error, NULL);
2309 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2310 if (method->rtype) {
2311 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
2312 if (!is_ok (error)) {
2313 image_g_free (image, sig);
2317 sig->ret = &mono_defaults.void_class->byval_arg;
2319 sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
2323 static MonoMethodSignature*
2324 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
2325 MonoMethodSignature *sig;
2327 mono_error_init (error);
2329 sig = parameters_to_signature (NULL, method->parameters, error);
2330 return_val_if_nok (error, NULL);
2331 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2332 if (method->rtype) {
2333 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
2334 if (!is_ok (error)) {
2339 sig->ret = &mono_defaults.void_class->byval_arg;
2341 sig->generic_param_count = 0;
2346 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
2348 mono_error_init (error);
2349 MonoClass *klass = mono_object_class (prop);
2350 if (strcmp (klass->name, "PropertyBuilder") == 0) {
2351 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
2352 *name = mono_string_to_utf8_checked (pb->name, error);
2353 return_if_nok (error);
2354 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
2356 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
2357 *name = g_strdup (p->property->name);
2358 if (p->property->get)
2359 *type = mono_method_signature (p->property->get)->ret;
2361 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
2366 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
2368 mono_error_init (error);
2369 MonoClass *klass = mono_object_class (field);
2370 if (strcmp (klass->name, "FieldBuilder") == 0) {
2371 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
2372 *name = mono_string_to_utf8_checked (fb->name, error);
2373 return_if_nok (error);
2374 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
2376 MonoReflectionField *f = (MonoReflectionField *)field;
2377 *name = g_strdup (mono_field_get_name (f->field));
2378 *type = f->field->type;
2382 #else /* DISABLE_REFLECTION_EMIT */
2385 mono_reflection_register_with_runtime (MonoReflectionType *type)
2391 is_sre_type_builder (MonoClass *klass)
2397 is_sre_generic_instance (MonoClass *klass)
2403 mono_is_sre_ctor_builder (MonoClass *klass)
2409 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2415 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2421 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
2423 mono_error_init (error);
2426 #endif /* !DISABLE_REFLECTION_EMIT */
2430 is_sr_mono_field (MonoClass *klass)
2432 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
2436 mono_is_sr_mono_property (MonoClass *klass)
2438 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
2442 is_sr_mono_method (MonoClass *klass)
2444 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
2448 mono_is_sr_mono_cmethod (MonoClass *klass)
2450 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
2454 is_sr_mono_generic_method (MonoClass *klass)
2456 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
2460 is_sr_mono_generic_cmethod (MonoClass *klass)
2462 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
2466 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
2468 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
2472 mono_is_sre_type_builder (MonoClass *klass)
2474 return is_sre_type_builder (klass);
2478 mono_is_sre_generic_instance (MonoClass *klass)
2480 return is_sre_generic_instance (klass);
2486 * encode_cattr_value:
2487 * Encode a value in a custom attribute stream of bytes.
2488 * The value to encode is either supplied as an object in argument val
2489 * (valuetypes are boxed), or as a pointer to the data in the
2491 * @type represents the type of the value
2492 * @buffer is the start of the buffer
2493 * @p the current position in the buffer
2494 * @buflen contains the size of the buffer and is used to return the new buffer size
2495 * if this needs to be realloced.
2496 * @retbuffer and @retp return the start and the position of the buffer
2497 * @error set on error.
2500 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2502 MonoTypeEnum simple_type;
2504 mono_error_init (error);
2505 if ((p-buffer) + 10 >= *buflen) {
2508 newbuf = (char *)g_realloc (buffer, *buflen);
2509 p = newbuf + (p-buffer);
2513 argval = ((char*)arg + sizeof (MonoObject));
2514 simple_type = type->type;
2516 switch (simple_type) {
2517 case MONO_TYPE_BOOLEAN:
2522 case MONO_TYPE_CHAR:
2525 swap_with_size (p, argval, 2, 1);
2531 swap_with_size (p, argval, 4, 1);
2535 swap_with_size (p, argval, 8, 1);
2540 swap_with_size (p, argval, 8, 1);
2543 case MONO_TYPE_VALUETYPE:
2544 if (type->data.klass->enumtype) {
2545 simple_type = mono_class_enum_basetype (type->data.klass)->type;
2548 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2551 case MONO_TYPE_STRING: {
2558 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2559 return_if_nok (error);
2560 slen = strlen (str);
2561 if ((p-buffer) + 10 + slen >= *buflen) {
2565 newbuf = (char *)g_realloc (buffer, *buflen);
2566 p = newbuf + (p-buffer);
2569 mono_metadata_encode_value (slen, p, &p);
2570 memcpy (p, str, slen);
2575 case MONO_TYPE_CLASS: {
2584 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2585 return_if_nok (error);
2587 str = type_get_qualified_name (arg_type, NULL);
2588 slen = strlen (str);
2589 if ((p-buffer) + 10 + slen >= *buflen) {
2593 newbuf = (char *)g_realloc (buffer, *buflen);
2594 p = newbuf + (p-buffer);
2597 mono_metadata_encode_value (slen, p, &p);
2598 memcpy (p, str, slen);
2603 case MONO_TYPE_SZARRAY: {
2605 MonoClass *eclass, *arg_eclass;
2608 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2611 len = mono_array_length ((MonoArray*)arg);
2613 *p++ = (len >> 8) & 0xff;
2614 *p++ = (len >> 16) & 0xff;
2615 *p++ = (len >> 24) & 0xff;
2617 *retbuffer = buffer;
2618 eclass = type->data.klass;
2619 arg_eclass = mono_object_class (arg)->element_class;
2622 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2623 eclass = mono_defaults.object_class;
2625 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2626 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2627 int elsize = mono_class_array_element_size (arg_eclass);
2628 for (i = 0; i < len; ++i) {
2629 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2630 return_if_nok (error);
2633 } else if (eclass->valuetype && arg_eclass->valuetype) {
2634 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2635 int elsize = mono_class_array_element_size (eclass);
2636 for (i = 0; i < len; ++i) {
2637 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2638 return_if_nok (error);
2642 for (i = 0; i < len; ++i) {
2643 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2644 return_if_nok (error);
2649 case MONO_TYPE_OBJECT: {
2655 * The parameter type is 'object' but the type of the actual
2656 * argument is not. So we have to add type information to the blob
2657 * too. This is completely undocumented in the spec.
2661 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2666 klass = mono_object_class (arg);
2668 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2672 return_if_nok (error);
2675 if (klass->enumtype) {
2677 } else if (klass == mono_defaults.string_class) {
2678 simple_type = MONO_TYPE_STRING;
2681 } else if (klass->rank == 1) {
2683 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2684 /* See Partition II, Appendix B3 */
2687 *p++ = klass->element_class->byval_arg.type;
2688 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2689 return_if_nok (error);
2691 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2692 *p++ = simple_type = klass->byval_arg.type;
2695 g_error ("unhandled type in custom attr");
2697 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2698 slen = strlen (str);
2699 if ((p-buffer) + 10 + slen >= *buflen) {
2703 newbuf = (char *)g_realloc (buffer, *buflen);
2704 p = newbuf + (p-buffer);
2707 mono_metadata_encode_value (slen, p, &p);
2708 memcpy (p, str, slen);
2711 simple_type = mono_class_enum_basetype (klass)->type;
2715 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2718 *retbuffer = buffer;
2722 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2724 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2725 char *str = type_get_qualified_name (type, NULL);
2726 int slen = strlen (str);
2730 * This seems to be optional...
2733 mono_metadata_encode_value (slen, p, &p);
2734 memcpy (p, str, slen);
2737 } else if (type->type == MONO_TYPE_OBJECT) {
2739 } else if (type->type == MONO_TYPE_CLASS) {
2740 /* it should be a type: encode_cattr_value () has the check */
2743 mono_metadata_encode_value (type->type, p, &p);
2744 if (type->type == MONO_TYPE_SZARRAY)
2745 /* See the examples in Partition VI, Annex B */
2746 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2752 #ifndef DISABLE_REFLECTION_EMIT
2754 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2758 mono_error_init (error);
2760 /* Preallocate a large enough buffer */
2761 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2762 char *str = type_get_qualified_name (type, NULL);
2765 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2766 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2772 len += strlen (name);
2774 if ((p-buffer) + 20 + len >= *buflen) {
2778 newbuf = (char *)g_realloc (buffer, *buflen);
2779 p = newbuf + (p-buffer);
2783 encode_field_or_prop_type (type, p, &p);
2785 len = strlen (name);
2786 mono_metadata_encode_value (len, p, &p);
2787 memcpy (p, name, len);
2789 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2790 return_if_nok (error);
2792 *retbuffer = buffer;
2796 * mono_reflection_get_custom_attrs_blob:
2797 * @ctor: custom attribute constructor
2798 * @ctorArgs: arguments o the constructor
2804 * Creates the blob of data that needs to be saved in the metadata and that represents
2805 * the custom attributed described by @ctor, @ctorArgs etc.
2806 * Returns: a Byte array representing the blob of data.
2809 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2812 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2813 mono_error_cleanup (&error);
2818 * mono_reflection_get_custom_attrs_blob_checked:
2819 * @ctor: custom attribute constructor
2820 * @ctorArgs: arguments o the constructor
2825 * @error: set on error
2827 * Creates the blob of data that needs to be saved in the metadata and that represents
2828 * the custom attributed described by @ctor, @ctorArgs etc.
2829 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2832 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2834 MonoArray *result = NULL;
2835 MonoMethodSignature *sig;
2840 mono_error_init (error);
2842 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2843 /* sig is freed later so allocate it in the heap */
2844 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2845 if (!is_ok (error)) {
2850 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2853 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2855 p = buffer = (char *)g_malloc (buflen);
2856 /* write the prolog */
2859 for (i = 0; i < sig->param_count; ++i) {
2860 arg = mono_array_get (ctorArgs, MonoObject*, i);
2861 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2862 if (!is_ok (error)) goto leave;
2866 i += mono_array_length (properties);
2868 i += mono_array_length (fields);
2870 *p++ = (i >> 8) & 0xff;
2873 for (i = 0; i < mono_array_length (properties); ++i) {
2877 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2878 get_prop_name_and_type (prop, &pname, &ptype, error);
2879 if (!is_ok (error)) goto leave;
2880 *p++ = 0x54; /* PROPERTY signature */
2881 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2883 if (!is_ok (error)) goto leave;
2889 for (i = 0; i < mono_array_length (fields); ++i) {
2893 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2894 get_field_name_and_type (field, &fname, &ftype, error);
2895 if (!is_ok (error)) goto leave;
2896 *p++ = 0x53; /* FIELD signature */
2897 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2899 if (!is_ok (error)) goto leave;
2903 g_assert (p - buffer <= buflen);
2904 buflen = p - buffer;
2905 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2908 p = mono_array_addr (result, char, 0);
2909 memcpy (p, buffer, buflen);
2912 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2918 * reflection_setup_internal_class:
2919 * @tb: a TypeBuilder object
2920 * @error: set on error
2922 * Creates a MonoClass that represents the TypeBuilder.
2923 * This is a trick that lets us simplify a lot of reflection code
2924 * (and will allow us to support Build and Run assemblies easier).
2926 * Returns TRUE on success. On failure, returns FALSE and sets @error.
2929 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2931 MonoClass *klass, *parent;
2933 mono_error_init (error);
2935 mono_loader_lock ();
2938 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
2939 if (!is_ok (error)) {
2940 mono_loader_unlock ();
2943 /* check so we can compile corlib correctly */
2944 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
2945 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2946 parent = parent_type->data.klass;
2948 parent = mono_class_from_mono_type (parent_type);
2954 /* the type has already being created: it means we just have to change the parent */
2955 if (tb->type.type) {
2956 klass = mono_class_from_mono_type (tb->type.type);
2957 klass->parent = NULL;
2958 /* fool mono_class_setup_parent */
2959 klass->supertypes = NULL;
2960 mono_class_setup_parent (klass, parent);
2961 mono_class_setup_mono_type (klass);
2962 mono_loader_unlock ();
2966 klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
2968 klass->image = &tb->module->dynamic_image->image;
2970 klass->inited = 1; /* we lie to the runtime */
2971 klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
2974 klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
2977 klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
2978 klass->flags = tb->attrs;
2980 mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2982 klass->element_class = klass;
2984 if (mono_class_get_ref_info (klass) == NULL) {
2985 mono_class_set_ref_info (klass, tb);
2987 /* Put into cache so mono_class_get_checked () will find it.
2988 Skip nested types as those should not be available on the global scope. */
2989 if (!tb->nesting_type)
2990 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
2993 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2994 by performing a mono_class_get which does the full resolution.
2996 Working around this semantics would require us to write a lot of code for no clear advantage.
2998 mono_image_append_class_to_reflection_info_set (klass);
3000 g_assert (mono_class_get_ref_info (klass) == tb);
3003 mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
3005 if (parent != NULL) {
3006 mono_class_setup_parent (klass, parent);
3007 } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
3008 const char *old_n = klass->name;
3009 /* trick to get relative numbering right when compiling corlib */
3010 klass->name = "BuildingObject";
3011 mono_class_setup_parent (klass, mono_defaults.object_class);
3012 klass->name = old_n;
3015 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
3016 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
3017 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
3018 klass->instance_size = sizeof (MonoObject);
3019 klass->size_inited = 1;
3020 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
3023 mono_class_setup_mono_type (klass);
3025 mono_class_setup_supertypes (klass);
3028 * FIXME: handle interfaces.
3031 tb->type.type = &klass->byval_arg;
3033 if (tb->nesting_type) {
3034 g_assert (tb->nesting_type->type);
3035 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
3036 if (!is_ok (error)) goto failure;
3037 klass->nested_in = mono_class_from_mono_type (nesting_type);
3040 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
3042 mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
3044 mono_loader_unlock ();
3048 mono_loader_unlock ();
3053 * ves_icall_TypeBuilder_setup_internal_class:
3054 * @tb: a TypeBuilder object
3057 * Creates a MonoClass that represents the TypeBuilder.
3058 * This is a trick that lets us simplify a lot of reflection code
3059 * (and will allow us to support Build and Run assemblies easier).
3063 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
3066 (void) reflection_setup_internal_class (tb, &error);
3067 mono_error_set_pending_exception (&error);
3071 * mono_reflection_create_generic_class:
3072 * @tb: a TypeBuilder object
3073 * @error: set on error
3075 * Creates the generic class after all generic parameters have been added.
3076 * On success returns TRUE, on failure returns FALSE and sets @error.
3080 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3086 mono_error_init (error);
3088 klass = mono_class_from_mono_type (tb->type.type);
3090 count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
3092 if (klass->generic_container || (count == 0))
3095 g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
3097 klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3099 klass->generic_container->owner.klass = klass;
3100 klass->generic_container->type_argc = count;
3101 klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
3103 klass->is_generic = 1;
3105 for (i = 0; i < count; i++) {
3106 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3107 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
3108 return_val_if_nok (error, FALSE);
3109 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
3110 klass->generic_container->type_params [i] = *param;
3111 /*Make sure we are a diferent type instance */
3112 klass->generic_container->type_params [i].param.owner = klass->generic_container;
3113 klass->generic_container->type_params [i].info.pklass = NULL;
3114 klass->generic_container->type_params [i].info.flags = gparam->attrs;
3116 g_assert (klass->generic_container->type_params [i].param.owner);
3119 klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
3123 static MonoMarshalSpec*
3124 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
3125 MonoReflectionMarshal *minfo, MonoError *error)
3127 MonoMarshalSpec *res;
3129 mono_error_init (error);
3131 res = image_g_new0 (image, MonoMarshalSpec, 1);
3132 res->native = (MonoMarshalNative)minfo->type;
3134 switch (minfo->type) {
3135 case MONO_NATIVE_LPARRAY:
3136 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
3137 if (minfo->has_size) {
3138 res->data.array_data.param_num = minfo->param_num;
3139 res->data.array_data.num_elem = minfo->count;
3140 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
3143 res->data.array_data.param_num = -1;
3144 res->data.array_data.num_elem = -1;
3145 res->data.array_data.elem_mult = -1;
3149 case MONO_NATIVE_BYVALTSTR:
3150 case MONO_NATIVE_BYVALARRAY:
3151 res->data.array_data.num_elem = minfo->count;
3154 case MONO_NATIVE_CUSTOM:
3155 if (minfo->marshaltyperef) {
3156 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
3157 if (!is_ok (error)) {
3158 image_g_free (image, res);
3161 res->data.custom_data.custom_name =
3162 type_get_fully_qualified_name (marshaltyperef);
3164 if (minfo->mcookie) {
3165 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
3166 if (!is_ok (error)) {
3167 image_g_free (image, res);
3179 #endif /* !DISABLE_REFLECTION_EMIT */
3181 MonoReflectionMarshalAsAttribute*
3182 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
3183 MonoMarshalSpec *spec, MonoError *error)
3185 MonoReflectionType *rt;
3186 MonoReflectionMarshalAsAttribute *minfo;
3189 mono_error_init (error);
3191 minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
3194 minfo->utype = spec->native;
3196 switch (minfo->utype) {
3197 case MONO_NATIVE_LPARRAY:
3198 minfo->array_subtype = spec->data.array_data.elem_type;
3199 minfo->size_const = spec->data.array_data.num_elem;
3200 if (spec->data.array_data.param_num != -1)
3201 minfo->size_param_index = spec->data.array_data.param_num;
3204 case MONO_NATIVE_BYVALTSTR:
3205 case MONO_NATIVE_BYVALARRAY:
3206 minfo->size_const = spec->data.array_data.num_elem;
3209 case MONO_NATIVE_CUSTOM:
3210 if (spec->data.custom_data.custom_name) {
3211 mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
3212 return_val_if_nok (error, NULL);
3215 rt = mono_type_get_object_checked (domain, mtype, error);
3219 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
3222 MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
3224 if (spec->data.custom_data.cookie)
3225 MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
3235 #ifndef DISABLE_REFLECTION_EMIT
3237 reflection_methodbuilder_to_mono_method (MonoClass *klass,
3238 ReflectionMethodBuilder *rmb,
3239 MonoMethodSignature *sig,
3243 MonoMethodWrapper *wrapperm;
3244 MonoMarshalSpec **specs;
3245 MonoReflectionMethodAux *method_aux;
3250 mono_error_init (error);
3252 * Methods created using a MethodBuilder should have their memory allocated
3253 * inside the image mempool, while dynamic methods should have their memory
3256 dynamic = rmb->refs != NULL;
3257 image = dynamic ? NULL : klass->image;
3260 g_assert (!klass->generic_class);
3262 mono_loader_lock ();
3264 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
3265 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
3266 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
3268 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
3270 wrapperm = (MonoMethodWrapper*)m;
3272 m->dynamic = dynamic;
3274 m->flags = rmb->attrs;
3275 m->iflags = rmb->iattrs;
3276 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
3279 m->sre_method = TRUE;
3280 m->skip_visibility = rmb->skip_visibility;
3282 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
3284 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
3285 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
3288 m->signature->pinvoke = 1;
3289 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3290 m->signature->pinvoke = 1;
3292 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3294 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
3295 mono_error_assert_ok (error);
3296 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
3297 mono_error_assert_ok (error);
3299 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
3301 if (image_is_dynamic (klass->image))
3302 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3304 mono_loader_unlock ();
3307 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
3308 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
3309 MonoMethodHeader *header;
3311 gint32 max_stack, i;
3312 gint32 num_locals = 0;
3313 gint32 num_clauses = 0;
3317 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
3318 code_size = rmb->ilgen->code_len;
3319 max_stack = rmb->ilgen->max_stack;
3320 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
3321 if (rmb->ilgen->ex_handlers)
3322 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
3325 code = mono_array_addr (rmb->code, guint8, 0);
3326 code_size = mono_array_length (rmb->code);
3327 /* we probably need to run a verifier on the code... */
3337 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
3338 header->code_size = code_size;
3339 header->code = (const unsigned char *)image_g_malloc (image, code_size);
3340 memcpy ((char*)header->code, code, code_size);
3341 header->max_stack = max_stack;
3342 header->init_locals = rmb->init_locals;
3343 header->num_locals = num_locals;
3345 for (i = 0; i < num_locals; ++i) {
3346 MonoReflectionLocalBuilder *lb =
3347 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
3349 header->locals [i] = image_g_new0 (image, MonoType, 1);
3350 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
3351 mono_error_assert_ok (error);
3352 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
3355 header->num_clauses = num_clauses;
3357 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
3358 rmb->ilgen, num_clauses, error);
3359 mono_error_assert_ok (error);
3362 wrapperm->header = header;
3365 if (rmb->generic_params) {
3366 int count = mono_array_length (rmb->generic_params);
3367 MonoGenericContainer *container = rmb->generic_container;
3369 g_assert (container);
3371 container->type_argc = count;
3372 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
3373 container->owner.method = m;
3374 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
3376 m->is_generic = TRUE;
3377 mono_method_set_generic_container (m, container);
3379 for (i = 0; i < count; i++) {
3380 MonoReflectionGenericParam *gp =
3381 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
3382 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
3383 mono_error_assert_ok (error);
3384 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
3385 container->type_params [i] = *param;
3389 * The method signature might have pointers to generic parameters that belong to other methods.
3390 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3391 * generic parameters.
3393 for (i = 0; i < m->signature->param_count; ++i) {
3394 MonoType *t = m->signature->params [i];
3395 if (t->type == MONO_TYPE_MVAR) {
3396 MonoGenericParam *gparam = t->data.generic_param;
3397 if (gparam->num < count) {
3398 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
3399 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
3405 if (klass->generic_container) {
3406 container->parent = klass->generic_container;
3407 container->context.class_inst = klass->generic_container->context.class_inst;
3409 container->context.method_inst = mono_get_shared_generic_inst (container);
3413 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
3417 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
3419 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
3420 data [0] = GUINT_TO_POINTER (rmb->nrefs);
3421 for (i = 0; i < rmb->nrefs; ++i)
3422 data [i + 1] = rmb->refs [i];
3427 /* Parameter info */
3430 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3431 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
3432 for (i = 0; i <= m->signature->param_count; ++i) {
3433 MonoReflectionParamBuilder *pb;
3434 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3435 if ((i > 0) && (pb->attrs)) {
3436 /* Make a copy since it might point to a shared type structure */
3437 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
3438 m->signature->params [i - 1]->attrs = pb->attrs;
3441 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3442 MonoDynamicImage *assembly;
3444 MonoTypeEnum def_type;
3448 if (!method_aux->param_defaults) {
3449 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3450 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3452 assembly = (MonoDynamicImage*)klass->image;
3453 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3454 /* Copy the data from the blob since it might get realloc-ed */
3455 p = assembly->blob.data + idx;
3456 len = mono_metadata_decode_blob_size (p, &p2);
3458 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3459 method_aux->param_default_types [i] = def_type;
3460 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3464 method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
3465 mono_error_assert_ok (error);
3468 if (!method_aux->param_cattr)
3469 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3470 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3476 /* Parameter marshalling */
3479 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3480 MonoReflectionParamBuilder *pb;
3481 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3482 if (pb->marshal_info) {
3484 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3485 specs [pb->position] =
3486 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3487 if (!is_ok (error)) {
3488 mono_loader_unlock ();
3489 image_g_free (image, specs);
3490 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3496 if (specs != NULL) {
3498 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3499 method_aux->param_marshall = specs;
3502 if (image_is_dynamic (klass->image) && method_aux)
3503 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3505 mono_loader_unlock ();
3511 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3513 ReflectionMethodBuilder rmb;
3514 MonoMethodSignature *sig;
3516 mono_loader_lock ();
3517 g_assert (klass->image != NULL);
3518 sig = ctor_builder_to_signature (klass->image, mb, error);
3519 mono_loader_unlock ();
3520 return_val_if_nok (error, NULL);
3522 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3525 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3526 return_val_if_nok (error, NULL);
3527 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3529 /* If we are in a generic class, we might be called multiple times from inflate_method */
3530 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3531 /* ilgen is no longer needed */
3539 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
3541 ReflectionMethodBuilder rmb;
3542 MonoMethodSignature *sig;
3544 mono_error_init (error);
3546 mono_loader_lock ();
3547 g_assert (klass->image != NULL);
3548 sig = method_builder_to_signature (klass->image, mb, error);
3549 mono_loader_unlock ();
3550 return_val_if_nok (error, NULL);
3552 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3555 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3556 return_val_if_nok (error, NULL);
3557 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3559 /* If we are in a generic class, we might be called multiple times from inflate_method */
3560 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3561 /* ilgen is no longer needed */
3567 static MonoClassField*
3568 fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
3570 MonoClassField *field;
3573 mono_error_init (error);
3575 field = g_new0 (MonoClassField, 1);
3577 field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
3578 mono_error_assert_ok (error);
3579 if (fb->attrs || fb->modreq || fb->modopt) {
3580 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3581 if (!is_ok (error)) {
3585 field->type = mono_metadata_type_dup (NULL, type);
3586 field->type->attrs = fb->attrs;
3588 g_assert (image_is_dynamic (klass->image));
3589 custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
3590 g_free (field->type);
3591 if (!is_ok (error)) {
3595 field->type = mono_metadata_type_dup (klass->image, custom);
3598 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3599 if (!is_ok (error)) {
3604 if (fb->offset != -1)
3605 field->offset = fb->offset;
3606 field->parent = klass;
3607 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3609 // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
3615 #ifndef DISABLE_REFLECTION_EMIT
3618 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
3620 MonoMethodInflated *imethod;
3621 MonoGenericContext *context;
3625 * With generic code sharing the klass might not be inflated.
3626 * This can happen because classes inflated with their own
3627 * type arguments are "normalized" to the uninflated class.
3629 if (!klass->generic_class)
3632 context = mono_class_get_context (klass);
3634 if (klass->method.count && klass->methods) {
3635 /* Find the already created inflated method */
3636 for (i = 0; i < klass->method.count; ++i) {
3637 g_assert (klass->methods [i]->is_inflated);
3638 if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
3641 g_assert (i < klass->method.count);
3642 imethod = (MonoMethodInflated*)klass->methods [i];
3645 imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
3646 mono_error_assert_ok (&error);
3649 if (method->is_generic && image_is_dynamic (method->klass->image)) {
3650 MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
3652 mono_image_lock ((MonoImage*)image);
3653 mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
3654 mono_image_unlock ((MonoImage*)image);
3656 return (MonoMethod *) imethod;
3660 inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
3665 mono_error_init (error);
3667 MonoClass *type_class = mono_object_class (type);
3669 if (is_sre_generic_instance (type_class)) {
3670 MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
3671 MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
3672 return_val_if_nok (error, NULL);
3673 gklass = mono_class_from_mono_type (generic_type);
3674 } else if (is_sre_type_builder (type_class)) {
3675 MonoType *t = mono_reflection_type_get_handle (type, error);
3676 return_val_if_nok (error, NULL);
3677 gklass = mono_class_from_mono_type (t);
3678 } else if (type->type) {
3679 gklass = mono_class_from_mono_type (type->type);
3680 gklass = mono_class_get_generic_type_definition (gklass);
3682 g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
3685 if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
3686 if (((MonoReflectionMethodBuilder*)obj)->mhandle)
3687 method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
3689 method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
3693 else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
3694 method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
3697 } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
3698 method = ((MonoReflectionMethod *) obj)->method;
3700 method = NULL; /* prevent compiler warning */
3701 g_error ("can't handle type %s", obj->vtable->klass->name);
3704 MonoType *t = mono_reflection_type_get_handle (type, error);
3705 return_val_if_nok (error, NULL);
3706 return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
3710 reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoError *error)
3712 MonoGenericClass *gclass;
3713 MonoClass *klass, *gklass;
3716 mono_error_init (error);
3718 gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
3719 return_if_nok (error);
3720 klass = mono_class_from_mono_type (gtype);
3721 g_assert (gtype->type == MONO_TYPE_GENERICINST);
3722 gclass = gtype->data.generic_class;
3724 if (!gclass->is_dynamic)
3727 gklass = gclass->container_class;
3728 mono_class_init (gklass);
3730 /* Mark this as needing synchronization with its generic container */
3731 gclass->need_sync = TRUE;
3735 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
3738 reflection_generic_class_initialize (type, &error);
3739 mono_error_set_pending_exception (&error);
3743 * fix_partial_generic_class:
3744 * @klass: a generic instantiation MonoClass
3745 * @error: set on error
3747 * Assumes that the generic container of @klass has its vtable
3748 * initialized, and updates the parent class, interfaces, methods and
3749 * fields of @klass by inflating the types using the generic context.
3751 * On success returns TRUE, on failure returns FALSE and sets @error.
3755 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3757 MonoClass *gklass = klass->generic_class->container_class;
3760 mono_error_init (error);
3762 if (klass->wastypebuilder)
3765 if (klass->parent != gklass->parent) {
3766 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
3767 if (mono_error_ok (error)) {
3768 MonoClass *parent = mono_class_from_mono_type (parent_type);
3769 mono_metadata_free_type (parent_type);
3770 if (parent != klass->parent) {
3771 /*fool mono_class_setup_parent*/
3772 klass->supertypes = NULL;
3773 mono_class_setup_parent (klass, parent);
3776 if (gklass->wastypebuilder)
3777 klass->wastypebuilder = TRUE;
3782 if (!klass->generic_class->need_sync)
3785 if (klass->method.count != gklass->method.count) {
3786 klass->method.count = gklass->method.count;
3787 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
3789 for (i = 0; i < klass->method.count; i++) {
3790 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3791 gklass->methods [i], klass, mono_class_get_context (klass), error);
3792 mono_error_assert_ok (error);
3796 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3797 klass->interface_count = gklass->interface_count;
3798 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3799 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3801 for (i = 0; i < gklass->interface_count; ++i) {
3802 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3803 return_val_if_nok (error, FALSE);
3805 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3806 mono_metadata_free_type (iface_type);
3808 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3811 klass->interfaces_inited = 1;
3814 if (klass->field.count != gklass->field.count) {
3815 klass->field.count = gklass->field.count;
3816 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
3818 for (i = 0; i < klass->field.count; i++) {
3819 klass->fields [i] = gklass->fields [i];
3820 klass->fields [i].parent = klass;
3821 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3822 return_val_if_nok (error, FALSE);
3826 /*We can only finish with this klass once it's parent has as well*/
3827 if (gklass->wastypebuilder)
3828 klass->wastypebuilder = TRUE;
3833 * ensure_generic_class_runtime_vtable:
3834 * @klass a generic class
3835 * @error set on error
3837 * Ensures that the generic container of @klass has a vtable and
3838 * returns TRUE on success. On error returns FALSE and sets @error.
3841 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3843 MonoClass *gklass = klass->generic_class->container_class;
3845 mono_error_init (error);
3847 if (!ensure_runtime_vtable (gklass, error))
3850 return fix_partial_generic_class (klass, error);
3854 * ensure_runtime_vtable:
3856 * @error set on error
3858 * Ensures that @klass has a vtable and returns TRUE on success. On
3859 * error returns FALSE and sets @error.
3862 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3864 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3867 mono_error_init (error);
3869 if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
3872 if (!ensure_runtime_vtable (klass->parent, error))
3876 num = tb->ctors? mono_array_length (tb->ctors): 0;
3877 num += tb->num_methods;
3878 klass->method.count = num;
3879 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3880 num = tb->ctors? mono_array_length (tb->ctors): 0;
3881 for (i = 0; i < num; ++i) {
3882 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3885 klass->methods [i] = ctor;
3887 num = tb->num_methods;
3889 for (i = 0; i < num; ++i) {
3890 MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3893 klass->methods [j++] = meth;
3896 if (tb->interfaces) {
3897 klass->interface_count = mono_array_length (tb->interfaces);
3898 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3899 for (i = 0; i < klass->interface_count; ++i) {
3900 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3901 return_val_if_nok (error, FALSE);
3902 klass->interfaces [i] = mono_class_from_mono_type (iface);
3903 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3906 klass->interfaces_inited = 1;
3908 } else if (klass->generic_class){
3909 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3910 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3915 if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
3917 for (i = 0; i < klass->method.count; ++i) {
3918 MonoMethod *im = klass->methods [i];
3919 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3920 im->slot = slot_num++;
3923 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3924 mono_class_setup_interface_offsets (klass);
3925 mono_class_setup_interface_id (klass);
3929 * The generic vtable is needed even if image->run is not set since some
3930 * runtime code like ves_icall_Type_GetMethodsByName depends on
3931 * method->slot being defined.
3935 * tb->methods could not be freed since it is used for determining
3936 * overrides during dynamic vtable construction.
3943 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3945 mono_error_init (error);
3946 MonoClass *klass = mono_object_class (method);
3947 if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
3948 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3949 return sr_method->method;
3951 if (is_sre_method_builder (klass)) {
3952 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3955 if (mono_is_sre_method_on_tb_inst (klass)) {
3956 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
3958 /*FIXME move this to a proper method and unify with resolve_object*/
3959 if (m->method_args) {
3960 result = mono_reflection_method_on_tb_inst_get_handle (m, error);
3962 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
3963 return_val_if_nok (error, NULL);
3964 MonoClass *inflated_klass = mono_class_from_mono_type (type);
3965 MonoMethod *mono_method;
3967 if (is_sre_method_builder (mono_object_class (m->mb)))
3968 mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
3969 else if (is_sr_mono_method (mono_object_class (m->mb)))
3970 mono_method = ((MonoReflectionMethod *)m->mb)->method;
3972 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)));
3974 result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
3979 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3984 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3986 MonoReflectionTypeBuilder *tb;
3988 MonoReflectionMethod *m;
3990 mono_error_init (error);
3994 g_assert (image_is_dynamic (klass->image));
3996 if (!mono_class_get_ref_info (klass))
3999 g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
4001 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
4005 for (i = 0; i < tb->num_methods; ++i) {
4006 MonoReflectionMethodBuilder *mb =
4007 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4008 if (mb->override_methods)
4009 onum += mono_array_length (mb->override_methods);
4014 *overrides = g_new0 (MonoMethod*, onum * 2);
4017 for (i = 0; i < tb->num_methods; ++i) {
4018 MonoReflectionMethodBuilder *mb =
4019 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4020 if (mb->override_methods) {
4021 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
4022 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
4024 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
4025 return_if_nok (error);
4026 (*overrides) [onum * 2 + 1] = mb->mhandle;
4028 g_assert (mb->mhandle);
4036 *num_overrides = onum;
4040 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
4042 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4043 MonoReflectionFieldBuilder *fb;
4044 MonoClassField *field;
4045 MonoImage *image = klass->image;
4048 guint32 len, idx, real_size = 0;
4050 klass->field.count = tb->num_fields;
4051 klass->field.first = 0;
4053 mono_error_init (error);
4055 if (tb->class_size) {
4056 if ((tb->packing_size & 0xffffff00) != 0) {
4057 char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
4058 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
4061 klass->packing_size = tb->packing_size;
4062 real_size = klass->instance_size + tb->class_size;
4065 if (!klass->field.count) {
4066 klass->instance_size = MAX (klass->instance_size, real_size);
4070 klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
4071 mono_class_alloc_ext (klass);
4072 klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
4074 This is, guess what, a hack.
4075 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
4076 On the static path no field class is resolved, only types are built. This is the right thing to do
4078 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
4080 klass->size_inited = 1;
4082 for (i = 0; i < klass->field.count; ++i) {
4083 MonoArray *rva_data;
4084 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4085 field = &klass->fields [i];
4086 field->name = mono_string_to_utf8_image (image, fb->name, error);
4087 if (!mono_error_ok (error))
4090 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4091 return_if_nok (error);
4092 field->type = mono_metadata_type_dup (klass->image, type);
4093 field->type->attrs = fb->attrs;
4095 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4096 return_if_nok (error);
4099 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
4100 char *base = mono_array_addr (rva_data, char, 0);
4101 size_t size = mono_array_length (rva_data);
4102 char *data = (char *)mono_image_alloc (klass->image, size);
4103 memcpy (data, base, size);
4104 klass->ext->field_def_values [i].data = data;
4106 if (fb->offset != -1)
4107 field->offset = fb->offset;
4108 field->parent = klass;
4110 mono_save_custom_attrs (klass->image, field, fb->cattrs);
4112 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
4113 klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
4115 if (fb->def_value) {
4116 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4117 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
4118 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
4119 /* Copy the data from the blob since it might get realloc-ed */
4120 p = assembly->blob.data + idx;
4121 len = mono_metadata_decode_blob_size (p, &p2);
4123 klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
4124 memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
4128 klass->instance_size = MAX (klass->instance_size, real_size);
4129 mono_class_layout_fields (klass, klass->instance_size);
4133 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
4135 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4136 MonoReflectionPropertyBuilder *pb;
4137 MonoImage *image = klass->image;
4138 MonoProperty *properties;
4141 mono_error_init (error);
4144 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4146 klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
4147 klass->ext->property.first = 0;
4149 properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
4150 klass->ext->properties = properties;
4151 for (i = 0; i < klass->ext->property.count; ++i) {
4152 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
4153 properties [i].parent = klass;
4154 properties [i].attrs = pb->attrs;
4155 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
4156 if (!mono_error_ok (error))
4159 properties [i].get = pb->get_method->mhandle;
4161 properties [i].set = pb->set_method->mhandle;
4163 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
4164 if (pb->def_value) {
4167 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4168 if (!klass->ext->prop_def_values)
4169 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
4170 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
4171 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
4172 /* Copy the data from the blob since it might get realloc-ed */
4173 p = assembly->blob.data + idx;
4174 len = mono_metadata_decode_blob_size (p, &p2);
4176 klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
4177 memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
4182 static MonoReflectionEvent *
4183 reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
4185 mono_error_init (error);
4187 MonoEvent *event = g_new0 (MonoEvent, 1);
4190 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4191 if (!is_ok (error)) {
4195 klass = mono_class_from_mono_type (type);
4197 event->parent = klass;
4198 event->attrs = eb->attrs;
4199 event->name = mono_string_to_utf8_checked (eb->name, error);
4200 if (!is_ok (error)) {
4205 event->add = eb->add_method->mhandle;
4206 if (eb->remove_method)
4207 event->remove = eb->remove_method->mhandle;
4208 if (eb->raise_method)
4209 event->raise = eb->raise_method->mhandle;
4211 #ifndef MONO_SMALL_CONFIG
4212 if (eb->other_methods) {
4214 event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
4215 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4216 MonoReflectionMethodBuilder *mb =
4217 mono_array_get (eb->other_methods,
4218 MonoReflectionMethodBuilder*, j);
4219 event->other [j] = mb->mhandle;
4224 MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
4225 if (!is_ok (error)) {
4226 #ifndef MONO_SMALL_CONFIG
4227 g_free (event->other);
4235 MonoReflectionEvent *
4236 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
4239 MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
4240 mono_error_set_pending_exception (&error);
4245 typebuilder_setup_events (MonoClass *klass, MonoError *error)
4247 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4248 MonoReflectionEventBuilder *eb;
4249 MonoImage *image = klass->image;
4253 mono_error_init (error);
4256 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4258 klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
4259 klass->ext->event.first = 0;
4261 events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
4262 klass->ext->events = events;
4263 for (i = 0; i < klass->ext->event.count; ++i) {
4264 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
4265 events [i].parent = klass;
4266 events [i].attrs = eb->attrs;
4267 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
4268 if (!mono_error_ok (error))
4271 events [i].add = eb->add_method->mhandle;
4272 if (eb->remove_method)
4273 events [i].remove = eb->remove_method->mhandle;
4274 if (eb->raise_method)
4275 events [i].raise = eb->raise_method->mhandle;
4277 #ifndef MONO_SMALL_CONFIG
4278 if (eb->other_methods) {
4280 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
4281 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4282 MonoReflectionMethodBuilder *mb =
4283 mono_array_get (eb->other_methods,
4284 MonoReflectionMethodBuilder*, j);
4285 events [i].other [j] = mb->mhandle;
4289 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
4293 struct remove_instantiations_user_data
4300 remove_instantiations_of_and_ensure_contents (gpointer key,
4304 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
4305 MonoType *type = (MonoType*)key;
4306 MonoClass *klass = data->klass;
4307 gboolean already_failed = !is_ok (data->error);
4309 MonoError *error = already_failed ? &lerror : data->error;
4311 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
4312 MonoClass *inst_klass = mono_class_from_mono_type (type);
4313 //Ensure it's safe to use it.
4314 if (!fix_partial_generic_class (inst_klass, error)) {
4315 mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4316 // Marked the class with failure, but since some other instantiation already failed,
4317 // just report that one, and swallow the error from this one.
4319 mono_error_cleanup (error);
4327 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4332 MonoReflectionType* res;
4335 mono_error_init (&error);
4337 domain = mono_object_domain (tb);
4338 klass = mono_class_from_mono_type (tb->type.type);
4340 mono_save_custom_attrs (klass->image, klass, tb->cattrs);
4343 * we need to lock the domain because the lock will be taken inside
4344 * So, we need to keep the locking order correct.
4346 mono_loader_lock ();
4347 mono_domain_lock (domain);
4348 if (klass->wastypebuilder) {
4349 mono_domain_unlock (domain);
4350 mono_loader_unlock ();
4352 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4353 mono_error_set_pending_exception (&error);
4358 * Fields to set in klass:
4359 * the various flags: delegate/unicode/contextbound etc.
4361 klass->flags = tb->attrs;
4362 klass->has_cctor = 1;
4364 mono_class_setup_parent (klass, klass->parent);
4365 /* fool mono_class_setup_supertypes */
4366 klass->supertypes = NULL;
4367 mono_class_setup_supertypes (klass);
4368 mono_class_setup_mono_type (klass);
4371 if (!((MonoDynamicImage*)klass->image)->run) {
4372 if (klass->generic_container) {
4373 /* FIXME: The code below can't handle generic classes */
4374 klass->wastypebuilder = TRUE;
4375 mono_loader_unlock ();
4376 mono_domain_unlock (domain);
4378 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4379 mono_error_set_pending_exception (&error);
4386 /* enums are done right away */
4387 if (!klass->enumtype)
4388 if (!ensure_runtime_vtable (klass, &error))
4392 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
4393 MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
4394 mono_class_alloc_ext (klass);
4395 MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
4396 if (!is_ok (&error)) goto failure;
4397 klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
4401 klass->nested_classes_inited = TRUE;
4403 /* fields and object layout */
4404 if (klass->parent) {
4405 if (!klass->parent->size_inited)
4406 mono_class_init (klass->parent);
4407 klass->instance_size = klass->parent->instance_size;
4408 klass->sizes.class_size = 0;
4409 klass->min_align = klass->parent->min_align;
4410 /* if the type has no fields we won't call the field_setup
4411 * routine which sets up klass->has_references.
4413 klass->has_references |= klass->parent->has_references;
4415 klass->instance_size = sizeof (MonoObject);
4416 klass->min_align = 1;
4419 /* FIXME: handle packing_size and instance_size */
4420 typebuilder_setup_fields (klass, &error);
4421 if (!mono_error_ok (&error))
4423 typebuilder_setup_properties (klass, &error);
4424 if (!mono_error_ok (&error))
4427 typebuilder_setup_events (klass, &error);
4428 if (!mono_error_ok (&error))
4431 klass->wastypebuilder = TRUE;
4434 * If we are a generic TypeBuilder, there might be instantiations in the type cache
4435 * which have type System.Reflection.MonoGenericClass, but after the type is created,
4436 * we want to return normal System.MonoType objects, so clear these out from the cache.
4438 * Together with this we must ensure the contents of all instances to match the created type.
4440 if (domain->type_hash && klass->generic_container) {
4441 struct remove_instantiations_user_data data;
4443 data.error = &error;
4444 mono_error_assert_ok (&error);
4445 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
4446 if (!is_ok (&error))
4450 mono_domain_unlock (domain);
4451 mono_loader_unlock ();
4453 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
4454 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4455 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
4456 goto failure_unlocked;
4459 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4460 if (!is_ok (&error))
4461 goto failure_unlocked;
4463 g_assert (res != (MonoReflectionType*)tb);
4468 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4469 klass->wastypebuilder = TRUE;
4470 mono_domain_unlock (domain);
4471 mono_loader_unlock ();
4473 mono_error_set_pending_exception (&error);
4478 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
4480 MonoGenericParamFull *param;
4484 mono_error_init (error);
4486 image = &gparam->tbuilder->module->dynamic_image->image;
4488 param = mono_image_new0 (image, MonoGenericParamFull, 1);
4490 param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
4491 mono_error_assert_ok (error);
4492 param->param.num = gparam->index;
4494 if (gparam->mbuilder) {
4495 if (!gparam->mbuilder->generic_container) {
4496 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
4497 return_val_if_nok (error, FALSE);
4499 MonoClass *klass = mono_class_from_mono_type (tb);
4500 gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4501 gparam->mbuilder->generic_container->is_method = TRUE;
4503 * Cannot set owner.method, since the MonoMethod is not created yet.
4504 * Set the image field instead, so type_in_image () works.
4506 gparam->mbuilder->generic_container->is_anonymous = TRUE;
4507 gparam->mbuilder->generic_container->owner.image = klass->image;
4509 param->param.owner = gparam->mbuilder->generic_container;
4510 } else if (gparam->tbuilder) {
4511 if (!gparam->tbuilder->generic_container) {
4512 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
4513 return_val_if_nok (error, FALSE);
4514 MonoClass *klass = mono_class_from_mono_type (tb);
4515 gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4516 gparam->tbuilder->generic_container->owner.klass = klass;
4518 param->param.owner = gparam->tbuilder->generic_container;
4521 pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
4523 gparam->type.type = &pklass->byval_arg;
4525 mono_class_set_ref_info (pklass, gparam);
4526 mono_image_append_class_to_reflection_info_set (pklass);
4532 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
4535 (void) reflection_initialize_generic_parameter (gparam, &error);
4536 mono_error_set_pending_exception (&error);
4543 } DynamicMethodReleaseData;
4546 * The runtime automatically clean up those after finalization.
4548 static MonoReferenceQueue *dynamic_method_queue;
4551 free_dynamic_method (void *dynamic_method)
4553 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
4554 MonoDomain *domain = data->domain;
4555 MonoMethod *method = data->handle;
4558 mono_domain_lock (domain);
4559 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
4560 g_hash_table_remove (domain->method_to_dyn_method, method);
4561 mono_domain_unlock (domain);
4562 g_assert (dis_link);
4563 mono_gchandle_free (dis_link);
4565 mono_runtime_free_method (domain, method);
4570 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
4572 MonoReferenceQueue *queue;
4574 DynamicMethodReleaseData *release_data;
4575 ReflectionMethodBuilder rmb;
4576 MonoMethodSignature *sig;
4582 mono_error_init (error);
4584 if (mono_runtime_is_shutting_down ()) {
4585 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
4589 if (!(queue = dynamic_method_queue)) {
4590 mono_loader_lock ();
4591 if (!(queue = dynamic_method_queue))
4592 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
4593 mono_loader_unlock ();
4596 sig = dynamic_method_to_signature (mb, error);
4597 return_val_if_nok (error, FALSE);
4599 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
4602 * Resolve references.
4605 * Every second entry in the refs array is reserved for storing handle_class,
4606 * which is needed by the ldtoken implementation in the JIT.
4608 rmb.nrefs = mb->nrefs;
4609 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
4610 for (i = 0; i < mb->nrefs; i += 2) {
4611 MonoClass *handle_class;
4613 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
4615 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4616 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4618 * The referenced DynamicMethod should already be created by the managed
4619 * code, except in the case of circular references. In that case, we store
4620 * method in the refs array, and fix it up later when the referenced
4621 * DynamicMethod is created.
4623 if (method->mhandle) {
4624 ref = method->mhandle;
4626 /* FIXME: GC object stored in unmanaged memory */
4629 /* FIXME: GC object stored in unmanaged memory */
4630 method->referenced_by = g_slist_append (method->referenced_by, mb);
4632 handle_class = mono_defaults.methodhandle_class;
4634 MonoException *ex = NULL;
4635 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
4636 if (!is_ok (error)) {
4641 ex = mono_get_exception_type_load (NULL, NULL);
4642 else if (mono_security_core_clr_enabled ())
4643 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
4647 mono_error_set_exception_instance (error, ex);
4652 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4653 rmb.refs [i + 1] = handle_class;
4657 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
4658 if (!is_ok (error)) {
4662 klass = mono_class_from_mono_type (owner_type);
4664 klass = mono_defaults.object_class;
4667 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
4669 return_val_if_nok (error, FALSE);
4671 release_data = g_new (DynamicMethodReleaseData, 1);
4672 release_data->handle = handle;
4673 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
4674 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
4675 g_free (release_data);
4677 /* Fix up refs entries pointing at us */
4678 for (l = mb->referenced_by; l; l = l->next) {
4679 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
4680 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
4683 g_assert (method->mhandle);
4685 data = (gpointer*)wrapper->method_data;
4686 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
4687 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
4688 data [i + 1] = mb->mhandle;
4691 g_slist_free (mb->referenced_by);
4693 /* ilgen is no longer needed */
4696 domain = mono_domain_get ();
4697 mono_domain_lock (domain);
4698 if (!domain->method_to_dyn_method)
4699 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4700 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4701 mono_domain_unlock (domain);
4707 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4710 (void) reflection_create_dynamic_method (mb, &error);
4711 mono_error_set_pending_exception (&error);
4714 #endif /* DISABLE_REFLECTION_EMIT */
4716 MonoMethodSignature *
4717 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4719 MonoMethodSignature *sig;
4720 g_assert (image_is_dynamic (image));
4722 mono_error_init (error);
4724 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4728 return mono_method_signature_checked (method, error);
4731 #ifndef DISABLE_REFLECTION_EMIT
4734 * ensure_complete_type:
4736 * Ensure that KLASS is completed if it is a dynamic type, or references
4740 ensure_complete_type (MonoClass *klass, MonoError *error)
4742 mono_error_init (error);
4744 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
4745 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4747 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4748 return_if_nok (error);
4750 // Asserting here could break a lot of code
4751 //g_assert (klass->wastypebuilder);
4754 if (klass->generic_class) {
4755 MonoGenericInst *inst = klass->generic_class->context.class_inst;
4758 for (i = 0; i < inst->type_argc; ++i) {
4759 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4760 return_if_nok (error);
4766 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4768 gpointer result = NULL;
4770 mono_error_init (error);
4772 if (strcmp (obj->vtable->klass->name, "String") == 0) {
4773 result = mono_string_intern_checked ((MonoString*)obj, error);
4774 return_val_if_nok (error, NULL);
4775 *handle_class = mono_defaults.string_class;
4777 } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
4778 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4779 return_val_if_nok (error, NULL);
4780 MonoClass *mc = mono_class_from_mono_type (type);
4781 if (!mono_class_init (mc)) {
4782 mono_error_set_for_class_failure (error, mc);
4787 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4788 return_val_if_nok (error, NULL);
4790 result = mono_class_from_mono_type (inflated);
4791 mono_metadata_free_type (inflated);
4793 result = mono_class_from_mono_type (type);
4795 *handle_class = mono_defaults.typehandle_class;
4797 } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
4798 strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
4799 strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
4800 strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
4801 result = ((MonoReflectionMethod*)obj)->method;
4803 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4804 mono_error_assert_ok (error);
4806 *handle_class = mono_defaults.methodhandle_class;
4808 } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
4809 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
4810 result = mb->mhandle;
4812 /* Type is not yet created */
4813 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
4815 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4816 return_val_if_nok (error, NULL);
4819 * Hopefully this has been filled in by calling CreateType() on the
4823 * TODO: This won't work if the application finishes another
4824 * TypeBuilder instance instead of this one.
4826 result = mb->mhandle;
4829 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4830 mono_error_assert_ok (error);
4832 *handle_class = mono_defaults.methodhandle_class;
4833 } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
4834 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
4836 result = cb->mhandle;
4838 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
4840 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4841 return_val_if_nok (error, NULL);
4842 result = cb->mhandle;
4845 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4846 mono_error_assert_ok (error);
4848 *handle_class = mono_defaults.methodhandle_class;
4849 } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
4850 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4852 ensure_complete_type (field->parent, error);
4853 return_val_if_nok (error, NULL);
4856 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
4857 return_val_if_nok (error, NULL);
4859 MonoClass *klass = mono_class_from_mono_type (inflated);
4860 MonoClassField *inflated_field;
4861 gpointer iter = NULL;
4862 mono_metadata_free_type (inflated);
4863 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
4864 if (!strcmp (field->name, inflated_field->name))
4867 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4868 result = inflated_field;
4872 *handle_class = mono_defaults.fieldhandle_class;
4874 } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
4875 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
4876 result = fb->handle;
4879 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
4881 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4882 return_val_if_nok (error, NULL);
4883 result = fb->handle;
4886 if (fb->handle && fb->handle->parent->generic_container) {
4887 MonoClass *klass = fb->handle->parent;
4888 MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
4889 return_val_if_nok (error, NULL);
4891 MonoClass *inflated = mono_class_from_mono_type (type);
4893 result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
4895 mono_metadata_free_type (type);
4897 *handle_class = mono_defaults.fieldhandle_class;
4898 } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
4899 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
4900 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4901 return_val_if_nok (error, NULL);
4904 klass = type->data.klass;
4905 if (klass->wastypebuilder) {
4906 /* Already created */
4910 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4911 return_val_if_nok (error, NULL);
4912 result = type->data.klass;
4915 *handle_class = mono_defaults.typehandle_class;
4916 } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
4917 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4918 MonoMethodSignature *sig;
4921 if (helper->arguments)
4922 nargs = mono_array_length (helper->arguments);
4926 sig = mono_metadata_signature_alloc (image, nargs);
4927 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4928 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4930 if (helper->unmanaged_call_conv) { /* unmanaged */
4931 sig->call_convention = helper->unmanaged_call_conv - 1;
4932 sig->pinvoke = TRUE;
4933 } else if (helper->call_conv & 0x02) {
4934 sig->call_convention = MONO_CALL_VARARG;
4936 sig->call_convention = MONO_CALL_DEFAULT;
4939 sig->param_count = nargs;
4940 /* TODO: Copy type ? */
4941 sig->ret = helper->return_type->type;
4942 for (i = 0; i < nargs; ++i) {
4943 sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
4944 if (!is_ok (error)) {
4945 image_g_free (image, sig);
4951 *handle_class = NULL;
4952 } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4953 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4954 /* Already created by the managed code */
4955 g_assert (method->mhandle);
4956 result = method->mhandle;
4957 *handle_class = mono_defaults.methodhandle_class;
4958 } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
4959 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4960 return_val_if_nok (error, NULL);
4961 type = mono_class_inflate_generic_type_checked (type, context, error);
4962 return_val_if_nok (error, NULL);
4964 result = mono_class_from_mono_type (type);
4965 *handle_class = mono_defaults.typehandle_class;
4967 mono_metadata_free_type (type);
4968 } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
4969 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4970 return_val_if_nok (error, NULL);
4971 type = mono_class_inflate_generic_type_checked (type, context, error);
4972 return_val_if_nok (error, NULL);
4974 result = mono_class_from_mono_type (type);
4975 *handle_class = mono_defaults.typehandle_class;
4977 mono_metadata_free_type (type);
4978 } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
4979 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
4980 MonoClass *inflated;
4982 MonoClassField *field;
4984 if (is_sre_field_builder (mono_object_class (f->fb)))
4985 field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
4986 else if (is_sr_mono_field (mono_object_class (f->fb)))
4987 field = ((MonoReflectionField*)f->fb)->field;
4989 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)));
4991 MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
4992 return_val_if_nok (error, NULL);
4993 type = mono_class_inflate_generic_type_checked (finst, context, error);
4994 return_val_if_nok (error, NULL);
4996 inflated = mono_class_from_mono_type (type);
4998 result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
4999 ensure_complete_type (field->parent, error);
5000 if (!is_ok (error)) {
5001 mono_metadata_free_type (type);
5006 mono_metadata_free_type (type);
5007 *handle_class = mono_defaults.fieldhandle_class;
5008 } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
5009 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
5010 MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
5011 return_val_if_nok (error, NULL);
5012 MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
5013 return_val_if_nok (error, NULL);
5015 MonoClass *inflated_klass = mono_class_from_mono_type (type);
5018 if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
5019 method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
5020 else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
5021 method = ((MonoReflectionMethod *)c->cb)->method;
5023 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)));
5025 result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
5026 *handle_class = mono_defaults.methodhandle_class;
5027 mono_metadata_free_type (type);
5028 } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
5029 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
5030 if (m->method_args) {
5031 result = mono_reflection_method_on_tb_inst_get_handle (m, error);
5032 return_val_if_nok (error, NULL);
5034 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5035 mono_error_assert_ok (error);
5038 MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
5039 return_val_if_nok (error, NULL);
5040 MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
5041 return_val_if_nok (error, NULL);
5043 MonoClass *inflated_klass = mono_class_from_mono_type (type);
5046 if (is_sre_method_builder (mono_object_class (m->mb)))
5047 method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
5048 else if (is_sr_mono_method (mono_object_class (m->mb)))
5049 method = ((MonoReflectionMethod *)m->mb)->method;
5051 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)));
5053 result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
5054 mono_metadata_free_type (type);
5056 *handle_class = mono_defaults.methodhandle_class;
5057 } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
5058 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
5065 mtype = mono_reflection_type_get_handle (m->parent, error);
5066 return_val_if_nok (error, NULL);
5067 klass = mono_class_from_mono_type (mtype);
5069 /* Find the method */
5071 name = mono_string_to_utf8_checked (m->name, error);
5072 return_val_if_nok (error, NULL);
5074 while ((method = mono_class_get_methods (klass, &iter))) {
5075 if (!strcmp (method->name, name))
5082 // FIXME: Check parameters/return value etc. match
5085 *handle_class = mono_defaults.methodhandle_class;
5086 } else if (is_sre_array (mono_object_get_class(obj)) ||
5087 is_sre_byref (mono_object_get_class(obj)) ||
5088 is_sre_pointer (mono_object_get_class(obj))) {
5089 MonoReflectionType *ref_type = (MonoReflectionType *)obj;
5090 MonoType *type = mono_reflection_type_get_handle (ref_type, error);
5091 return_val_if_nok (error, NULL);
5094 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
5095 return_val_if_nok (error, NULL);
5097 result = mono_class_from_mono_type (inflated);
5098 mono_metadata_free_type (inflated);
5100 result = mono_class_from_mono_type (type);
5102 *handle_class = mono_defaults.typehandle_class;
5104 g_print ("%s\n", obj->vtable->klass->name);
5105 g_assert_not_reached ();
5110 #else /* DISABLE_REFLECTION_EMIT */
5113 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5115 g_assert_not_reached ();
5120 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
5122 g_assert_not_reached ();
5126 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
5128 g_assert_not_reached ();
5133 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5135 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
5139 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
5141 g_assert_not_reached ();
5145 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
5147 g_assert_not_reached ();
5152 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
5154 g_assert_not_reached ();
5159 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
5160 gboolean create_open_instance, gboolean register_token, MonoError *error)
5162 g_assert_not_reached ();
5167 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
5169 g_assert_not_reached ();
5173 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
5175 mono_error_init (error);
5180 MonoReflectionEvent *
5181 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
5183 g_assert_not_reached ();
5188 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
5190 g_assert_not_reached ();
5195 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
5197 g_assert_not_reached ();
5201 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
5206 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
5208 mono_error_init (error);
5214 #endif /* DISABLE_REFLECTION_EMIT */
5216 #ifndef DISABLE_REFLECTION_EMIT
5218 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5223 tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
5224 return_val_if_nok (error, NULL);
5225 klass = mono_class_from_mono_type (tb);
5227 return methodbuilder_to_mono_method (klass, mb, error);
5229 #else /* DISABLE_REFLECTION_EMIT */
5231 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5233 g_assert_not_reached ();
5236 #endif /* DISABLE_REFLECTION_EMIT */
5239 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
5241 MONO_CHECK_ARG_NULL (obj, 0);
5244 gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
5245 mono_error_set_pending_exception (&error);
5250 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
5251 MonoReflectionMethod *method,
5252 MonoArray *opt_param_types)
5254 MONO_CHECK_ARG_NULL (method, 0);
5257 gint32 result = mono_image_create_method_token (
5258 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
5259 mono_error_set_pending_exception (&error);
5264 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
5267 mono_image_create_pefile (mb, file, &error);
5268 mono_error_set_pending_exception (&error);
5272 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
5275 mono_image_build_metadata (mb, &error);
5276 mono_error_set_pending_exception (&error);
5280 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
5282 mono_image_register_token (mb->dynamic_image, token, obj);
5286 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
5290 mono_loader_lock ();
5291 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
5292 mono_loader_unlock ();
5298 * ves_icall_TypeBuilder_create_generic_class:
5299 * @tb: a TypeBuilder object
5302 * Creates the generic class after all generic parameters have been added.
5305 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
5308 (void) mono_reflection_create_generic_class (tb, &error);
5309 mono_error_set_pending_exception (&error);
5312 #ifndef DISABLE_REFLECTION_EMIT
5314 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5317 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
5318 mono_error_set_pending_exception (&error);
5324 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5326 mono_reflection_dynimage_basic_init (assemblyb);
5330 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
5332 return mono_type_is_generic_parameter (tb->type.type);
5336 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
5337 MonoReflectionType *t)
5339 enumtype->type = t->type;
5343 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5346 MonoReflectionType *ret;
5348 int isbyref = 0, rank;
5350 char *str = mono_string_to_utf8_checked (smodifiers, &error);
5351 if (mono_error_set_pending_exception (&error))
5354 klass = mono_class_from_mono_type (tb->type.type);
5356 /* logic taken from mono_reflection_parse_type(): keep in sync */
5360 if (isbyref) { /* only one level allowed by the spec */
5369 ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
5370 mono_error_set_pending_exception (&error);
5374 klass = mono_ptr_class_get (&klass->byval_arg);
5375 mono_class_init (klass);
5386 else if (*p != '*') { /* '*' means unknown lower bound */
5397 klass = mono_array_class_get (klass, rank);
5398 mono_class_init (klass);
5407 ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
5408 mono_error_set_pending_exception (&error);
5414 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
5416 mono_image_module_basic_init (moduleb);
5420 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
5422 return mono_image_insert_string (module, str);
5426 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
5428 MonoDynamicImage *image = moduleb->dynamic_image;
5430 g_assert (type->type);
5431 image->wrappers_type = mono_class_from_mono_type (type->type);