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);
45 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
47 #ifndef DISABLE_REFLECTION_EMIT
48 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
49 static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
50 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
51 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
52 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
53 static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
54 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
56 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
59 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
60 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
61 static gboolean is_sre_array (MonoClass *klass);
62 static gboolean is_sre_byref (MonoClass *klass);
63 static gboolean is_sre_pointer (MonoClass *klass);
64 static gboolean is_sre_type_builder (MonoClass *klass);
65 static gboolean is_sre_method_builder (MonoClass *klass);
66 static gboolean is_sre_field_builder (MonoClass *klass);
67 static gboolean is_sr_mono_method (MonoClass *klass);
68 static gboolean is_sr_mono_generic_method (MonoClass *klass);
69 static gboolean is_sr_mono_generic_cmethod (MonoClass *klass);
70 static gboolean is_sr_mono_field (MonoClass *klass);
72 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
73 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
74 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
76 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
78 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
81 mono_reflection_emit_init (void)
83 mono_dynamic_images_init ();
87 type_get_fully_qualified_name (MonoType *type)
89 MONO_REQ_GC_NEUTRAL_MODE;
91 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
95 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
97 MONO_REQ_GC_UNSAFE_MODE;
102 klass = mono_class_from_mono_type (type);
104 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
105 ta = klass->image->assembly;
106 if (assembly_is_dynamic (ta) || (ta == ass)) {
107 if (klass->generic_class || klass->generic_container)
108 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
109 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
111 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
114 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
117 #ifndef DISABLE_REFLECTION_EMIT
121 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
125 image_g_malloc (MonoImage *image, guint size)
127 MONO_REQ_GC_NEUTRAL_MODE;
130 return mono_image_alloc (image, size);
132 return g_malloc (size);
134 #endif /* !DISABLE_REFLECTION_EMIT */
139 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
143 mono_image_g_malloc0 (MonoImage *image, guint size)
145 MONO_REQ_GC_NEUTRAL_MODE;
148 return mono_image_alloc0 (image, size);
150 return g_malloc0 (size);
155 * @image: a MonoImage
158 * If @image is NULL, free @ptr, otherwise do nothing.
161 image_g_free (MonoImage *image, gpointer ptr)
167 #ifndef DISABLE_REFLECTION_EMIT
169 image_strdup (MonoImage *image, const char *s)
171 MONO_REQ_GC_NEUTRAL_MODE;
174 return mono_image_strdup (image, s);
180 #define image_g_new(image,struct_type, n_structs) \
181 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
183 #define image_g_new0(image,struct_type, n_structs) \
184 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
188 alloc_table (MonoDynamicTable *table, guint nrows)
190 mono_dynimage_alloc_table (table, nrows);
194 string_heap_insert (MonoDynamicStream *sh, const char *str)
196 return mono_dynstream_insert_string (sh, str);
200 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
202 return mono_dynstream_add_data (stream, data, len);
206 * Despite the name, we handle also TypeSpec (with the above helper).
209 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
211 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
215 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
216 * dest may be misaligned.
219 swap_with_size (char *dest, const char* val, int len, int nelem) {
220 MONO_REQ_GC_NEUTRAL_MODE;
221 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
224 for (elem = 0; elem < nelem; ++elem) {
250 g_assert_not_reached ();
256 memcpy (dest, val, len * nelem);
261 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
263 MONO_REQ_GC_UNSAFE_MODE;
265 guint32 num_clauses = 0;
268 MonoILExceptionInfo *ex_info;
269 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
270 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
271 if (ex_info->handlers)
272 num_clauses += mono_array_length (ex_info->handlers);
280 #ifndef DISABLE_REFLECTION_EMIT
281 static MonoExceptionClause*
282 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
284 MONO_REQ_GC_UNSAFE_MODE;
286 mono_error_init (error);
288 MonoExceptionClause *clauses;
289 MonoExceptionClause *clause;
290 MonoILExceptionInfo *ex_info;
291 MonoILExceptionBlock *ex_block;
292 guint32 finally_start;
293 int i, j, clause_index;;
295 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
298 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
299 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
300 finally_start = ex_info->start + ex_info->len;
301 if (!ex_info->handlers)
303 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
304 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
305 clause = &(clauses [clause_index]);
307 clause->flags = ex_block->type;
308 clause->try_offset = ex_info->start;
310 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
311 clause->try_len = finally_start - ex_info->start;
313 clause->try_len = ex_info->len;
314 clause->handler_offset = ex_block->start;
315 clause->handler_len = ex_block->len;
316 if (ex_block->extype) {
317 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
319 if (!is_ok (error)) {
320 image_g_free (image, clauses);
323 clause->data.catch_class = mono_class_from_mono_type (extype);
325 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
326 clause->data.filter_offset = ex_block->filter_offset;
328 clause->data.filter_offset = 0;
330 finally_start = ex_block->start + ex_block->len;
338 #endif /* !DISABLE_REFLECTION_EMIT */
340 #ifndef DISABLE_REFLECTION_EMIT
342 * LOCKING: Acquires the loader lock.
345 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
347 MONO_REQ_GC_UNSAFE_MODE;
349 MonoCustomAttrInfo *ainfo, *tmp;
351 if (!cattrs || !mono_array_length (cattrs))
354 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
357 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
359 mono_custom_attrs_free (tmp);
360 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
361 mono_loader_unlock ();
368 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
370 MONO_REQ_GC_UNSAFE_MODE;
372 MonoDynamicTable *table;
375 guint32 cols [MONO_ASSEMBLY_SIZE];
379 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
382 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
383 table = &assembly->tables [MONO_TABLE_MODULEREF];
384 token = table->next_idx ++;
386 alloc_table (table, table->rows);
387 values = table->values + token * MONO_MODULEREF_SIZE;
388 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
390 token <<= MONO_RESOLUTION_SCOPE_BITS;
391 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
392 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
397 if (assembly_is_dynamic (image->assembly))
399 memset (cols, 0, sizeof (cols));
401 /* image->assembly->image is the manifest module */
402 image = image->assembly->image;
403 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
406 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
407 token = table->next_idx ++;
409 alloc_table (table, table->rows);
410 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
411 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
412 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
413 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
414 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
415 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
416 values [MONO_ASSEMBLYREF_FLAGS] = 0;
417 values [MONO_ASSEMBLYREF_CULTURE] = 0;
418 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
420 if (strcmp ("", image->assembly->aname.culture)) {
421 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
422 image->assembly->aname.culture);
425 if ((pubkey = mono_image_get_public_key (image, &publen))) {
428 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
429 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
431 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
433 token <<= MONO_RESOLUTION_SCOPE_BITS;
434 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
435 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
439 #ifndef DISABLE_REFLECTION_EMIT
441 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
443 MONO_REQ_GC_UNSAFE_MODE;
445 mono_error_init (error);
446 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
448 rmb->ilgen = mb->ilgen;
449 rmb->rtype = (MonoReflectionType*)mb->rtype;
450 return_val_if_nok (error, FALSE);
451 rmb->parameters = mb->parameters;
452 rmb->generic_params = mb->generic_params;
453 rmb->generic_container = mb->generic_container;
454 rmb->opt_types = NULL;
455 rmb->pinfo = mb->pinfo;
456 rmb->attrs = mb->attrs;
457 rmb->iattrs = mb->iattrs;
458 rmb->call_conv = mb->call_conv;
459 rmb->code = mb->code;
460 rmb->type = mb->type;
461 rmb->name = mb->name;
462 rmb->table_idx = &mb->table_idx;
463 rmb->init_locals = mb->init_locals;
464 rmb->skip_visibility = FALSE;
465 rmb->return_modreq = mb->return_modreq;
466 rmb->return_modopt = mb->return_modopt;
467 rmb->param_modreq = mb->param_modreq;
468 rmb->param_modopt = mb->param_modopt;
469 rmb->permissions = mb->permissions;
470 rmb->mhandle = mb->mhandle;
475 rmb->charset = mb->charset;
476 rmb->extra_flags = mb->extra_flags;
477 rmb->native_cc = mb->native_cc;
478 rmb->dllentry = mb->dllentry;
486 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
488 MONO_REQ_GC_UNSAFE_MODE;
490 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
492 mono_error_init (error);
494 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
496 rmb->ilgen = mb->ilgen;
497 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
498 return_val_if_nok (error, FALSE);
499 rmb->parameters = mb->parameters;
500 rmb->generic_params = NULL;
501 rmb->generic_container = NULL;
502 rmb->opt_types = NULL;
503 rmb->pinfo = mb->pinfo;
504 rmb->attrs = mb->attrs;
505 rmb->iattrs = mb->iattrs;
506 rmb->call_conv = mb->call_conv;
508 rmb->type = mb->type;
509 rmb->name = mono_string_new (mono_domain_get (), name);
510 rmb->table_idx = &mb->table_idx;
511 rmb->init_locals = mb->init_locals;
512 rmb->skip_visibility = FALSE;
513 rmb->return_modreq = NULL;
514 rmb->return_modopt = NULL;
515 rmb->param_modreq = mb->param_modreq;
516 rmb->param_modopt = mb->param_modopt;
517 rmb->permissions = mb->permissions;
518 rmb->mhandle = mb->mhandle;
526 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
528 MONO_REQ_GC_UNSAFE_MODE;
530 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
532 rmb->ilgen = mb->ilgen;
533 rmb->rtype = mb->rtype;
534 rmb->parameters = mb->parameters;
535 rmb->generic_params = NULL;
536 rmb->generic_container = NULL;
537 rmb->opt_types = NULL;
539 rmb->attrs = mb->attrs;
541 rmb->call_conv = mb->call_conv;
543 rmb->type = (MonoObject *) mb->owner;
544 rmb->name = mb->name;
545 rmb->table_idx = NULL;
546 rmb->init_locals = mb->init_locals;
547 rmb->skip_visibility = mb->skip_visibility;
548 rmb->return_modreq = NULL;
549 rmb->return_modopt = NULL;
550 rmb->param_modreq = NULL;
551 rmb->param_modopt = NULL;
552 rmb->permissions = NULL;
553 rmb->mhandle = mb->mhandle;
557 #else /* DISABLE_REFLECTION_EMIT */
559 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
560 g_assert_not_reached ();
564 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
566 g_assert_not_reached ();
569 #endif /* DISABLE_REFLECTION_EMIT */
571 #ifndef DISABLE_REFLECTION_EMIT
573 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
575 MONO_REQ_GC_NEUTRAL_MODE;
577 MonoDynamicTable *table;
579 guint32 token, pclass;
581 switch (parent & MONO_TYPEDEFORREF_MASK) {
582 case MONO_TYPEDEFORREF_TYPEREF:
583 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
585 case MONO_TYPEDEFORREF_TYPESPEC:
586 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
588 case MONO_TYPEDEFORREF_TYPEDEF:
589 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
592 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
595 /* extract the index */
596 parent >>= MONO_TYPEDEFORREF_BITS;
598 table = &assembly->tables [MONO_TABLE_MEMBERREF];
600 if (assembly->save) {
601 alloc_table (table, table->rows + 1);
602 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
603 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
604 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
605 values [MONO_MEMBERREF_SIGNATURE] = sig;
608 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
615 * Insert a memberef row into the metadata: the token that point to the memberref
616 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
617 * mono_image_get_fieldref_token()).
618 * The sig param is an index to an already built signature.
621 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
623 MONO_REQ_GC_NEUTRAL_MODE;
625 guint32 parent = mono_image_typedef_or_ref (assembly, type);
626 return mono_image_add_memberef_row (assembly, parent, name, sig);
631 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
633 MONO_REQ_GC_NEUTRAL_MODE;
636 MonoMethodSignature *sig;
638 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
640 if (create_typespec) {
641 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
646 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
647 if (token && !create_typespec)
650 g_assert (!method->is_inflated);
653 * A methodref signature can't contain an unmanaged calling convention.
655 sig = mono_metadata_signature_dup (mono_method_signature (method));
656 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
657 sig->call_convention = MONO_CALL_DEFAULT;
658 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
659 method->name, mono_dynimage_encode_method_signature (assembly, sig));
661 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
664 if (create_typespec) {
665 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
666 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
667 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
669 if (assembly->save) {
672 alloc_table (table, table->rows + 1);
673 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
674 values [MONO_METHODSPEC_METHOD] = token;
675 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
678 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
680 /*methodspec and memberef tokens are diferent, */
681 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
688 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
690 guint32 token, parent, sig;
691 ReflectionMethodBuilder rmb;
692 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
694 mono_error_init (error);
695 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
699 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
703 * A methodref signature can't contain an unmanaged calling convention.
704 * Since some flags are encoded as part of call_conv, we need to check against it.
706 if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
707 rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
709 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
710 return_val_if_nok (error, 0);
712 if (tb->generic_params) {
713 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
714 return_val_if_nok (error, 0);
716 MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
717 return_val_if_nok (error, 0);
719 parent = mono_image_typedef_or_ref (assembly, t);
722 char *name = mono_string_to_utf8_checked (method->name, error);
723 return_val_if_nok (error, 0);
725 token = mono_image_add_memberef_row (assembly, parent, name, sig);
728 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
734 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
735 const gchar *name, guint32 sig)
737 MonoDynamicTable *table;
741 table = &assembly->tables [MONO_TABLE_MEMBERREF];
743 if (assembly->save) {
744 alloc_table (table, table->rows + 1);
745 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
746 values [MONO_MEMBERREF_CLASS] = original;
747 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
748 values [MONO_MEMBERREF_SIGNATURE] = sig;
751 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
758 mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
760 MonoDynamicTable *table;
762 guint32 token, mtoken = 0;
764 mono_error_init (error);
765 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
769 table = &assembly->tables [MONO_TABLE_METHODSPEC];
771 mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
772 if (!mono_error_ok (error))
775 switch (mono_metadata_token_table (mtoken)) {
776 case MONO_TABLE_MEMBERREF:
777 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
779 case MONO_TABLE_METHOD:
780 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
783 g_assert_not_reached ();
786 if (assembly->save) {
787 alloc_table (table, table->rows + 1);
788 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
789 values [MONO_METHODSPEC_METHOD] = mtoken;
790 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
793 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
796 mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
801 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
805 mono_error_init (error);
807 if (mb->generic_params && create_methodspec)
808 return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
810 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
814 token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
815 if (!mono_error_ok (error))
817 mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
822 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
824 guint32 token, parent, sig;
825 ReflectionMethodBuilder rmb;
827 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
829 mono_error_init (error);
831 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
835 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
838 if (tb->generic_params) {
839 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
840 return_val_if_nok (error, 0);
842 MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
843 return_val_if_nok (error, 0);
844 parent = mono_image_typedef_or_ref (assembly, type);
847 name = mono_string_to_utf8_checked (rmb.name, error);
848 return_val_if_nok (error, 0);
849 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
850 return_val_if_nok (error, 0);
852 token = mono_image_add_memberef_row (assembly, parent, name, sig);
855 mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
861 is_field_on_inst (MonoClassField *field)
863 return field->parent->generic_class && field->parent->generic_class->is_dynamic;
866 #ifndef DISABLE_REFLECTION_EMIT
868 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
874 g_assert (field->parent);
876 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
880 if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
881 int index = field - field->parent->fields;
882 type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
884 type = mono_field_get_type (field);
886 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
887 mono_field_get_name (field),
888 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
889 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
894 mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
898 MonoGenericClass *gclass;
902 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
905 if (is_sre_field_builder (mono_object_class (f->fb))) {
906 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
907 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
908 return_val_if_nok (error, 0);
909 klass = mono_class_from_mono_type (type);
910 gclass = type->data.generic_class;
911 g_assert (gclass->is_dynamic);
913 guint32 sig_token = mono_dynimage_encode_field_signature (assembly, fb, error);
914 return_val_if_nok (error, 0);
915 name = mono_string_to_utf8_checked (fb->name, error);
916 return_val_if_nok (error, 0);
917 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
919 } else if (is_sr_mono_field (mono_object_class (f->fb))) {
921 MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
923 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
924 return_val_if_nok (error, 0);
925 klass = mono_class_from_mono_type (type);
927 sig = mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, field->type);
928 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
930 char *name = mono_type_get_full_name (mono_object_class (f->fb));
931 g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
934 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
939 mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
943 MonoGenericClass *gclass;
946 mono_error_init (error);
948 /* A ctor cannot be a generic method, so we can ignore create_methodspec */
950 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
954 if (mono_is_sre_ctor_builder (mono_object_class (c->cb))) {
955 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
956 ReflectionMethodBuilder rmb;
959 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
960 return_val_if_nok (error, 0);
961 klass = mono_class_from_mono_type (type);
963 gclass = type->data.generic_class;
964 g_assert (gclass->is_dynamic);
966 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
969 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
970 return_val_if_nok (error, 0);
972 name = mono_string_to_utf8_checked (rmb.name, error);
973 return_val_if_nok (error, 0);
975 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
977 } else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb))) {
978 MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
980 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
981 return_val_if_nok (error, 0);
982 klass = mono_class_from_mono_type (type);
984 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
985 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
987 char *name = mono_type_get_full_name (mono_object_class (c->cb));
988 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
992 mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
997 mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
1000 MonoGenericContext tmp_context;
1001 MonoType **type_argv;
1002 MonoGenericInst *ginst;
1003 MonoMethod *method, *inflated;
1006 mono_error_init (error);
1008 mono_reflection_init_type_builder_generics ((MonoObject*)m->inst, error);
1009 return_val_if_nok (error, NULL);
1011 method = inflate_method (m->inst, (MonoObject*)m->mb, error);
1012 return_val_if_nok (error, NULL);
1014 klass = method->klass;
1016 if (m->method_args == NULL)
1019 if (method->is_inflated)
1020 method = ((MonoMethodInflated *) method)->declaring;
1022 count = mono_array_length (m->method_args);
1024 type_argv = g_new0 (MonoType *, count);
1025 for (i = 0; i < count; i++) {
1026 MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
1027 type_argv [i] = mono_reflection_type_get_handle (garg, error);
1028 return_val_if_nok (error, NULL);
1030 ginst = mono_metadata_get_generic_inst (count, type_argv);
1033 tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
1034 tmp_context.method_inst = ginst;
1036 inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
1037 mono_error_assert_ok (error);
1042 mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
1044 guint32 sig, token = 0;
1048 mono_error_init (error);
1050 if (m->method_args) {
1051 MonoMethod *inflated;
1053 inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
1054 return_val_if_nok (error, 0);
1056 if (create_methodspec)
1057 token = mono_image_get_methodspec_token (assembly, inflated);
1059 token = mono_image_get_inflated_method_token (assembly, inflated);
1063 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
1067 if (is_sre_method_builder (mono_object_class (m->mb))) {
1068 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
1069 MonoGenericClass *gclass;
1070 ReflectionMethodBuilder rmb;
1073 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1074 return_val_if_nok (error, 0);
1075 klass = mono_class_from_mono_type (type);
1076 gclass = type->data.generic_class;
1077 g_assert (gclass->is_dynamic);
1079 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1082 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1083 return_val_if_nok (error, 0);
1085 name = mono_string_to_utf8_checked (rmb.name, error);
1086 return_val_if_nok (error, 0);
1088 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1090 } else if (is_sr_mono_method (mono_object_class (m->mb))) {
1091 MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
1093 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1094 return_val_if_nok (error, 0);
1095 klass = mono_class_from_mono_type (type);
1097 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1098 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1100 char *name = mono_type_get_full_name (mono_object_class (m->mb));
1101 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1104 mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
1109 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
1111 MonoDynamicTable *table;
1113 guint32 token, mtoken = 0, sig;
1114 MonoMethodInflated *imethod;
1115 MonoMethod *declaring;
1117 table = &assembly->tables [MONO_TABLE_METHODSPEC];
1119 g_assert (method->is_inflated);
1120 imethod = (MonoMethodInflated *) method;
1121 declaring = imethod->declaring;
1123 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
1124 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
1126 if (!mono_method_signature (declaring)->generic_param_count)
1129 switch (mono_metadata_token_table (mtoken)) {
1130 case MONO_TABLE_MEMBERREF:
1131 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
1133 case MONO_TABLE_METHOD:
1134 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
1137 g_assert_not_reached ();
1140 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
1142 if (assembly->save) {
1143 alloc_table (table, table->rows + 1);
1144 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
1145 values [MONO_METHODSPEC_METHOD] = mtoken;
1146 values [MONO_METHODSPEC_SIGNATURE] = sig;
1149 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
1156 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
1158 MonoMethodInflated *imethod;
1161 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
1165 g_assert (method->is_inflated);
1166 imethod = (MonoMethodInflated *) method;
1168 if (mono_method_signature (imethod->declaring)->generic_param_count) {
1169 token = method_encode_methodspec (assembly, method);
1171 guint32 sig = mono_dynimage_encode_method_signature (
1172 assembly, mono_method_signature (imethod->declaring));
1173 token = mono_image_get_memberref_token (
1174 assembly, &method->klass->byval_arg, method->name, sig);
1177 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
1182 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
1184 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
1187 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
1188 token = mono_image_get_memberref_token (
1189 assembly, &m->klass->byval_arg, m->name, sig);
1195 * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
1198 add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
1200 int i, count, len, pos;
1203 mono_error_init (error);
1207 count += mono_array_length (modreq);
1209 count += mono_array_length (modopt);
1212 return mono_metadata_type_dup (NULL, type);
1214 len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
1215 t = (MonoType *)g_malloc (len);
1216 memcpy (t, type, MONO_SIZEOF_TYPE);
1218 t->num_mods = count;
1221 for (i = 0; i < mono_array_length (modreq); ++i) {
1222 MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
1225 t->modifiers [pos].required = 1;
1226 t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1231 for (i = 0; i < mono_array_length (modopt); ++i) {
1232 MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
1235 t->modifiers [pos].required = 0;
1236 t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1248 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
1250 MonoReflectionTypeBuilder *tb;
1252 mono_error_init (error);
1254 if (!is_sre_type_builder(mono_object_class (type)))
1256 tb = (MonoReflectionTypeBuilder *)type;
1258 if (tb && tb->generic_container)
1259 mono_reflection_create_generic_class (tb, error);
1263 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
1265 MonoDynamicTable *table;
1266 MonoType *custom = NULL, *type;
1268 guint32 token, pclass, parent, sig;
1271 mono_error_init (error);
1273 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
1277 MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
1278 return_val_if_nok (error, 0);
1279 /* FIXME: is this call necessary? */
1280 mono_class_from_mono_type (typeb);
1282 /*FIXME this is one more layer of ugliness due how types are created.*/
1283 mono_reflection_init_type_builder_generics (fb->type, error);
1284 return_val_if_nok (error, 0);
1286 /* fb->type does not include the custom modifiers */
1287 /* FIXME: We should do this in one place when a fieldbuilder is created */
1288 type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1289 return_val_if_nok (error, 0);
1291 if (fb->modreq || fb->modopt) {
1292 type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
1293 return_val_if_nok (error, 0);
1296 sig = mono_dynimage_encode_fieldref_signature (assembly, NULL, type);
1299 parent = mono_dynimage_encode_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
1300 return_val_if_nok (error, 0);
1301 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
1303 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
1304 parent >>= MONO_TYPEDEFORREF_BITS;
1306 table = &assembly->tables [MONO_TABLE_MEMBERREF];
1308 name = mono_string_to_utf8_checked (fb->name, error);
1309 return_val_if_nok (error, 0);
1311 if (assembly->save) {
1312 alloc_table (table, table->rows + 1);
1313 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
1314 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
1315 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
1316 values [MONO_MEMBERREF_SIGNATURE] = sig;
1319 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
1321 mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
1327 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
1330 MonoDynamicTable *table;
1333 mono_error_init (error);
1335 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
1336 idx = table->next_idx ++;
1338 alloc_table (table, table->rows);
1339 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
1341 values [MONO_STAND_ALONE_SIGNATURE] =
1342 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
1343 return_val_if_nok (error, 0);
1349 reflection_cc_to_file (int call_conv) {
1350 switch (call_conv & 0x3) {
1352 case 1: return MONO_CALL_DEFAULT;
1353 case 2: return MONO_CALL_VARARG;
1355 g_assert_not_reached ();
1359 #endif /* !DISABLE_REFLECTION_EMIT */
1361 struct _ArrayMethod {
1363 MonoMethodSignature *sig;
1369 mono_sre_array_method_free (ArrayMethod *am)
1376 #ifndef DISABLE_REFLECTION_EMIT
1378 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
1383 MonoMethodSignature *sig;
1384 ArrayMethod *am = NULL;
1387 mono_error_init (error);
1389 nparams = mono_array_length (m->parameters);
1390 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
1392 sig->sentinelpos = -1;
1393 sig->call_convention = reflection_cc_to_file (m->call_conv);
1394 sig->param_count = nparams;
1396 sig->ret = mono_reflection_type_get_handle (m->ret, error);
1400 sig->ret = &mono_defaults.void_class->byval_arg;
1402 mtype = mono_reflection_type_get_handle (m->parent, error);
1406 for (i = 0; i < nparams; ++i) {
1407 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
1412 name = mono_string_to_utf8_checked (m->name, error);
1415 for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
1416 am = (ArrayMethod *)tmp->data;
1417 if (strcmp (name, am->name) == 0 &&
1418 mono_metadata_type_equal (am->parent, mtype) &&
1419 mono_metadata_signature_equal (am->sig, sig)) {
1422 m->table_idx = am->token & 0xffffff;
1426 am = g_new0 (ArrayMethod, 1);
1430 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
1431 mono_dynimage_encode_method_signature (assembly, sig));
1432 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
1433 m->table_idx = am->token & 0xffffff;
1444 #ifndef DISABLE_REFLECTION_EMIT
1447 * mono_image_insert_string:
1448 * @module: module builder object
1451 * Insert @str into the user string stream of @module.
1454 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
1456 MonoDynamicImage *assembly;
1461 if (!module->dynamic_image)
1462 mono_image_module_basic_init (module);
1464 assembly = module->dynamic_image;
1466 if (assembly->save) {
1467 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
1468 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1469 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1471 char *swapped = g_malloc (2 * mono_string_length (str));
1472 const char *p = (const char*)mono_string_chars (str);
1474 swap_with_size (swapped, p, 2, mono_string_length (str));
1475 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
1479 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
1481 mono_image_add_stream_data (&assembly->us, "", 1);
1483 idx = assembly->us.index ++;
1486 mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
1488 return MONO_TOKEN_STRING | idx;
1492 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
1496 MonoMethodSignature *sig;
1498 mono_error_init (error);
1500 klass = obj->vtable->klass;
1501 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1502 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1503 MonoMethodSignature *old;
1504 guint32 sig_token, parent;
1507 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1509 nargs = mono_array_length (opt_param_types);
1510 old = mono_method_signature (method);
1511 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1513 sig->hasthis = old->hasthis;
1514 sig->explicit_this = old->explicit_this;
1515 sig->call_convention = old->call_convention;
1516 sig->generic_param_count = old->generic_param_count;
1517 sig->param_count = old->param_count + nargs;
1518 sig->sentinelpos = old->param_count;
1519 sig->ret = old->ret;
1521 for (i = 0; i < old->param_count; i++)
1522 sig->params [i] = old->params [i];
1524 for (i = 0; i < nargs; i++) {
1525 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1526 sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1527 if (!is_ok (error)) goto fail;
1530 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1531 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1532 parent >>= MONO_TYPEDEFORREF_BITS;
1534 parent <<= MONO_MEMBERREF_PARENT_BITS;
1535 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1537 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1538 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1539 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1540 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1541 ReflectionMethodBuilder rmb;
1542 guint32 parent, sig_token;
1543 int nopt_args, nparams, ngparams, i;
1545 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1548 rmb.opt_types = opt_param_types;
1549 nopt_args = mono_array_length (opt_param_types);
1551 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1552 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1553 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1555 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1556 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1557 sig->call_convention = rmb.call_conv;
1558 sig->generic_param_count = ngparams;
1559 sig->param_count = nparams + nopt_args;
1560 sig->sentinelpos = nparams;
1561 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1562 if (!is_ok (error)) goto fail;
1564 for (i = 0; i < nparams; i++) {
1565 MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1566 sig->params [i] = mono_reflection_type_get_handle (rt, error);
1567 if (!is_ok (error)) goto fail;
1570 for (i = 0; i < nopt_args; i++) {
1571 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1572 sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1573 if (!is_ok (error)) goto fail;
1576 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1580 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1581 if (!mono_error_ok (error))
1583 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1585 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1586 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1588 char *name = mono_string_to_utf8_checked (rmb.name, error);
1589 if (!is_ok (error)) goto fail;
1590 token = mono_image_get_varargs_method_token (
1591 assembly, parent, name, sig_token);
1594 g_error ("requested method token for %s\n", klass->name);
1597 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1598 mono_dynamic_image_register_token (assembly, token, obj);
1601 g_assert (!mono_error_ok (error));
1606 * mono_image_create_token:
1607 * @assembly: a dynamic assembly
1609 * @register_token: Whenever to register the token in the assembly->tokens hash.
1611 * Get a token to insert in the IL code stream for the given MemberInfo.
1612 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1613 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1617 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
1618 gboolean create_open_instance, gboolean register_token,
1624 mono_error_init (error);
1626 klass = obj->vtable->klass;
1628 /* Check for user defined reflection objects */
1629 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1630 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1631 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1635 if (strcmp (klass->name, "MethodBuilder") == 0) {
1636 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1637 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1639 if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
1640 token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1642 token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
1643 if (!mono_error_ok (error))
1646 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1647 } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
1648 MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
1649 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1651 if (tb->module->dynamic_image == assembly && !tb->generic_params)
1652 token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1654 token = mono_image_get_ctorbuilder_token (assembly, mb, error);
1655 if (!mono_error_ok (error))
1658 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1659 } else if (strcmp (klass->name, "FieldBuilder") == 0) {
1660 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
1661 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
1662 if (tb->generic_params) {
1663 token = mono_image_get_generic_field_token (assembly, fb, error);
1664 return_val_if_nok (error, 0);
1666 if (tb->module->dynamic_image == assembly) {
1667 token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
1669 token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
1672 } else if (strcmp (klass->name, "TypeBuilder") == 0) {
1673 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
1674 if (create_open_instance && tb->generic_params) {
1676 mono_reflection_init_type_builder_generics (obj, error);
1677 return_val_if_nok (error, 0);
1678 type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1679 return_val_if_nok (error, 0);
1680 token = mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
1681 token = mono_metadata_token_from_dor (token);
1682 } else if (tb->module->dynamic_image == assembly) {
1683 token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
1686 type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1687 return_val_if_nok (error, 0);
1688 token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
1690 } else if (strcmp (klass->name, "RuntimeType") == 0) {
1691 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1692 return_val_if_nok (error, 0);
1693 MonoClass *mc = mono_class_from_mono_type (type);
1694 token = mono_metadata_token_from_dor (
1695 mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
1696 } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
1697 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1698 return_val_if_nok (error, 0);
1699 token = mono_metadata_token_from_dor (
1700 mono_image_typedef_or_ref (assembly, type));
1701 } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
1702 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1703 return_val_if_nok (error, 0);
1704 token = mono_metadata_token_from_dor (
1705 mono_image_typedef_or_ref (assembly, type));
1706 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1707 strcmp (klass->name, "MonoMethod") == 0 ||
1708 strcmp (klass->name, "MonoGenericMethod") == 0 ||
1709 strcmp (klass->name, "MonoGenericCMethod") == 0) {
1710 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1711 if (m->method->is_inflated) {
1712 if (create_open_instance)
1713 token = mono_image_get_methodspec_token (assembly, m->method);
1715 token = mono_image_get_inflated_method_token (assembly, m->method);
1716 } else if ((m->method->klass->image == &assembly->image) &&
1717 !m->method->klass->generic_class) {
1718 static guint32 method_table_idx = 0xffffff;
1719 if (m->method->klass->wastypebuilder) {
1720 /* we use the same token as the one that was assigned
1721 * to the Methodbuilder.
1722 * FIXME: do the equivalent for Fields.
1724 token = m->method->token;
1727 * Each token should have a unique index, but the indexes are
1728 * assigned by managed code, so we don't know about them. An
1729 * easy solution is to count backwards...
1731 method_table_idx --;
1732 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1735 token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1737 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1738 } else if (strcmp (klass->name, "MonoField") == 0) {
1739 MonoReflectionField *f = (MonoReflectionField *)obj;
1740 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1741 static guint32 field_table_idx = 0xffffff;
1743 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1745 token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1747 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1748 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1749 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1750 token = mono_image_get_array_token (assembly, m, error);
1751 return_val_if_nok (error, 0);
1752 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1753 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1754 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1755 return_val_if_nok (error, 0);
1756 } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1757 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1758 return_val_if_nok (error, 0);
1759 token = mono_metadata_token_from_dor (
1760 mono_image_typedef_or_ref (assembly, type));
1761 } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
1762 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
1763 token = mono_image_get_field_on_inst_token (assembly, f, error);
1764 return_val_if_nok (error, 0);
1765 } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
1766 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
1767 token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
1768 if (!mono_error_ok (error))
1770 } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
1771 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
1772 token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
1773 if (!mono_error_ok (error))
1775 } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
1776 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1777 return_val_if_nok (error, 0);
1778 token = mono_metadata_token_from_dor (
1779 mono_image_typedef_or_ref (assembly, type));
1781 g_error ("requested token for %s\n", klass->name);
1785 mono_image_register_token (assembly, token, obj);
1793 #ifndef DISABLE_REFLECTION_EMIT
1796 * mono_reflection_dynimage_basic_init:
1797 * @assembly: an assembly builder object
1799 * Create the MonoImage that represents the assembly builder and setup some
1800 * of the helper hash table and the basic metadata streams.
1803 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1806 MonoDynamicAssembly *assembly;
1807 MonoDynamicImage *image;
1808 MonoDomain *domain = mono_object_domain (assemblyb);
1810 if (assemblyb->dynamic_assembly)
1814 /* assembly->assembly.image might be GC allocated */
1815 assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1817 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1820 mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1822 assembly->assembly.ref_count = 1;
1823 assembly->assembly.dynamic = TRUE;
1824 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1825 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1826 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1827 if (mono_error_set_pending_exception (&error))
1829 if (assemblyb->culture) {
1830 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1831 if (mono_error_set_pending_exception (&error))
1834 assembly->assembly.aname.culture = g_strdup ("");
1836 if (assemblyb->version) {
1837 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1838 if (mono_error_set_pending_exception (&error))
1840 char **version = g_strsplit (vstr, ".", 4);
1841 char **parts = version;
1842 assembly->assembly.aname.major = atoi (*parts++);
1843 assembly->assembly.aname.minor = atoi (*parts++);
1844 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1845 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1847 g_strfreev (version);
1850 assembly->assembly.aname.major = 0;
1851 assembly->assembly.aname.minor = 0;
1852 assembly->assembly.aname.build = 0;
1853 assembly->assembly.aname.revision = 0;
1856 assembly->run = assemblyb->access != 2;
1857 assembly->save = assemblyb->access != 1;
1858 assembly->domain = domain;
1860 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1861 if (mono_error_set_pending_exception (&error))
1863 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1864 image->initial_image = TRUE;
1865 assembly->assembly.aname.name = image->image.name;
1866 assembly->assembly.image = &image->image;
1867 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1868 /* -1 to correct for the trailing NULL byte */
1869 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1870 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1872 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1875 mono_domain_assemblies_lock (domain);
1876 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1877 mono_domain_assemblies_unlock (domain);
1879 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1881 mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1883 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1886 #endif /* !DISABLE_REFLECTION_EMIT */
1888 #ifndef DISABLE_REFLECTION_EMIT
1890 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1892 CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
1896 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
1898 CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
1902 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
1904 MonoDynamicImage *image = moduleb->dynamic_image;
1905 MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
1906 mono_error_init (error);
1909 MonoImage **new_modules;
1911 char *name, *fqname;
1913 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1914 * we don't know which module it belongs to, since that is only
1915 * determined at assembly save time.
1917 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1918 name = mono_string_to_utf8_checked (ab->name, error);
1919 return_val_if_nok (error, FALSE);
1920 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
1921 if (!is_ok (error)) {
1925 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
1927 moduleb->module.image = &image->image;
1928 moduleb->dynamic_image = image;
1929 register_module (mono_object_domain (moduleb), moduleb, image);
1931 /* register the module with the assembly */
1932 ass = ab->dynamic_assembly->assembly.image;
1933 module_count = ass->module_count;
1934 new_modules = g_new0 (MonoImage *, module_count + 1);
1937 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1938 new_modules [module_count] = &image->image;
1939 mono_image_addref (&image->image);
1941 g_free (ass->modules);
1942 ass->modules = new_modules;
1943 ass->module_count ++;
1949 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
1952 (void) image_module_basic_init (moduleb, &error);
1953 mono_error_set_pending_exception (&error);
1959 is_corlib_type (MonoClass *klass)
1961 return klass->image == mono_defaults.corlib;
1964 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1965 static MonoClass *cached_class; \
1967 return cached_class == _class; \
1968 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1969 cached_class = _class; \
1977 #ifndef DISABLE_REFLECTION_EMIT
1979 is_sre_array (MonoClass *klass)
1981 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1985 is_sre_byref (MonoClass *klass)
1987 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1991 is_sre_pointer (MonoClass *klass)
1993 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1997 is_sre_generic_instance (MonoClass *klass)
1999 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
2003 is_sre_type_builder (MonoClass *klass)
2005 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
2009 is_sre_method_builder (MonoClass *klass)
2011 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
2015 mono_is_sre_ctor_builder (MonoClass *klass)
2017 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
2021 is_sre_field_builder (MonoClass *klass)
2023 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
2027 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2029 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
2033 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2035 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
2038 static MonoReflectionType*
2039 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
2041 static MonoMethod *method_get_underlying_system_type = NULL;
2042 MonoReflectionType *rt;
2043 MonoMethod *usertype_method;
2045 mono_error_init (error);
2047 if (!method_get_underlying_system_type)
2048 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
2050 usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
2052 rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
2058 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
2061 mono_error_init (error);
2068 if (mono_reflection_is_usertype (ref)) {
2069 ref = mono_reflection_type_get_underlying_system_type (ref, error);
2070 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
2076 klass = mono_object_class (ref);
2078 if (is_sre_array (klass)) {
2080 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
2081 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
2082 return_val_if_nok (error, NULL);
2084 if (sre_array->rank == 0) //single dimentional array
2085 res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
2087 res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
2088 sre_array->type.type = res;
2090 } else if (is_sre_byref (klass)) {
2092 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
2093 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
2094 return_val_if_nok (error, NULL);
2096 res = &mono_class_from_mono_type (base)->this_arg;
2097 sre_byref->type.type = res;
2099 } else if (is_sre_pointer (klass)) {
2101 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
2102 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
2103 return_val_if_nok (error, NULL);
2105 res = &mono_ptr_class_get (base)->byval_arg;
2106 sre_pointer->type.type = res;
2108 } else if (is_sre_generic_instance (klass)) {
2109 MonoType *res, **types;
2110 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
2113 count = mono_array_length (gclass->type_arguments);
2114 types = g_new0 (MonoType*, count);
2115 for (i = 0; i < count; ++i) {
2116 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
2117 types [i] = mono_reflection_type_get_handle (t, error);
2118 if (!types[i] || !is_ok (error)) {
2124 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
2127 gclass->type.type = res;
2131 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
2136 ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
2139 mono_reflection_type_get_handle (type, &error);
2140 mono_error_set_pending_exception (&error);
2144 reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
2146 MonoDomain *domain = mono_object_domain ((MonoObject*)type);
2149 mono_error_init (error);
2151 MonoType *res = mono_reflection_type_get_handle (type, error);
2153 if (!res && is_ok (error)) {
2154 mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
2156 return_val_if_nok (error, FALSE);
2158 klass = mono_class_from_mono_type (res);
2160 mono_loader_lock (); /*same locking as mono_type_get_object_checked */
2161 mono_domain_lock (domain);
2163 if (!image_is_dynamic (klass->image)) {
2164 mono_class_setup_supertypes (klass);
2166 if (!domain->type_hash)
2167 domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash,
2168 (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
2169 mono_g_hash_table_insert (domain->type_hash, res, type);
2171 mono_domain_unlock (domain);
2172 mono_loader_unlock ();
2178 mono_reflection_register_with_runtime (MonoReflectionType *type)
2181 (void) reflection_register_with_runtime (type, &error);
2182 mono_error_set_pending_exception (&error);
2186 * LOCKING: Assumes the loader lock is held.
2188 static MonoMethodSignature*
2189 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
2190 MonoMethodSignature *sig;
2193 mono_error_init (error);
2195 count = parameters? mono_array_length (parameters): 0;
2197 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
2198 sig->param_count = count;
2199 sig->sentinelpos = -1; /* FIXME */
2200 for (i = 0; i < count; ++i) {
2201 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
2202 if (!is_ok (error)) {
2203 image_g_free (image, sig);
2211 * LOCKING: Assumes the loader lock is held.
2213 static MonoMethodSignature*
2214 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
2215 MonoMethodSignature *sig;
2217 mono_error_init (error);
2219 sig = parameters_to_signature (image, ctor->parameters, error);
2220 return_val_if_nok (error, NULL);
2221 sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2222 sig->ret = &mono_defaults.void_class->byval_arg;
2227 * LOCKING: Assumes the loader lock is held.
2229 static MonoMethodSignature*
2230 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
2231 MonoMethodSignature *sig;
2233 mono_error_init (error);
2235 sig = parameters_to_signature (image, method->parameters, error);
2236 return_val_if_nok (error, NULL);
2237 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2238 if (method->rtype) {
2239 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
2240 if (!is_ok (error)) {
2241 image_g_free (image, sig);
2245 sig->ret = &mono_defaults.void_class->byval_arg;
2247 sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
2251 static MonoMethodSignature*
2252 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
2253 MonoMethodSignature *sig;
2255 mono_error_init (error);
2257 sig = parameters_to_signature (NULL, method->parameters, error);
2258 return_val_if_nok (error, NULL);
2259 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2260 if (method->rtype) {
2261 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
2262 if (!is_ok (error)) {
2267 sig->ret = &mono_defaults.void_class->byval_arg;
2269 sig->generic_param_count = 0;
2274 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
2276 mono_error_init (error);
2277 MonoClass *klass = mono_object_class (prop);
2278 if (strcmp (klass->name, "PropertyBuilder") == 0) {
2279 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
2280 *name = mono_string_to_utf8_checked (pb->name, error);
2281 return_if_nok (error);
2282 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
2284 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
2285 *name = g_strdup (p->property->name);
2286 if (p->property->get)
2287 *type = mono_method_signature (p->property->get)->ret;
2289 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
2294 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
2296 mono_error_init (error);
2297 MonoClass *klass = mono_object_class (field);
2298 if (strcmp (klass->name, "FieldBuilder") == 0) {
2299 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
2300 *name = mono_string_to_utf8_checked (fb->name, error);
2301 return_if_nok (error);
2302 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
2304 MonoReflectionField *f = (MonoReflectionField *)field;
2305 *name = g_strdup (mono_field_get_name (f->field));
2306 *type = f->field->type;
2310 #else /* DISABLE_REFLECTION_EMIT */
2313 mono_reflection_register_with_runtime (MonoReflectionType *type)
2319 is_sre_type_builder (MonoClass *klass)
2325 is_sre_generic_instance (MonoClass *klass)
2331 mono_is_sre_ctor_builder (MonoClass *klass)
2337 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2343 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2349 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
2351 mono_error_init (error);
2354 #endif /* !DISABLE_REFLECTION_EMIT */
2358 is_sr_mono_field (MonoClass *klass)
2360 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
2364 mono_is_sr_mono_property (MonoClass *klass)
2366 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
2370 is_sr_mono_method (MonoClass *klass)
2372 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
2376 mono_is_sr_mono_cmethod (MonoClass *klass)
2378 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
2382 is_sr_mono_generic_method (MonoClass *klass)
2384 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
2388 is_sr_mono_generic_cmethod (MonoClass *klass)
2390 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
2394 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
2396 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
2400 mono_is_sre_type_builder (MonoClass *klass)
2402 return is_sre_type_builder (klass);
2406 mono_is_sre_generic_instance (MonoClass *klass)
2408 return is_sre_generic_instance (klass);
2414 * encode_cattr_value:
2415 * Encode a value in a custom attribute stream of bytes.
2416 * The value to encode is either supplied as an object in argument val
2417 * (valuetypes are boxed), or as a pointer to the data in the
2419 * @type represents the type of the value
2420 * @buffer is the start of the buffer
2421 * @p the current position in the buffer
2422 * @buflen contains the size of the buffer and is used to return the new buffer size
2423 * if this needs to be realloced.
2424 * @retbuffer and @retp return the start and the position of the buffer
2425 * @error set on error.
2428 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2430 MonoTypeEnum simple_type;
2432 mono_error_init (error);
2433 if ((p-buffer) + 10 >= *buflen) {
2436 newbuf = (char *)g_realloc (buffer, *buflen);
2437 p = newbuf + (p-buffer);
2441 argval = ((char*)arg + sizeof (MonoObject));
2442 simple_type = type->type;
2444 switch (simple_type) {
2445 case MONO_TYPE_BOOLEAN:
2450 case MONO_TYPE_CHAR:
2453 swap_with_size (p, argval, 2, 1);
2459 swap_with_size (p, argval, 4, 1);
2463 swap_with_size (p, argval, 8, 1);
2468 swap_with_size (p, argval, 8, 1);
2471 case MONO_TYPE_VALUETYPE:
2472 if (type->data.klass->enumtype) {
2473 simple_type = mono_class_enum_basetype (type->data.klass)->type;
2476 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2479 case MONO_TYPE_STRING: {
2486 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2487 return_if_nok (error);
2488 slen = strlen (str);
2489 if ((p-buffer) + 10 + slen >= *buflen) {
2493 newbuf = (char *)g_realloc (buffer, *buflen);
2494 p = newbuf + (p-buffer);
2497 mono_metadata_encode_value (slen, p, &p);
2498 memcpy (p, str, slen);
2503 case MONO_TYPE_CLASS: {
2512 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2513 return_if_nok (error);
2515 str = type_get_qualified_name (arg_type, NULL);
2516 slen = strlen (str);
2517 if ((p-buffer) + 10 + slen >= *buflen) {
2521 newbuf = (char *)g_realloc (buffer, *buflen);
2522 p = newbuf + (p-buffer);
2525 mono_metadata_encode_value (slen, p, &p);
2526 memcpy (p, str, slen);
2531 case MONO_TYPE_SZARRAY: {
2533 MonoClass *eclass, *arg_eclass;
2536 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2539 len = mono_array_length ((MonoArray*)arg);
2541 *p++ = (len >> 8) & 0xff;
2542 *p++ = (len >> 16) & 0xff;
2543 *p++ = (len >> 24) & 0xff;
2545 *retbuffer = buffer;
2546 eclass = type->data.klass;
2547 arg_eclass = mono_object_class (arg)->element_class;
2550 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2551 eclass = mono_defaults.object_class;
2553 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2554 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2555 int elsize = mono_class_array_element_size (arg_eclass);
2556 for (i = 0; i < len; ++i) {
2557 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2558 return_if_nok (error);
2561 } else if (eclass->valuetype && arg_eclass->valuetype) {
2562 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2563 int elsize = mono_class_array_element_size (eclass);
2564 for (i = 0; i < len; ++i) {
2565 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2566 return_if_nok (error);
2570 for (i = 0; i < len; ++i) {
2571 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2572 return_if_nok (error);
2577 case MONO_TYPE_OBJECT: {
2583 * The parameter type is 'object' but the type of the actual
2584 * argument is not. So we have to add type information to the blob
2585 * too. This is completely undocumented in the spec.
2589 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2594 klass = mono_object_class (arg);
2596 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2600 return_if_nok (error);
2603 if (klass->enumtype) {
2605 } else if (klass == mono_defaults.string_class) {
2606 simple_type = MONO_TYPE_STRING;
2609 } else if (klass->rank == 1) {
2611 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2612 /* See Partition II, Appendix B3 */
2615 *p++ = klass->element_class->byval_arg.type;
2616 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2617 return_if_nok (error);
2619 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2620 *p++ = simple_type = klass->byval_arg.type;
2623 g_error ("unhandled type in custom attr");
2625 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2626 slen = strlen (str);
2627 if ((p-buffer) + 10 + slen >= *buflen) {
2631 newbuf = (char *)g_realloc (buffer, *buflen);
2632 p = newbuf + (p-buffer);
2635 mono_metadata_encode_value (slen, p, &p);
2636 memcpy (p, str, slen);
2639 simple_type = mono_class_enum_basetype (klass)->type;
2643 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2646 *retbuffer = buffer;
2650 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2652 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2653 char *str = type_get_qualified_name (type, NULL);
2654 int slen = strlen (str);
2658 * This seems to be optional...
2661 mono_metadata_encode_value (slen, p, &p);
2662 memcpy (p, str, slen);
2665 } else if (type->type == MONO_TYPE_OBJECT) {
2667 } else if (type->type == MONO_TYPE_CLASS) {
2668 /* it should be a type: encode_cattr_value () has the check */
2671 mono_metadata_encode_value (type->type, p, &p);
2672 if (type->type == MONO_TYPE_SZARRAY)
2673 /* See the examples in Partition VI, Annex B */
2674 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2680 #ifndef DISABLE_REFLECTION_EMIT
2682 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2686 mono_error_init (error);
2688 /* Preallocate a large enough buffer */
2689 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2690 char *str = type_get_qualified_name (type, NULL);
2693 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2694 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2700 len += strlen (name);
2702 if ((p-buffer) + 20 + len >= *buflen) {
2706 newbuf = (char *)g_realloc (buffer, *buflen);
2707 p = newbuf + (p-buffer);
2711 encode_field_or_prop_type (type, p, &p);
2713 len = strlen (name);
2714 mono_metadata_encode_value (len, p, &p);
2715 memcpy (p, name, len);
2717 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2718 return_if_nok (error);
2720 *retbuffer = buffer;
2724 * mono_reflection_get_custom_attrs_blob:
2725 * @ctor: custom attribute constructor
2726 * @ctorArgs: arguments o the constructor
2732 * Creates the blob of data that needs to be saved in the metadata and that represents
2733 * the custom attributed described by @ctor, @ctorArgs etc.
2734 * Returns: a Byte array representing the blob of data.
2737 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2740 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2741 mono_error_cleanup (&error);
2746 * mono_reflection_get_custom_attrs_blob_checked:
2747 * @ctor: custom attribute constructor
2748 * @ctorArgs: arguments o the constructor
2753 * @error: set on error
2755 * Creates the blob of data that needs to be saved in the metadata and that represents
2756 * the custom attributed described by @ctor, @ctorArgs etc.
2757 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2760 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2762 MonoArray *result = NULL;
2763 MonoMethodSignature *sig;
2768 mono_error_init (error);
2770 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2771 /* sig is freed later so allocate it in the heap */
2772 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2773 if (!is_ok (error)) {
2778 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2781 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2783 p = buffer = (char *)g_malloc (buflen);
2784 /* write the prolog */
2787 for (i = 0; i < sig->param_count; ++i) {
2788 arg = mono_array_get (ctorArgs, MonoObject*, i);
2789 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2790 if (!is_ok (error)) goto leave;
2794 i += mono_array_length (properties);
2796 i += mono_array_length (fields);
2798 *p++ = (i >> 8) & 0xff;
2801 for (i = 0; i < mono_array_length (properties); ++i) {
2805 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2806 get_prop_name_and_type (prop, &pname, &ptype, error);
2807 if (!is_ok (error)) goto leave;
2808 *p++ = 0x54; /* PROPERTY signature */
2809 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2811 if (!is_ok (error)) goto leave;
2817 for (i = 0; i < mono_array_length (fields); ++i) {
2821 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2822 get_field_name_and_type (field, &fname, &ftype, error);
2823 if (!is_ok (error)) goto leave;
2824 *p++ = 0x53; /* FIELD signature */
2825 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2827 if (!is_ok (error)) goto leave;
2831 g_assert (p - buffer <= buflen);
2832 buflen = p - buffer;
2833 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2836 p = mono_array_addr (result, char, 0);
2837 memcpy (p, buffer, buflen);
2840 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2846 * reflection_setup_internal_class:
2847 * @tb: a TypeBuilder object
2848 * @error: set on error
2850 * Creates a MonoClass that represents the TypeBuilder.
2851 * This is a trick that lets us simplify a lot of reflection code
2852 * (and will allow us to support Build and Run assemblies easier).
2854 * Returns TRUE on success. On failure, returns FALSE and sets @error.
2857 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2859 MonoClass *klass, *parent;
2861 mono_error_init (error);
2863 mono_loader_lock ();
2866 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
2867 if (!is_ok (error)) {
2868 mono_loader_unlock ();
2871 /* check so we can compile corlib correctly */
2872 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
2873 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2874 parent = parent_type->data.klass;
2876 parent = mono_class_from_mono_type (parent_type);
2882 /* the type has already being created: it means we just have to change the parent */
2883 if (tb->type.type) {
2884 klass = mono_class_from_mono_type (tb->type.type);
2885 klass->parent = NULL;
2886 /* fool mono_class_setup_parent */
2887 klass->supertypes = NULL;
2888 mono_class_setup_parent (klass, parent);
2889 mono_class_setup_mono_type (klass);
2890 mono_loader_unlock ();
2894 klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
2896 klass->image = &tb->module->dynamic_image->image;
2898 klass->inited = 1; /* we lie to the runtime */
2899 klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
2902 klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
2905 klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
2906 klass->flags = tb->attrs;
2908 mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2910 klass->element_class = klass;
2912 if (mono_class_get_ref_info (klass) == NULL) {
2913 mono_class_set_ref_info (klass, tb);
2915 /* Put into cache so mono_class_get_checked () will find it.
2916 Skip nested types as those should not be available on the global scope. */
2917 if (!tb->nesting_type)
2918 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
2921 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2922 by performing a mono_class_get which does the full resolution.
2924 Working around this semantics would require us to write a lot of code for no clear advantage.
2926 mono_image_append_class_to_reflection_info_set (klass);
2928 g_assert (mono_class_get_ref_info (klass) == tb);
2931 mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
2933 if (parent != NULL) {
2934 mono_class_setup_parent (klass, parent);
2935 } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
2936 const char *old_n = klass->name;
2937 /* trick to get relative numbering right when compiling corlib */
2938 klass->name = "BuildingObject";
2939 mono_class_setup_parent (klass, mono_defaults.object_class);
2940 klass->name = old_n;
2943 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2944 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2945 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2946 klass->instance_size = sizeof (MonoObject);
2947 klass->size_inited = 1;
2948 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2951 mono_class_setup_mono_type (klass);
2953 mono_class_setup_supertypes (klass);
2956 * FIXME: handle interfaces.
2959 tb->type.type = &klass->byval_arg;
2961 if (tb->nesting_type) {
2962 g_assert (tb->nesting_type->type);
2963 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
2964 if (!is_ok (error)) goto failure;
2965 klass->nested_in = mono_class_from_mono_type (nesting_type);
2968 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2970 mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
2972 mono_loader_unlock ();
2976 mono_loader_unlock ();
2981 * ves_icall_TypeBuilder_setup_internal_class:
2982 * @tb: a TypeBuilder object
2985 * Creates a MonoClass that represents the TypeBuilder.
2986 * This is a trick that lets us simplify a lot of reflection code
2987 * (and will allow us to support Build and Run assemblies easier).
2991 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
2994 (void) reflection_setup_internal_class (tb, &error);
2995 mono_error_set_pending_exception (&error);
2999 * mono_reflection_create_generic_class:
3000 * @tb: a TypeBuilder object
3001 * @error: set on error
3003 * Creates the generic class after all generic parameters have been added.
3004 * On success returns TRUE, on failure returns FALSE and sets @error.
3008 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3014 mono_error_init (error);
3016 klass = mono_class_from_mono_type (tb->type.type);
3018 count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
3020 if (klass->generic_container || (count == 0))
3023 g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
3025 klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3027 klass->generic_container->owner.klass = klass;
3028 klass->generic_container->type_argc = count;
3029 klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
3031 klass->is_generic = 1;
3033 for (i = 0; i < count; i++) {
3034 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3035 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
3036 return_val_if_nok (error, FALSE);
3037 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
3038 klass->generic_container->type_params [i] = *param;
3039 /*Make sure we are a diferent type instance */
3040 klass->generic_container->type_params [i].param.owner = klass->generic_container;
3041 klass->generic_container->type_params [i].info.pklass = NULL;
3042 klass->generic_container->type_params [i].info.flags = gparam->attrs;
3044 g_assert (klass->generic_container->type_params [i].param.owner);
3047 klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
3051 static MonoMarshalSpec*
3052 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
3053 MonoReflectionMarshal *minfo, MonoError *error)
3055 MonoMarshalSpec *res;
3057 mono_error_init (error);
3059 res = image_g_new0 (image, MonoMarshalSpec, 1);
3060 res->native = (MonoMarshalNative)minfo->type;
3062 switch (minfo->type) {
3063 case MONO_NATIVE_LPARRAY:
3064 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
3065 if (minfo->has_size) {
3066 res->data.array_data.param_num = minfo->param_num;
3067 res->data.array_data.num_elem = minfo->count;
3068 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
3071 res->data.array_data.param_num = -1;
3072 res->data.array_data.num_elem = -1;
3073 res->data.array_data.elem_mult = -1;
3077 case MONO_NATIVE_BYVALTSTR:
3078 case MONO_NATIVE_BYVALARRAY:
3079 res->data.array_data.num_elem = minfo->count;
3082 case MONO_NATIVE_CUSTOM:
3083 if (minfo->marshaltyperef) {
3084 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
3085 if (!is_ok (error)) {
3086 image_g_free (image, res);
3089 res->data.custom_data.custom_name =
3090 type_get_fully_qualified_name (marshaltyperef);
3092 if (minfo->mcookie) {
3093 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
3094 if (!is_ok (error)) {
3095 image_g_free (image, res);
3107 #endif /* !DISABLE_REFLECTION_EMIT */
3109 MonoReflectionMarshalAsAttribute*
3110 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
3111 MonoMarshalSpec *spec, MonoError *error)
3113 MonoReflectionType *rt;
3114 MonoReflectionMarshalAsAttribute *minfo;
3117 mono_error_init (error);
3119 minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
3122 minfo->utype = spec->native;
3124 switch (minfo->utype) {
3125 case MONO_NATIVE_LPARRAY:
3126 minfo->array_subtype = spec->data.array_data.elem_type;
3127 minfo->size_const = spec->data.array_data.num_elem;
3128 if (spec->data.array_data.param_num != -1)
3129 minfo->size_param_index = spec->data.array_data.param_num;
3132 case MONO_NATIVE_BYVALTSTR:
3133 case MONO_NATIVE_BYVALARRAY:
3134 minfo->size_const = spec->data.array_data.num_elem;
3137 case MONO_NATIVE_CUSTOM:
3138 if (spec->data.custom_data.custom_name) {
3139 mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
3140 return_val_if_nok (error, NULL);
3143 rt = mono_type_get_object_checked (domain, mtype, error);
3147 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
3150 MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
3152 if (spec->data.custom_data.cookie)
3153 MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
3163 #ifndef DISABLE_REFLECTION_EMIT
3165 reflection_methodbuilder_to_mono_method (MonoClass *klass,
3166 ReflectionMethodBuilder *rmb,
3167 MonoMethodSignature *sig,
3171 MonoMethodWrapper *wrapperm;
3172 MonoMarshalSpec **specs;
3173 MonoReflectionMethodAux *method_aux;
3178 mono_error_init (error);
3180 * Methods created using a MethodBuilder should have their memory allocated
3181 * inside the image mempool, while dynamic methods should have their memory
3184 dynamic = rmb->refs != NULL;
3185 image = dynamic ? NULL : klass->image;
3188 g_assert (!klass->generic_class);
3190 mono_loader_lock ();
3192 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
3193 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
3194 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
3196 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
3198 wrapperm = (MonoMethodWrapper*)m;
3200 m->dynamic = dynamic;
3202 m->flags = rmb->attrs;
3203 m->iflags = rmb->iattrs;
3204 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
3207 m->sre_method = TRUE;
3208 m->skip_visibility = rmb->skip_visibility;
3210 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
3212 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
3213 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
3216 m->signature->pinvoke = 1;
3217 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3218 m->signature->pinvoke = 1;
3220 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3222 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
3223 mono_error_assert_ok (error);
3224 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
3225 mono_error_assert_ok (error);
3227 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
3229 if (image_is_dynamic (klass->image))
3230 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3232 mono_loader_unlock ();
3235 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
3236 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
3237 MonoMethodHeader *header;
3239 gint32 max_stack, i;
3240 gint32 num_locals = 0;
3241 gint32 num_clauses = 0;
3245 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
3246 code_size = rmb->ilgen->code_len;
3247 max_stack = rmb->ilgen->max_stack;
3248 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
3249 if (rmb->ilgen->ex_handlers)
3250 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
3253 code = mono_array_addr (rmb->code, guint8, 0);
3254 code_size = mono_array_length (rmb->code);
3255 /* we probably need to run a verifier on the code... */
3265 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
3266 header->code_size = code_size;
3267 header->code = (const unsigned char *)image_g_malloc (image, code_size);
3268 memcpy ((char*)header->code, code, code_size);
3269 header->max_stack = max_stack;
3270 header->init_locals = rmb->init_locals;
3271 header->num_locals = num_locals;
3273 for (i = 0; i < num_locals; ++i) {
3274 MonoReflectionLocalBuilder *lb =
3275 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
3277 header->locals [i] = image_g_new0 (image, MonoType, 1);
3278 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
3279 mono_error_assert_ok (error);
3280 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
3283 header->num_clauses = num_clauses;
3285 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
3286 rmb->ilgen, num_clauses, error);
3287 mono_error_assert_ok (error);
3290 wrapperm->header = header;
3293 if (rmb->generic_params) {
3294 int count = mono_array_length (rmb->generic_params);
3295 MonoGenericContainer *container = rmb->generic_container;
3297 g_assert (container);
3299 container->type_argc = count;
3300 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
3301 container->owner.method = m;
3302 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
3304 m->is_generic = TRUE;
3305 mono_method_set_generic_container (m, container);
3307 for (i = 0; i < count; i++) {
3308 MonoReflectionGenericParam *gp =
3309 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
3310 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
3311 mono_error_assert_ok (error);
3312 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
3313 container->type_params [i] = *param;
3317 * The method signature might have pointers to generic parameters that belong to other methods.
3318 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3319 * generic parameters.
3321 for (i = 0; i < m->signature->param_count; ++i) {
3322 MonoType *t = m->signature->params [i];
3323 if (t->type == MONO_TYPE_MVAR) {
3324 MonoGenericParam *gparam = t->data.generic_param;
3325 if (gparam->num < count) {
3326 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
3327 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
3333 if (klass->generic_container) {
3334 container->parent = klass->generic_container;
3335 container->context.class_inst = klass->generic_container->context.class_inst;
3337 container->context.method_inst = mono_get_shared_generic_inst (container);
3341 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
3345 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
3347 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
3348 data [0] = GUINT_TO_POINTER (rmb->nrefs);
3349 for (i = 0; i < rmb->nrefs; ++i)
3350 data [i + 1] = rmb->refs [i];
3355 /* Parameter info */
3358 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3359 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
3360 for (i = 0; i <= m->signature->param_count; ++i) {
3361 MonoReflectionParamBuilder *pb;
3362 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3363 if ((i > 0) && (pb->attrs)) {
3364 /* Make a copy since it might point to a shared type structure */
3365 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
3366 m->signature->params [i - 1]->attrs = pb->attrs;
3369 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3370 MonoDynamicImage *assembly;
3372 MonoTypeEnum def_type;
3376 if (!method_aux->param_defaults) {
3377 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3378 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3380 assembly = (MonoDynamicImage*)klass->image;
3381 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3382 /* Copy the data from the blob since it might get realloc-ed */
3383 p = assembly->blob.data + idx;
3384 len = mono_metadata_decode_blob_size (p, &p2);
3386 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3387 method_aux->param_default_types [i] = def_type;
3388 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3392 method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
3393 mono_error_assert_ok (error);
3396 if (!method_aux->param_cattr)
3397 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3398 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3404 /* Parameter marshalling */
3407 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3408 MonoReflectionParamBuilder *pb;
3409 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3410 if (pb->marshal_info) {
3412 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3413 specs [pb->position] =
3414 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3415 if (!is_ok (error)) {
3416 mono_loader_unlock ();
3417 image_g_free (image, specs);
3418 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3424 if (specs != NULL) {
3426 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3427 method_aux->param_marshall = specs;
3430 if (image_is_dynamic (klass->image) && method_aux)
3431 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3433 mono_loader_unlock ();
3439 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3441 ReflectionMethodBuilder rmb;
3442 MonoMethodSignature *sig;
3444 mono_loader_lock ();
3445 g_assert (klass->image != NULL);
3446 sig = ctor_builder_to_signature (klass->image, mb, error);
3447 mono_loader_unlock ();
3448 return_val_if_nok (error, NULL);
3450 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3453 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3454 return_val_if_nok (error, NULL);
3455 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3457 /* If we are in a generic class, we might be called multiple times from inflate_method */
3458 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3459 /* ilgen is no longer needed */
3467 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
3469 ReflectionMethodBuilder rmb;
3470 MonoMethodSignature *sig;
3472 mono_error_init (error);
3474 mono_loader_lock ();
3475 g_assert (klass->image != NULL);
3476 sig = method_builder_to_signature (klass->image, mb, error);
3477 mono_loader_unlock ();
3478 return_val_if_nok (error, NULL);
3480 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3483 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3484 return_val_if_nok (error, NULL);
3485 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3487 /* If we are in a generic class, we might be called multiple times from inflate_method */
3488 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3489 /* ilgen is no longer needed */
3496 #ifndef DISABLE_REFLECTION_EMIT
3499 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
3501 MonoMethodInflated *imethod;
3502 MonoGenericContext *context;
3506 * With generic code sharing the klass might not be inflated.
3507 * This can happen because classes inflated with their own
3508 * type arguments are "normalized" to the uninflated class.
3510 if (!klass->generic_class)
3513 context = mono_class_get_context (klass);
3515 if (klass->method.count && klass->methods) {
3516 /* Find the already created inflated method */
3517 for (i = 0; i < klass->method.count; ++i) {
3518 g_assert (klass->methods [i]->is_inflated);
3519 if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
3522 g_assert (i < klass->method.count);
3523 imethod = (MonoMethodInflated*)klass->methods [i];
3526 imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
3527 mono_error_assert_ok (&error);
3530 if (method->is_generic && image_is_dynamic (method->klass->image)) {
3531 MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
3533 mono_image_lock ((MonoImage*)image);
3534 mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
3535 mono_image_unlock ((MonoImage*)image);
3537 return (MonoMethod *) imethod;
3541 inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
3546 mono_error_init (error);
3548 MonoClass *type_class = mono_object_class (type);
3550 if (is_sre_generic_instance (type_class)) {
3551 MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
3552 MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
3553 return_val_if_nok (error, NULL);
3554 gklass = mono_class_from_mono_type (generic_type);
3555 } else if (is_sre_type_builder (type_class)) {
3556 MonoType *t = mono_reflection_type_get_handle (type, error);
3557 return_val_if_nok (error, NULL);
3558 gklass = mono_class_from_mono_type (t);
3559 } else if (type->type) {
3560 gklass = mono_class_from_mono_type (type->type);
3561 gklass = mono_class_get_generic_type_definition (gklass);
3563 g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
3566 if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
3567 if (((MonoReflectionMethodBuilder*)obj)->mhandle)
3568 method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
3570 method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
3574 else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
3575 method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
3578 } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
3579 method = ((MonoReflectionMethod *) obj)->method;
3581 method = NULL; /* prevent compiler warning */
3582 g_error ("can't handle type %s", obj->vtable->klass->name);
3585 MonoType *t = mono_reflection_type_get_handle (type, error);
3586 return_val_if_nok (error, NULL);
3587 return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
3591 reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoError *error)
3593 MonoGenericClass *gclass;
3594 MonoClass *klass, *gklass;
3597 mono_error_init (error);
3599 gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
3600 return_if_nok (error);
3601 klass = mono_class_from_mono_type (gtype);
3602 g_assert (gtype->type == MONO_TYPE_GENERICINST);
3603 gclass = gtype->data.generic_class;
3605 if (!gclass->is_dynamic)
3608 gklass = gclass->container_class;
3609 mono_class_init (gklass);
3611 /* Mark this as needing synchronization with its generic container */
3612 gclass->need_sync = TRUE;
3616 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
3619 reflection_generic_class_initialize (type, &error);
3620 mono_error_set_pending_exception (&error);
3624 * fix_partial_generic_class:
3625 * @klass: a generic instantiation MonoClass
3626 * @error: set on error
3628 * Assumes that the generic container of @klass has its vtable
3629 * initialized, and updates the parent class, interfaces, methods and
3630 * fields of @klass by inflating the types using the generic context.
3632 * On success returns TRUE, on failure returns FALSE and sets @error.
3636 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3638 MonoClass *gklass = klass->generic_class->container_class;
3641 mono_error_init (error);
3643 if (klass->wastypebuilder)
3646 if (klass->parent != gklass->parent) {
3647 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
3648 if (mono_error_ok (error)) {
3649 MonoClass *parent = mono_class_from_mono_type (parent_type);
3650 mono_metadata_free_type (parent_type);
3651 if (parent != klass->parent) {
3652 /*fool mono_class_setup_parent*/
3653 klass->supertypes = NULL;
3654 mono_class_setup_parent (klass, parent);
3657 if (gklass->wastypebuilder)
3658 klass->wastypebuilder = TRUE;
3663 if (!klass->generic_class->need_sync)
3666 if (klass->method.count != gklass->method.count) {
3667 klass->method.count = gklass->method.count;
3668 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
3670 for (i = 0; i < klass->method.count; i++) {
3671 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3672 gklass->methods [i], klass, mono_class_get_context (klass), error);
3673 mono_error_assert_ok (error);
3677 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3678 klass->interface_count = gklass->interface_count;
3679 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3680 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3682 for (i = 0; i < gklass->interface_count; ++i) {
3683 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3684 return_val_if_nok (error, FALSE);
3686 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3687 mono_metadata_free_type (iface_type);
3689 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3692 klass->interfaces_inited = 1;
3695 if (klass->field.count != gklass->field.count) {
3696 klass->field.count = gklass->field.count;
3697 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
3699 for (i = 0; i < klass->field.count; i++) {
3700 klass->fields [i] = gklass->fields [i];
3701 klass->fields [i].parent = klass;
3702 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3703 return_val_if_nok (error, FALSE);
3707 /*We can only finish with this klass once it's parent has as well*/
3708 if (gklass->wastypebuilder)
3709 klass->wastypebuilder = TRUE;
3714 * ensure_generic_class_runtime_vtable:
3715 * @klass a generic class
3716 * @error set on error
3718 * Ensures that the generic container of @klass has a vtable and
3719 * returns TRUE on success. On error returns FALSE and sets @error.
3722 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3724 MonoClass *gklass = klass->generic_class->container_class;
3726 mono_error_init (error);
3728 if (!ensure_runtime_vtable (gklass, error))
3731 return fix_partial_generic_class (klass, error);
3735 * ensure_runtime_vtable:
3737 * @error set on error
3739 * Ensures that @klass has a vtable and returns TRUE on success. On
3740 * error returns FALSE and sets @error.
3743 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3745 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3748 mono_error_init (error);
3750 if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
3753 if (!ensure_runtime_vtable (klass->parent, error))
3757 num = tb->ctors? mono_array_length (tb->ctors): 0;
3758 num += tb->num_methods;
3759 klass->method.count = num;
3760 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3761 num = tb->ctors? mono_array_length (tb->ctors): 0;
3762 for (i = 0; i < num; ++i) {
3763 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3766 klass->methods [i] = ctor;
3768 num = tb->num_methods;
3770 for (i = 0; i < num; ++i) {
3771 MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3774 klass->methods [j++] = meth;
3777 if (tb->interfaces) {
3778 klass->interface_count = mono_array_length (tb->interfaces);
3779 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3780 for (i = 0; i < klass->interface_count; ++i) {
3781 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3782 return_val_if_nok (error, FALSE);
3783 klass->interfaces [i] = mono_class_from_mono_type (iface);
3784 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3787 klass->interfaces_inited = 1;
3789 } else if (klass->generic_class){
3790 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3791 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3796 if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
3798 for (i = 0; i < klass->method.count; ++i) {
3799 MonoMethod *im = klass->methods [i];
3800 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3801 im->slot = slot_num++;
3804 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3805 mono_class_setup_interface_offsets (klass);
3806 mono_class_setup_interface_id (klass);
3810 * The generic vtable is needed even if image->run is not set since some
3811 * runtime code like ves_icall_Type_GetMethodsByName depends on
3812 * method->slot being defined.
3816 * tb->methods could not be freed since it is used for determining
3817 * overrides during dynamic vtable construction.
3824 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3826 mono_error_init (error);
3827 MonoClass *klass = mono_object_class (method);
3828 if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
3829 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3830 return sr_method->method;
3832 if (is_sre_method_builder (klass)) {
3833 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3836 if (mono_is_sre_method_on_tb_inst (klass)) {
3837 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
3839 /*FIXME move this to a proper method and unify with resolve_object*/
3840 if (m->method_args) {
3841 result = mono_reflection_method_on_tb_inst_get_handle (m, error);
3843 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
3844 return_val_if_nok (error, NULL);
3845 MonoClass *inflated_klass = mono_class_from_mono_type (type);
3846 MonoMethod *mono_method;
3848 if (is_sre_method_builder (mono_object_class (m->mb)))
3849 mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
3850 else if (is_sr_mono_method (mono_object_class (m->mb)))
3851 mono_method = ((MonoReflectionMethod *)m->mb)->method;
3853 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)));
3855 result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
3860 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3865 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3867 MonoReflectionTypeBuilder *tb;
3869 MonoReflectionMethod *m;
3871 mono_error_init (error);
3875 g_assert (image_is_dynamic (klass->image));
3877 if (!mono_class_get_ref_info (klass))
3880 g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
3882 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
3886 for (i = 0; i < tb->num_methods; ++i) {
3887 MonoReflectionMethodBuilder *mb =
3888 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3889 if (mb->override_methods)
3890 onum += mono_array_length (mb->override_methods);
3895 *overrides = g_new0 (MonoMethod*, onum * 2);
3898 for (i = 0; i < tb->num_methods; ++i) {
3899 MonoReflectionMethodBuilder *mb =
3900 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3901 if (mb->override_methods) {
3902 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3903 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3905 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3906 return_if_nok (error);
3907 (*overrides) [onum * 2 + 1] = mb->mhandle;
3909 g_assert (mb->mhandle);
3917 *num_overrides = onum;
3921 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3923 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3924 MonoReflectionFieldBuilder *fb;
3925 MonoClassField *field;
3926 MonoImage *image = klass->image;
3929 guint32 len, idx, real_size = 0;
3931 klass->field.count = tb->num_fields;
3932 klass->field.first = 0;
3934 mono_error_init (error);
3936 if (tb->class_size) {
3937 if ((tb->packing_size & 0xffffff00) != 0) {
3938 char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
3939 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
3942 klass->packing_size = tb->packing_size;
3943 real_size = klass->instance_size + tb->class_size;
3946 if (!klass->field.count) {
3947 klass->instance_size = MAX (klass->instance_size, real_size);
3951 klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
3952 mono_class_alloc_ext (klass);
3953 klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
3955 This is, guess what, a hack.
3956 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3957 On the static path no field class is resolved, only types are built. This is the right thing to do
3959 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3961 klass->size_inited = 1;
3963 for (i = 0; i < klass->field.count; ++i) {
3964 MonoArray *rva_data;
3965 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3966 field = &klass->fields [i];
3967 field->name = mono_string_to_utf8_image (image, fb->name, error);
3968 if (!mono_error_ok (error))
3971 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3972 return_if_nok (error);
3973 field->type = mono_metadata_type_dup (klass->image, type);
3974 field->type->attrs = fb->attrs;
3976 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3977 return_if_nok (error);
3980 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3981 char *base = mono_array_addr (rva_data, char, 0);
3982 size_t size = mono_array_length (rva_data);
3983 char *data = (char *)mono_image_alloc (klass->image, size);
3984 memcpy (data, base, size);
3985 klass->ext->field_def_values [i].data = data;
3987 if (fb->offset != -1)
3988 field->offset = fb->offset;
3989 field->parent = klass;
3991 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3993 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
3994 klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
3996 if (fb->def_value) {
3997 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3998 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3999 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
4000 /* Copy the data from the blob since it might get realloc-ed */
4001 p = assembly->blob.data + idx;
4002 len = mono_metadata_decode_blob_size (p, &p2);
4004 klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
4005 memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
4009 klass->instance_size = MAX (klass->instance_size, real_size);
4010 mono_class_layout_fields (klass, klass->instance_size);
4014 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
4016 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4017 MonoReflectionPropertyBuilder *pb;
4018 MonoImage *image = klass->image;
4019 MonoProperty *properties;
4022 mono_error_init (error);
4025 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4027 klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
4028 klass->ext->property.first = 0;
4030 properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
4031 klass->ext->properties = properties;
4032 for (i = 0; i < klass->ext->property.count; ++i) {
4033 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
4034 properties [i].parent = klass;
4035 properties [i].attrs = pb->attrs;
4036 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
4037 if (!mono_error_ok (error))
4040 properties [i].get = pb->get_method->mhandle;
4042 properties [i].set = pb->set_method->mhandle;
4044 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
4045 if (pb->def_value) {
4048 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4049 if (!klass->ext->prop_def_values)
4050 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
4051 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
4052 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
4053 /* Copy the data from the blob since it might get realloc-ed */
4054 p = assembly->blob.data + idx;
4055 len = mono_metadata_decode_blob_size (p, &p2);
4057 klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
4058 memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
4063 static MonoReflectionEvent *
4064 reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
4066 mono_error_init (error);
4068 MonoEvent *event = g_new0 (MonoEvent, 1);
4071 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4072 if (!is_ok (error)) {
4076 klass = mono_class_from_mono_type (type);
4078 event->parent = klass;
4079 event->attrs = eb->attrs;
4080 event->name = mono_string_to_utf8_checked (eb->name, error);
4081 if (!is_ok (error)) {
4086 event->add = eb->add_method->mhandle;
4087 if (eb->remove_method)
4088 event->remove = eb->remove_method->mhandle;
4089 if (eb->raise_method)
4090 event->raise = eb->raise_method->mhandle;
4092 #ifndef MONO_SMALL_CONFIG
4093 if (eb->other_methods) {
4095 event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
4096 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4097 MonoReflectionMethodBuilder *mb =
4098 mono_array_get (eb->other_methods,
4099 MonoReflectionMethodBuilder*, j);
4100 event->other [j] = mb->mhandle;
4105 MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
4106 if (!is_ok (error)) {
4107 #ifndef MONO_SMALL_CONFIG
4108 g_free (event->other);
4116 MonoReflectionEvent *
4117 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
4120 MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
4121 mono_error_set_pending_exception (&error);
4126 typebuilder_setup_events (MonoClass *klass, MonoError *error)
4128 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4129 MonoReflectionEventBuilder *eb;
4130 MonoImage *image = klass->image;
4134 mono_error_init (error);
4137 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4139 klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
4140 klass->ext->event.first = 0;
4142 events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
4143 klass->ext->events = events;
4144 for (i = 0; i < klass->ext->event.count; ++i) {
4145 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
4146 events [i].parent = klass;
4147 events [i].attrs = eb->attrs;
4148 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
4149 if (!mono_error_ok (error))
4152 events [i].add = eb->add_method->mhandle;
4153 if (eb->remove_method)
4154 events [i].remove = eb->remove_method->mhandle;
4155 if (eb->raise_method)
4156 events [i].raise = eb->raise_method->mhandle;
4158 #ifndef MONO_SMALL_CONFIG
4159 if (eb->other_methods) {
4161 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
4162 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4163 MonoReflectionMethodBuilder *mb =
4164 mono_array_get (eb->other_methods,
4165 MonoReflectionMethodBuilder*, j);
4166 events [i].other [j] = mb->mhandle;
4170 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
4174 struct remove_instantiations_user_data
4181 remove_instantiations_of_and_ensure_contents (gpointer key,
4185 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
4186 MonoType *type = (MonoType*)key;
4187 MonoClass *klass = data->klass;
4188 gboolean already_failed = !is_ok (data->error);
4190 MonoError *error = already_failed ? &lerror : data->error;
4192 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
4193 MonoClass *inst_klass = mono_class_from_mono_type (type);
4194 //Ensure it's safe to use it.
4195 if (!fix_partial_generic_class (inst_klass, error)) {
4196 mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4197 // Marked the class with failure, but since some other instantiation already failed,
4198 // just report that one, and swallow the error from this one.
4200 mono_error_cleanup (error);
4208 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4213 MonoReflectionType* res;
4216 mono_error_init (&error);
4218 domain = mono_object_domain (tb);
4219 klass = mono_class_from_mono_type (tb->type.type);
4221 mono_save_custom_attrs (klass->image, klass, tb->cattrs);
4224 * we need to lock the domain because the lock will be taken inside
4225 * So, we need to keep the locking order correct.
4227 mono_loader_lock ();
4228 mono_domain_lock (domain);
4229 if (klass->wastypebuilder) {
4230 mono_domain_unlock (domain);
4231 mono_loader_unlock ();
4233 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4234 mono_error_set_pending_exception (&error);
4239 * Fields to set in klass:
4240 * the various flags: delegate/unicode/contextbound etc.
4242 klass->flags = tb->attrs;
4243 klass->has_cctor = 1;
4245 mono_class_setup_parent (klass, klass->parent);
4246 /* fool mono_class_setup_supertypes */
4247 klass->supertypes = NULL;
4248 mono_class_setup_supertypes (klass);
4249 mono_class_setup_mono_type (klass);
4252 if (!((MonoDynamicImage*)klass->image)->run) {
4253 if (klass->generic_container) {
4254 /* FIXME: The code below can't handle generic classes */
4255 klass->wastypebuilder = TRUE;
4256 mono_loader_unlock ();
4257 mono_domain_unlock (domain);
4259 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4260 mono_error_set_pending_exception (&error);
4267 /* enums are done right away */
4268 if (!klass->enumtype)
4269 if (!ensure_runtime_vtable (klass, &error))
4273 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
4274 MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
4275 mono_class_alloc_ext (klass);
4276 MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
4277 if (!is_ok (&error)) goto failure;
4278 klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
4282 klass->nested_classes_inited = TRUE;
4284 /* fields and object layout */
4285 if (klass->parent) {
4286 if (!klass->parent->size_inited)
4287 mono_class_init (klass->parent);
4288 klass->instance_size = klass->parent->instance_size;
4289 klass->sizes.class_size = 0;
4290 klass->min_align = klass->parent->min_align;
4291 /* if the type has no fields we won't call the field_setup
4292 * routine which sets up klass->has_references.
4294 klass->has_references |= klass->parent->has_references;
4296 klass->instance_size = sizeof (MonoObject);
4297 klass->min_align = 1;
4300 /* FIXME: handle packing_size and instance_size */
4301 typebuilder_setup_fields (klass, &error);
4302 if (!mono_error_ok (&error))
4304 typebuilder_setup_properties (klass, &error);
4305 if (!mono_error_ok (&error))
4308 typebuilder_setup_events (klass, &error);
4309 if (!mono_error_ok (&error))
4312 klass->wastypebuilder = TRUE;
4315 * If we are a generic TypeBuilder, there might be instantiations in the type cache
4316 * which have type System.Reflection.MonoGenericClass, but after the type is created,
4317 * we want to return normal System.MonoType objects, so clear these out from the cache.
4319 * Together with this we must ensure the contents of all instances to match the created type.
4321 if (domain->type_hash && klass->generic_container) {
4322 struct remove_instantiations_user_data data;
4324 data.error = &error;
4325 mono_error_assert_ok (&error);
4326 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
4327 if (!is_ok (&error))
4331 mono_domain_unlock (domain);
4332 mono_loader_unlock ();
4334 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
4335 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4336 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
4337 goto failure_unlocked;
4340 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4341 if (!is_ok (&error))
4342 goto failure_unlocked;
4344 g_assert (res != (MonoReflectionType*)tb);
4349 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4350 klass->wastypebuilder = TRUE;
4351 mono_domain_unlock (domain);
4352 mono_loader_unlock ();
4354 mono_error_set_pending_exception (&error);
4359 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
4361 MonoGenericParamFull *param;
4365 mono_error_init (error);
4367 image = &gparam->tbuilder->module->dynamic_image->image;
4369 param = mono_image_new0 (image, MonoGenericParamFull, 1);
4371 param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
4372 mono_error_assert_ok (error);
4373 param->param.num = gparam->index;
4375 if (gparam->mbuilder) {
4376 if (!gparam->mbuilder->generic_container) {
4377 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
4378 return_val_if_nok (error, FALSE);
4380 MonoClass *klass = mono_class_from_mono_type (tb);
4381 gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4382 gparam->mbuilder->generic_container->is_method = TRUE;
4384 * Cannot set owner.method, since the MonoMethod is not created yet.
4385 * Set the image field instead, so type_in_image () works.
4387 gparam->mbuilder->generic_container->is_anonymous = TRUE;
4388 gparam->mbuilder->generic_container->owner.image = klass->image;
4390 param->param.owner = gparam->mbuilder->generic_container;
4391 } else if (gparam->tbuilder) {
4392 if (!gparam->tbuilder->generic_container) {
4393 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
4394 return_val_if_nok (error, FALSE);
4395 MonoClass *klass = mono_class_from_mono_type (tb);
4396 gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4397 gparam->tbuilder->generic_container->owner.klass = klass;
4399 param->param.owner = gparam->tbuilder->generic_container;
4402 pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
4404 gparam->type.type = &pklass->byval_arg;
4406 mono_class_set_ref_info (pklass, gparam);
4407 mono_image_append_class_to_reflection_info_set (pklass);
4413 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
4416 (void) reflection_initialize_generic_parameter (gparam, &error);
4417 mono_error_set_pending_exception (&error);
4424 } DynamicMethodReleaseData;
4427 * The runtime automatically clean up those after finalization.
4429 static MonoReferenceQueue *dynamic_method_queue;
4432 free_dynamic_method (void *dynamic_method)
4434 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
4435 MonoDomain *domain = data->domain;
4436 MonoMethod *method = data->handle;
4439 mono_domain_lock (domain);
4440 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
4441 g_hash_table_remove (domain->method_to_dyn_method, method);
4442 mono_domain_unlock (domain);
4443 g_assert (dis_link);
4444 mono_gchandle_free (dis_link);
4446 mono_runtime_free_method (domain, method);
4451 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
4453 MonoReferenceQueue *queue;
4455 DynamicMethodReleaseData *release_data;
4456 ReflectionMethodBuilder rmb;
4457 MonoMethodSignature *sig;
4463 mono_error_init (error);
4465 if (mono_runtime_is_shutting_down ()) {
4466 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
4470 if (!(queue = dynamic_method_queue)) {
4471 mono_loader_lock ();
4472 if (!(queue = dynamic_method_queue))
4473 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
4474 mono_loader_unlock ();
4477 sig = dynamic_method_to_signature (mb, error);
4478 return_val_if_nok (error, FALSE);
4480 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
4483 * Resolve references.
4486 * Every second entry in the refs array is reserved for storing handle_class,
4487 * which is needed by the ldtoken implementation in the JIT.
4489 rmb.nrefs = mb->nrefs;
4490 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
4491 for (i = 0; i < mb->nrefs; i += 2) {
4492 MonoClass *handle_class;
4494 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
4496 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4497 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4499 * The referenced DynamicMethod should already be created by the managed
4500 * code, except in the case of circular references. In that case, we store
4501 * method in the refs array, and fix it up later when the referenced
4502 * DynamicMethod is created.
4504 if (method->mhandle) {
4505 ref = method->mhandle;
4507 /* FIXME: GC object stored in unmanaged memory */
4510 /* FIXME: GC object stored in unmanaged memory */
4511 method->referenced_by = g_slist_append (method->referenced_by, mb);
4513 handle_class = mono_defaults.methodhandle_class;
4515 MonoException *ex = NULL;
4516 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
4517 if (!is_ok (error)) {
4522 ex = mono_get_exception_type_load (NULL, NULL);
4523 else if (mono_security_core_clr_enabled ())
4524 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
4528 mono_error_set_exception_instance (error, ex);
4533 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4534 rmb.refs [i + 1] = handle_class;
4538 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
4539 if (!is_ok (error)) {
4543 klass = mono_class_from_mono_type (owner_type);
4545 klass = mono_defaults.object_class;
4548 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
4550 return_val_if_nok (error, FALSE);
4552 release_data = g_new (DynamicMethodReleaseData, 1);
4553 release_data->handle = handle;
4554 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
4555 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
4556 g_free (release_data);
4558 /* Fix up refs entries pointing at us */
4559 for (l = mb->referenced_by; l; l = l->next) {
4560 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
4561 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
4564 g_assert (method->mhandle);
4566 data = (gpointer*)wrapper->method_data;
4567 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
4568 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
4569 data [i + 1] = mb->mhandle;
4572 g_slist_free (mb->referenced_by);
4574 /* ilgen is no longer needed */
4577 domain = mono_domain_get ();
4578 mono_domain_lock (domain);
4579 if (!domain->method_to_dyn_method)
4580 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4581 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4582 mono_domain_unlock (domain);
4588 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4591 (void) reflection_create_dynamic_method (mb, &error);
4592 mono_error_set_pending_exception (&error);
4595 #endif /* DISABLE_REFLECTION_EMIT */
4597 MonoMethodSignature *
4598 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4600 MonoMethodSignature *sig;
4601 g_assert (image_is_dynamic (image));
4603 mono_error_init (error);
4605 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4609 return mono_method_signature_checked (method, error);
4612 #ifndef DISABLE_REFLECTION_EMIT
4615 * ensure_complete_type:
4617 * Ensure that KLASS is completed if it is a dynamic type, or references
4621 ensure_complete_type (MonoClass *klass, MonoError *error)
4623 mono_error_init (error);
4625 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
4626 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4628 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4629 return_if_nok (error);
4631 // Asserting here could break a lot of code
4632 //g_assert (klass->wastypebuilder);
4635 if (klass->generic_class) {
4636 MonoGenericInst *inst = klass->generic_class->context.class_inst;
4639 for (i = 0; i < inst->type_argc; ++i) {
4640 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4641 return_if_nok (error);
4647 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4649 gpointer result = NULL;
4651 mono_error_init (error);
4653 if (strcmp (obj->vtable->klass->name, "String") == 0) {
4654 result = mono_string_intern_checked ((MonoString*)obj, error);
4655 return_val_if_nok (error, NULL);
4656 *handle_class = mono_defaults.string_class;
4658 } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
4659 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4660 return_val_if_nok (error, NULL);
4661 MonoClass *mc = mono_class_from_mono_type (type);
4662 if (!mono_class_init (mc)) {
4663 mono_error_set_for_class_failure (error, mc);
4668 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4669 return_val_if_nok (error, NULL);
4671 result = mono_class_from_mono_type (inflated);
4672 mono_metadata_free_type (inflated);
4674 result = mono_class_from_mono_type (type);
4676 *handle_class = mono_defaults.typehandle_class;
4678 } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
4679 strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
4680 strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
4681 strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
4682 result = ((MonoReflectionMethod*)obj)->method;
4684 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4685 mono_error_assert_ok (error);
4687 *handle_class = mono_defaults.methodhandle_class;
4689 } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
4690 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
4691 result = mb->mhandle;
4693 /* Type is not yet created */
4694 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
4696 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4697 return_val_if_nok (error, NULL);
4700 * Hopefully this has been filled in by calling CreateType() on the
4704 * TODO: This won't work if the application finishes another
4705 * TypeBuilder instance instead of this one.
4707 result = mb->mhandle;
4710 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4711 mono_error_assert_ok (error);
4713 *handle_class = mono_defaults.methodhandle_class;
4714 } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
4715 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
4717 result = cb->mhandle;
4719 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
4721 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4722 return_val_if_nok (error, NULL);
4723 result = cb->mhandle;
4726 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4727 mono_error_assert_ok (error);
4729 *handle_class = mono_defaults.methodhandle_class;
4730 } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
4731 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4733 ensure_complete_type (field->parent, error);
4734 return_val_if_nok (error, NULL);
4737 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
4738 return_val_if_nok (error, NULL);
4740 MonoClass *klass = mono_class_from_mono_type (inflated);
4741 MonoClassField *inflated_field;
4742 gpointer iter = NULL;
4743 mono_metadata_free_type (inflated);
4744 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
4745 if (!strcmp (field->name, inflated_field->name))
4748 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4749 result = inflated_field;
4753 *handle_class = mono_defaults.fieldhandle_class;
4755 } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
4756 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
4757 result = fb->handle;
4760 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
4762 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4763 return_val_if_nok (error, NULL);
4764 result = fb->handle;
4767 if (fb->handle && fb->handle->parent->generic_container) {
4768 MonoClass *klass = fb->handle->parent;
4769 MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
4770 return_val_if_nok (error, NULL);
4772 MonoClass *inflated = mono_class_from_mono_type (type);
4774 result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
4776 mono_metadata_free_type (type);
4778 *handle_class = mono_defaults.fieldhandle_class;
4779 } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
4780 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
4781 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4782 return_val_if_nok (error, NULL);
4785 klass = type->data.klass;
4786 if (klass->wastypebuilder) {
4787 /* Already created */
4791 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4792 return_val_if_nok (error, NULL);
4793 result = type->data.klass;
4796 *handle_class = mono_defaults.typehandle_class;
4797 } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
4798 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4799 MonoMethodSignature *sig;
4802 if (helper->arguments)
4803 nargs = mono_array_length (helper->arguments);
4807 sig = mono_metadata_signature_alloc (image, nargs);
4808 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4809 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4811 if (helper->unmanaged_call_conv) { /* unmanaged */
4812 sig->call_convention = helper->unmanaged_call_conv - 1;
4813 sig->pinvoke = TRUE;
4814 } else if (helper->call_conv & 0x02) {
4815 sig->call_convention = MONO_CALL_VARARG;
4817 sig->call_convention = MONO_CALL_DEFAULT;
4820 sig->param_count = nargs;
4821 /* TODO: Copy type ? */
4822 sig->ret = helper->return_type->type;
4823 for (i = 0; i < nargs; ++i) {
4824 sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
4825 if (!is_ok (error)) {
4826 image_g_free (image, sig);
4832 *handle_class = NULL;
4833 } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4834 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4835 /* Already created by the managed code */
4836 g_assert (method->mhandle);
4837 result = method->mhandle;
4838 *handle_class = mono_defaults.methodhandle_class;
4839 } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
4840 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4841 return_val_if_nok (error, NULL);
4842 type = mono_class_inflate_generic_type_checked (type, context, error);
4843 return_val_if_nok (error, NULL);
4845 result = mono_class_from_mono_type (type);
4846 *handle_class = mono_defaults.typehandle_class;
4848 mono_metadata_free_type (type);
4849 } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
4850 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4851 return_val_if_nok (error, NULL);
4852 type = mono_class_inflate_generic_type_checked (type, context, error);
4853 return_val_if_nok (error, NULL);
4855 result = mono_class_from_mono_type (type);
4856 *handle_class = mono_defaults.typehandle_class;
4858 mono_metadata_free_type (type);
4859 } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
4860 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
4861 MonoClass *inflated;
4863 MonoClassField *field;
4865 if (is_sre_field_builder (mono_object_class (f->fb)))
4866 field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
4867 else if (is_sr_mono_field (mono_object_class (f->fb)))
4868 field = ((MonoReflectionField*)f->fb)->field;
4870 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)));
4872 MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
4873 return_val_if_nok (error, NULL);
4874 type = mono_class_inflate_generic_type_checked (finst, context, error);
4875 return_val_if_nok (error, NULL);
4877 inflated = mono_class_from_mono_type (type);
4879 result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
4880 ensure_complete_type (field->parent, error);
4881 if (!is_ok (error)) {
4882 mono_metadata_free_type (type);
4887 mono_metadata_free_type (type);
4888 *handle_class = mono_defaults.fieldhandle_class;
4889 } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
4890 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
4891 MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
4892 return_val_if_nok (error, NULL);
4893 MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
4894 return_val_if_nok (error, NULL);
4896 MonoClass *inflated_klass = mono_class_from_mono_type (type);
4899 if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
4900 method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
4901 else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
4902 method = ((MonoReflectionMethod *)c->cb)->method;
4904 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)));
4906 result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
4907 *handle_class = mono_defaults.methodhandle_class;
4908 mono_metadata_free_type (type);
4909 } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
4910 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
4911 if (m->method_args) {
4912 result = mono_reflection_method_on_tb_inst_get_handle (m, error);
4913 return_val_if_nok (error, NULL);
4915 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4916 mono_error_assert_ok (error);
4919 MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
4920 return_val_if_nok (error, NULL);
4921 MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
4922 return_val_if_nok (error, NULL);
4924 MonoClass *inflated_klass = mono_class_from_mono_type (type);
4927 if (is_sre_method_builder (mono_object_class (m->mb)))
4928 method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
4929 else if (is_sr_mono_method (mono_object_class (m->mb)))
4930 method = ((MonoReflectionMethod *)m->mb)->method;
4932 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)));
4934 result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
4935 mono_metadata_free_type (type);
4937 *handle_class = mono_defaults.methodhandle_class;
4938 } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
4939 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4946 mtype = mono_reflection_type_get_handle (m->parent, error);
4947 return_val_if_nok (error, NULL);
4948 klass = mono_class_from_mono_type (mtype);
4950 /* Find the method */
4952 name = mono_string_to_utf8_checked (m->name, error);
4953 return_val_if_nok (error, NULL);
4955 while ((method = mono_class_get_methods (klass, &iter))) {
4956 if (!strcmp (method->name, name))
4963 // FIXME: Check parameters/return value etc. match
4966 *handle_class = mono_defaults.methodhandle_class;
4967 } else if (is_sre_array (mono_object_get_class(obj)) ||
4968 is_sre_byref (mono_object_get_class(obj)) ||
4969 is_sre_pointer (mono_object_get_class(obj))) {
4970 MonoReflectionType *ref_type = (MonoReflectionType *)obj;
4971 MonoType *type = mono_reflection_type_get_handle (ref_type, error);
4972 return_val_if_nok (error, NULL);
4975 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4976 return_val_if_nok (error, NULL);
4978 result = mono_class_from_mono_type (inflated);
4979 mono_metadata_free_type (inflated);
4981 result = mono_class_from_mono_type (type);
4983 *handle_class = mono_defaults.typehandle_class;
4985 g_print ("%s\n", obj->vtable->klass->name);
4986 g_assert_not_reached ();
4991 #else /* DISABLE_REFLECTION_EMIT */
4994 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4996 g_assert_not_reached ();
5001 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
5003 g_assert_not_reached ();
5007 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
5009 g_assert_not_reached ();
5014 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5016 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
5020 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
5022 g_assert_not_reached ();
5026 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
5028 g_assert_not_reached ();
5033 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
5035 g_assert_not_reached ();
5040 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
5041 gboolean create_open_instance, gboolean register_token, MonoError *error)
5043 g_assert_not_reached ();
5048 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
5050 g_assert_not_reached ();
5054 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
5056 mono_error_init (error);
5061 MonoReflectionEvent *
5062 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
5064 g_assert_not_reached ();
5069 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
5071 g_assert_not_reached ();
5076 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
5078 g_assert_not_reached ();
5082 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
5087 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
5089 mono_error_init (error);
5095 #endif /* DISABLE_REFLECTION_EMIT */
5097 #ifndef DISABLE_REFLECTION_EMIT
5099 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5104 tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
5105 return_val_if_nok (error, NULL);
5106 klass = mono_class_from_mono_type (tb);
5108 return methodbuilder_to_mono_method (klass, mb, error);
5110 #else /* DISABLE_REFLECTION_EMIT */
5112 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5114 g_assert_not_reached ();
5117 #endif /* DISABLE_REFLECTION_EMIT */
5120 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
5122 MONO_CHECK_ARG_NULL (obj, 0);
5125 gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
5126 mono_error_set_pending_exception (&error);
5131 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
5132 MonoReflectionMethod *method,
5133 MonoArray *opt_param_types)
5135 MONO_CHECK_ARG_NULL (method, 0);
5138 gint32 result = mono_image_create_method_token (
5139 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
5140 mono_error_set_pending_exception (&error);
5145 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
5148 mono_image_create_pefile (mb, file, &error);
5149 mono_error_set_pending_exception (&error);
5153 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
5156 mono_image_build_metadata (mb, &error);
5157 mono_error_set_pending_exception (&error);
5161 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
5163 mono_image_register_token (mb->dynamic_image, token, obj);
5167 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
5171 mono_loader_lock ();
5172 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
5173 mono_loader_unlock ();
5179 * ves_icall_TypeBuilder_create_generic_class:
5180 * @tb: a TypeBuilder object
5183 * Creates the generic class after all generic parameters have been added.
5186 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
5189 (void) mono_reflection_create_generic_class (tb, &error);
5190 mono_error_set_pending_exception (&error);
5193 #ifndef DISABLE_REFLECTION_EMIT
5195 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5198 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
5199 mono_error_set_pending_exception (&error);
5205 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5207 mono_reflection_dynimage_basic_init (assemblyb);
5211 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
5213 return mono_type_is_generic_parameter (tb->type.type);
5217 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
5218 MonoReflectionType *t)
5220 enumtype->type = t->type;
5224 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
5226 mono_image_module_basic_init (moduleb);
5230 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
5232 return mono_image_insert_string (module, str);
5236 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
5238 MonoDynamicImage *image = moduleb->dynamic_image;
5240 g_assert (type->type);
5241 image->wrappers_type = mono_class_from_mono_type (type->type);