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"
37 #include "mono/io-layer/io-layer.h"
39 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
40 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder);
42 #ifndef DISABLE_REFLECTION_EMIT
43 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
44 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
45 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
46 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
47 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error);
48 static gboolean reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error);
51 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
54 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
55 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
56 static gboolean is_sre_array (MonoClass *klass);
57 static gboolean is_sre_byref (MonoClass *klass);
58 static gboolean is_sre_pointer (MonoClass *klass);
59 static gboolean is_sre_generic_instance (MonoClass *klass);
60 static gboolean is_sre_type_builder (MonoClass *klass);
61 static gboolean is_sre_method_builder (MonoClass *klass);
62 static gboolean is_sre_field_builder (MonoClass *klass);
63 static gboolean is_sre_gparam_builder (MonoClass *klass);
64 static gboolean is_sre_enum_builder (MonoClass *klass);
65 static gboolean is_sr_mono_method (MonoClass *klass);
66 static gboolean is_sr_mono_field (MonoClass *klass);
68 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
69 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
71 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
73 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
76 mono_reflection_emit_init (void)
78 mono_dynamic_images_init ();
82 type_get_fully_qualified_name (MonoType *type)
84 MONO_REQ_GC_NEUTRAL_MODE;
86 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
90 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
92 MONO_REQ_GC_UNSAFE_MODE;
97 klass = mono_class_from_mono_type (type);
99 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
100 ta = klass->image->assembly;
101 if (assembly_is_dynamic (ta) || (ta == ass)) {
102 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
103 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
104 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
106 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
109 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
112 #ifndef DISABLE_REFLECTION_EMIT
116 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
120 image_g_malloc (MonoImage *image, guint size)
122 MONO_REQ_GC_NEUTRAL_MODE;
125 return mono_image_alloc (image, size);
127 return g_malloc (size);
129 #endif /* !DISABLE_REFLECTION_EMIT */
134 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
138 mono_image_g_malloc0 (MonoImage *image, guint size)
140 MONO_REQ_GC_NEUTRAL_MODE;
143 return mono_image_alloc0 (image, size);
145 return g_malloc0 (size);
150 * @image: a MonoImage
153 * If @image is NULL, free @ptr, otherwise do nothing.
156 image_g_free (MonoImage *image, gpointer ptr)
162 #ifndef DISABLE_REFLECTION_EMIT
164 image_strdup (MonoImage *image, const char *s)
166 MONO_REQ_GC_NEUTRAL_MODE;
169 return mono_image_strdup (image, s);
175 #define image_g_new(image,struct_type, n_structs) \
176 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
178 #define image_g_new0(image,struct_type, n_structs) \
179 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
183 alloc_table (MonoDynamicTable *table, guint nrows)
185 mono_dynimage_alloc_table (table, nrows);
189 string_heap_insert (MonoDynamicStream *sh, const char *str)
191 return mono_dynstream_insert_string (sh, str);
195 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
197 return mono_dynstream_add_data (stream, data, len);
201 * Despite the name, we handle also TypeSpec (with the above helper).
204 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
206 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
210 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
211 * dest may be misaligned.
214 swap_with_size (char *dest, const char* val, int len, int nelem) {
215 MONO_REQ_GC_NEUTRAL_MODE;
216 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
219 for (elem = 0; elem < nelem; ++elem) {
245 g_assert_not_reached ();
251 memcpy (dest, val, len * nelem);
256 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
258 MONO_REQ_GC_UNSAFE_MODE;
260 guint32 num_clauses = 0;
263 MonoILExceptionInfo *ex_info;
264 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
265 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
266 if (ex_info->handlers)
267 num_clauses += mono_array_length (ex_info->handlers);
275 #ifndef DISABLE_REFLECTION_EMIT
276 static MonoExceptionClause*
277 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
279 MONO_REQ_GC_UNSAFE_MODE;
281 mono_error_init (error);
283 MonoExceptionClause *clauses;
284 MonoExceptionClause *clause;
285 MonoILExceptionInfo *ex_info;
286 MonoILExceptionBlock *ex_block;
287 guint32 finally_start;
288 int i, j, clause_index;;
290 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
293 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
294 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
295 finally_start = ex_info->start + ex_info->len;
296 if (!ex_info->handlers)
298 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
299 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
300 clause = &(clauses [clause_index]);
302 clause->flags = ex_block->type;
303 clause->try_offset = ex_info->start;
305 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
306 clause->try_len = finally_start - ex_info->start;
308 clause->try_len = ex_info->len;
309 clause->handler_offset = ex_block->start;
310 clause->handler_len = ex_block->len;
311 if (ex_block->extype) {
312 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
314 if (!is_ok (error)) {
315 image_g_free (image, clauses);
318 clause->data.catch_class = mono_class_from_mono_type (extype);
320 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
321 clause->data.filter_offset = ex_block->filter_offset;
323 clause->data.filter_offset = 0;
325 finally_start = ex_block->start + ex_block->len;
333 #endif /* !DISABLE_REFLECTION_EMIT */
335 #ifndef DISABLE_REFLECTION_EMIT
337 * LOCKING: Acquires the loader lock.
340 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
342 MONO_REQ_GC_UNSAFE_MODE;
344 MonoCustomAttrInfo *ainfo, *tmp;
346 if (!cattrs || !mono_array_length (cattrs))
349 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
352 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
354 mono_custom_attrs_free (tmp);
355 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
356 mono_loader_unlock ();
362 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
364 MONO_REQ_GC_UNSAFE_MODE;
366 MonoDynamicTable *table;
369 guint32 cols [MONO_ASSEMBLY_SIZE];
373 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
376 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
377 table = &assembly->tables [MONO_TABLE_MODULEREF];
378 token = table->next_idx ++;
380 alloc_table (table, table->rows);
381 values = table->values + token * MONO_MODULEREF_SIZE;
382 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
384 token <<= MONO_RESOLUTION_SCOPE_BITS;
385 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
386 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
391 if (assembly_is_dynamic (image->assembly))
393 memset (cols, 0, sizeof (cols));
395 /* image->assembly->image is the manifest module */
396 image = image->assembly->image;
397 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
400 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
401 token = table->next_idx ++;
403 alloc_table (table, table->rows);
404 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
405 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
406 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
407 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
408 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
409 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
410 values [MONO_ASSEMBLYREF_FLAGS] = 0;
411 values [MONO_ASSEMBLYREF_CULTURE] = 0;
412 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
414 if (strcmp ("", image->assembly->aname.culture)) {
415 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
416 image->assembly->aname.culture);
419 if ((pubkey = mono_image_get_public_key (image, &publen))) {
422 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
423 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
425 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
427 token <<= MONO_RESOLUTION_SCOPE_BITS;
428 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
429 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
433 #ifndef DISABLE_REFLECTION_EMIT
435 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
437 MONO_REQ_GC_UNSAFE_MODE;
439 mono_error_init (error);
440 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
442 rmb->ilgen = mb->ilgen;
443 rmb->rtype = (MonoReflectionType*)mb->rtype;
444 return_val_if_nok (error, FALSE);
445 rmb->parameters = mb->parameters;
446 rmb->generic_params = mb->generic_params;
447 rmb->generic_container = mb->generic_container;
448 rmb->opt_types = NULL;
449 rmb->pinfo = mb->pinfo;
450 rmb->attrs = mb->attrs;
451 rmb->iattrs = mb->iattrs;
452 rmb->call_conv = mb->call_conv;
453 rmb->code = mb->code;
454 rmb->type = mb->type;
455 rmb->name = mb->name;
456 rmb->table_idx = &mb->table_idx;
457 rmb->init_locals = mb->init_locals;
458 rmb->skip_visibility = FALSE;
459 rmb->return_modreq = mb->return_modreq;
460 rmb->return_modopt = mb->return_modopt;
461 rmb->param_modreq = mb->param_modreq;
462 rmb->param_modopt = mb->param_modopt;
463 rmb->permissions = mb->permissions;
464 rmb->mhandle = mb->mhandle;
469 rmb->charset = mb->charset;
470 rmb->extra_flags = mb->extra_flags;
471 rmb->native_cc = mb->native_cc;
472 rmb->dllentry = mb->dllentry;
480 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
482 MONO_REQ_GC_UNSAFE_MODE;
484 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
486 mono_error_init (error);
488 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
490 rmb->ilgen = mb->ilgen;
491 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
492 return_val_if_nok (error, FALSE);
493 rmb->parameters = mb->parameters;
494 rmb->generic_params = NULL;
495 rmb->generic_container = NULL;
496 rmb->opt_types = NULL;
497 rmb->pinfo = mb->pinfo;
498 rmb->attrs = mb->attrs;
499 rmb->iattrs = mb->iattrs;
500 rmb->call_conv = mb->call_conv;
502 rmb->type = mb->type;
503 rmb->name = mono_string_new (mono_domain_get (), name);
504 rmb->table_idx = &mb->table_idx;
505 rmb->init_locals = mb->init_locals;
506 rmb->skip_visibility = FALSE;
507 rmb->return_modreq = NULL;
508 rmb->return_modopt = NULL;
509 rmb->param_modreq = mb->param_modreq;
510 rmb->param_modopt = mb->param_modopt;
511 rmb->permissions = mb->permissions;
512 rmb->mhandle = mb->mhandle;
520 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
522 MONO_REQ_GC_UNSAFE_MODE;
524 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
526 rmb->ilgen = mb->ilgen;
527 rmb->rtype = mb->rtype;
528 rmb->parameters = mb->parameters;
529 rmb->generic_params = NULL;
530 rmb->generic_container = NULL;
531 rmb->opt_types = NULL;
533 rmb->attrs = mb->attrs;
535 rmb->call_conv = mb->call_conv;
537 rmb->type = (MonoObject *) mb->owner;
538 rmb->name = mb->name;
539 rmb->table_idx = NULL;
540 rmb->init_locals = mb->init_locals;
541 rmb->skip_visibility = mb->skip_visibility;
542 rmb->return_modreq = NULL;
543 rmb->return_modopt = NULL;
544 rmb->param_modreq = NULL;
545 rmb->param_modopt = NULL;
546 rmb->permissions = NULL;
547 rmb->mhandle = mb->mhandle;
551 #else /* DISABLE_REFLECTION_EMIT */
553 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
554 g_assert_not_reached ();
558 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
560 g_assert_not_reached ();
563 #endif /* DISABLE_REFLECTION_EMIT */
565 #ifndef DISABLE_REFLECTION_EMIT
567 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
569 MONO_REQ_GC_NEUTRAL_MODE;
571 MonoDynamicTable *table;
573 guint32 token, pclass;
575 switch (parent & MONO_TYPEDEFORREF_MASK) {
576 case MONO_TYPEDEFORREF_TYPEREF:
577 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
579 case MONO_TYPEDEFORREF_TYPESPEC:
580 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
582 case MONO_TYPEDEFORREF_TYPEDEF:
583 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
586 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
589 /* extract the index */
590 parent >>= MONO_TYPEDEFORREF_BITS;
592 table = &assembly->tables [MONO_TABLE_MEMBERREF];
594 if (assembly->save) {
595 alloc_table (table, table->rows + 1);
596 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
597 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
598 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
599 values [MONO_MEMBERREF_SIGNATURE] = sig;
602 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
609 * Insert a memberef row into the metadata: the token that point to the memberref
610 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
611 * mono_image_get_fieldref_token()).
612 * The sig param is an index to an already built signature.
615 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
617 MONO_REQ_GC_NEUTRAL_MODE;
619 guint32 parent = mono_image_typedef_or_ref (assembly, type);
620 return mono_image_add_memberef_row (assembly, parent, name, sig);
625 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
627 MONO_REQ_GC_NEUTRAL_MODE;
630 MonoMethodSignature *sig;
632 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
634 if (create_typespec) {
635 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
640 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
641 if (token && !create_typespec)
644 g_assert (!method->is_inflated);
647 * A methodref signature can't contain an unmanaged calling convention.
649 sig = mono_metadata_signature_dup (mono_method_signature (method));
650 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
651 sig->call_convention = MONO_CALL_DEFAULT;
652 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
653 method->name, mono_dynimage_encode_method_signature (assembly, sig));
655 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
658 if (create_typespec) {
659 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
660 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
661 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
663 if (assembly->save) {
666 alloc_table (table, table->rows + 1);
667 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
668 values [MONO_METHODSPEC_METHOD] = token;
669 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
672 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
674 /*methodspec and memberef tokens are diferent, */
675 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
682 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
683 const gchar *name, guint32 sig)
685 MonoDynamicTable *table;
689 table = &assembly->tables [MONO_TABLE_MEMBERREF];
691 if (assembly->save) {
692 alloc_table (table, table->rows + 1);
693 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
694 values [MONO_MEMBERREF_CLASS] = original;
695 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
696 values [MONO_MEMBERREF_SIGNATURE] = sig;
699 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
708 is_field_on_inst (MonoClassField *field)
710 return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
713 #ifndef DISABLE_REFLECTION_EMIT
715 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
721 g_assert (field->parent);
723 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
727 if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
728 int index = field - field->parent->fields;
729 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
731 type = mono_field_get_type (field);
733 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
734 mono_field_get_name (field),
735 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
736 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
741 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
743 MonoDynamicTable *table;
745 guint32 token, mtoken = 0, sig;
746 MonoMethodInflated *imethod;
747 MonoMethod *declaring;
749 table = &assembly->tables [MONO_TABLE_METHODSPEC];
751 g_assert (method->is_inflated);
752 imethod = (MonoMethodInflated *) method;
753 declaring = imethod->declaring;
755 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
756 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
758 if (!mono_method_signature (declaring)->generic_param_count)
761 switch (mono_metadata_token_table (mtoken)) {
762 case MONO_TABLE_MEMBERREF:
763 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
765 case MONO_TABLE_METHOD:
766 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
769 g_assert_not_reached ();
772 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
774 if (assembly->save) {
775 alloc_table (table, table->rows + 1);
776 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
777 values [MONO_METHODSPEC_METHOD] = mtoken;
778 values [MONO_METHODSPEC_SIGNATURE] = sig;
781 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
788 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
790 MonoMethodInflated *imethod;
793 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
797 g_assert (method->is_inflated);
798 imethod = (MonoMethodInflated *) method;
800 if (mono_method_signature (imethod->declaring)->generic_param_count) {
801 token = method_encode_methodspec (assembly, method);
803 guint32 sig = mono_dynimage_encode_method_signature (
804 assembly, mono_method_signature (imethod->declaring));
805 token = mono_image_get_memberref_token (
806 assembly, &method->klass->byval_arg, method->name, sig);
809 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
814 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
816 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
819 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
820 token = mono_image_get_memberref_token (
821 assembly, &m->klass->byval_arg, m->name, sig);
827 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
830 MonoDynamicTable *table;
833 mono_error_init (error);
835 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
836 idx = table->next_idx ++;
838 alloc_table (table, table->rows);
839 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
841 values [MONO_STAND_ALONE_SIGNATURE] =
842 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
843 return_val_if_nok (error, 0);
849 reflection_cc_to_file (int call_conv) {
850 switch (call_conv & 0x3) {
852 case 1: return MONO_CALL_DEFAULT;
853 case 2: return MONO_CALL_VARARG;
855 g_assert_not_reached ();
859 #endif /* !DISABLE_REFLECTION_EMIT */
861 struct _ArrayMethod {
863 MonoMethodSignature *sig;
869 mono_sre_array_method_free (ArrayMethod *am)
876 #ifndef DISABLE_REFLECTION_EMIT
878 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
883 MonoMethodSignature *sig;
884 ArrayMethod *am = NULL;
887 mono_error_init (error);
889 nparams = mono_array_length (m->parameters);
890 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
892 sig->sentinelpos = -1;
893 sig->call_convention = reflection_cc_to_file (m->call_conv);
894 sig->param_count = nparams;
896 sig->ret = mono_reflection_type_get_handle (m->ret, error);
900 sig->ret = &mono_defaults.void_class->byval_arg;
902 mtype = mono_reflection_type_get_handle (m->parent, error);
906 for (i = 0; i < nparams; ++i) {
907 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
912 name = mono_string_to_utf8_checked (m->name, error);
915 for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
916 am = (ArrayMethod *)tmp->data;
917 if (strcmp (name, am->name) == 0 &&
918 mono_metadata_type_equal (am->parent, mtype) &&
919 mono_metadata_signature_equal (am->sig, sig)) {
922 m->table_idx = am->token & 0xffffff;
926 am = g_new0 (ArrayMethod, 1);
930 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
931 mono_dynimage_encode_method_signature (assembly, sig));
932 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
933 m->table_idx = am->token & 0xffffff;
944 #ifndef DISABLE_REFLECTION_EMIT
947 * mono_image_insert_string:
948 * @module: module builder object
951 * Insert @str into the user string stream of @module.
954 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
956 MonoDynamicImage *assembly;
961 if (!module->dynamic_image)
962 mono_image_module_basic_init (module);
964 assembly = module->dynamic_image;
966 if (assembly->save) {
967 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
968 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
969 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
971 char *swapped = g_malloc (2 * mono_string_length (str));
972 const char *p = (const char*)mono_string_chars (str);
974 swap_with_size (swapped, p, 2, mono_string_length (str));
975 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
979 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
981 mono_image_add_stream_data (&assembly->us, "", 1);
983 idx = assembly->us.index ++;
986 mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
988 return MONO_TOKEN_STRING | idx;
992 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
996 MonoMethodSignature *sig;
998 mono_error_init (error);
1000 klass = obj->vtable->klass;
1001 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1002 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1003 MonoMethodSignature *old;
1004 guint32 sig_token, parent;
1007 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1009 nargs = mono_array_length (opt_param_types);
1010 old = mono_method_signature (method);
1011 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1013 sig->hasthis = old->hasthis;
1014 sig->explicit_this = old->explicit_this;
1015 sig->call_convention = old->call_convention;
1016 sig->generic_param_count = old->generic_param_count;
1017 sig->param_count = old->param_count + nargs;
1018 sig->sentinelpos = old->param_count;
1019 sig->ret = old->ret;
1021 for (i = 0; i < old->param_count; i++)
1022 sig->params [i] = old->params [i];
1024 for (i = 0; i < nargs; i++) {
1025 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1026 sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1027 if (!is_ok (error)) goto fail;
1030 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1031 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1032 parent >>= MONO_TYPEDEFORREF_BITS;
1034 parent <<= MONO_MEMBERREF_PARENT_BITS;
1035 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1037 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1038 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1039 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1040 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1041 ReflectionMethodBuilder rmb;
1042 guint32 parent, sig_token;
1043 int nopt_args, nparams, ngparams, i;
1045 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1048 rmb.opt_types = opt_param_types;
1049 nopt_args = mono_array_length (opt_param_types);
1051 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1052 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1053 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1055 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1056 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1057 sig->call_convention = rmb.call_conv;
1058 sig->generic_param_count = ngparams;
1059 sig->param_count = nparams + nopt_args;
1060 sig->sentinelpos = nparams;
1061 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1062 if (!is_ok (error)) goto fail;
1064 for (i = 0; i < nparams; i++) {
1065 MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1066 sig->params [i] = mono_reflection_type_get_handle (rt, error);
1067 if (!is_ok (error)) goto fail;
1070 for (i = 0; i < nopt_args; i++) {
1071 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1072 sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1073 if (!is_ok (error)) goto fail;
1076 // FIXME: This doesn't work, we don't use 'sig' for anything
1077 // The token fixup doesn't work either
1078 g_assert_not_reached ();
1080 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1084 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1085 if (!mono_error_ok (error))
1087 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1089 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1090 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1092 char *name = mono_string_to_utf8_checked (rmb.name, error);
1093 if (!is_ok (error)) goto fail;
1094 token = mono_image_get_varargs_method_token (
1095 assembly, parent, name, sig_token);
1098 g_error ("requested method token for %s\n", klass->name);
1101 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1102 mono_dynamic_image_register_token (assembly, token, obj);
1105 g_assert (!mono_error_ok (error));
1110 * mono_image_create_token:
1111 * @assembly: a dynamic assembly
1113 * @register_token: Whenever to register the token in the assembly->tokens hash.
1115 * Get a token to insert in the IL code stream for the given MemberInfo.
1116 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1117 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1121 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
1122 gboolean create_open_instance, gboolean register_token,
1128 mono_error_init (error);
1130 klass = obj->vtable->klass;
1132 /* Check for user defined reflection objects */
1133 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1134 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1135 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1139 if (strcmp (klass->name, "RuntimeType") == 0) {
1140 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1141 return_val_if_nok (error, 0);
1142 MonoClass *mc = mono_class_from_mono_type (type);
1143 token = mono_metadata_token_from_dor (
1144 mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1145 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1146 strcmp (klass->name, "MonoMethod") == 0) {
1147 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1148 if (m->method->is_inflated) {
1149 if (create_open_instance)
1150 token = mono_image_get_methodspec_token (assembly, m->method);
1152 token = mono_image_get_inflated_method_token (assembly, m->method);
1153 } else if ((m->method->klass->image == &assembly->image) &&
1154 !mono_class_is_ginst (m->method->klass)) {
1155 static guint32 method_table_idx = 0xffffff;
1156 if (m->method->klass->wastypebuilder) {
1157 /* we use the same token as the one that was assigned
1158 * to the Methodbuilder.
1159 * FIXME: do the equivalent for Fields.
1161 token = m->method->token;
1164 * Each token should have a unique index, but the indexes are
1165 * assigned by managed code, so we don't know about them. An
1166 * easy solution is to count backwards...
1168 method_table_idx --;
1169 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1172 token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1174 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1175 } else if (strcmp (klass->name, "MonoField") == 0) {
1176 MonoReflectionField *f = (MonoReflectionField *)obj;
1177 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1178 static guint32 field_table_idx = 0xffffff;
1180 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1182 token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1184 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1185 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1186 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1187 token = mono_image_get_array_token (assembly, m, error);
1188 return_val_if_nok (error, 0);
1189 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1190 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1191 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1192 return_val_if_nok (error, 0);
1193 } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1194 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1195 return_val_if_nok (error, 0);
1196 token = mono_metadata_token_from_dor (
1197 mono_image_typedef_or_ref (assembly, type));
1199 g_error ("requested token for %s\n", klass->name);
1203 mono_image_register_token (assembly, token, obj);
1211 #ifndef DISABLE_REFLECTION_EMIT
1214 * mono_reflection_dynimage_basic_init:
1215 * @assembly: an assembly builder object
1217 * Create the MonoImage that represents the assembly builder and setup some
1218 * of the helper hash table and the basic metadata streams.
1221 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1224 MonoDynamicAssembly *assembly;
1225 MonoDynamicImage *image;
1226 MonoDomain *domain = mono_object_domain (assemblyb);
1228 if (assemblyb->dynamic_assembly)
1232 /* assembly->assembly.image might be GC allocated */
1233 assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1235 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1238 mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1240 assembly->assembly.ref_count = 1;
1241 assembly->assembly.dynamic = TRUE;
1242 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1243 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1244 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1245 if (mono_error_set_pending_exception (&error))
1247 if (assemblyb->culture) {
1248 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1249 if (mono_error_set_pending_exception (&error))
1252 assembly->assembly.aname.culture = g_strdup ("");
1254 if (assemblyb->version) {
1255 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1256 if (mono_error_set_pending_exception (&error))
1258 char **version = g_strsplit (vstr, ".", 4);
1259 char **parts = version;
1260 assembly->assembly.aname.major = atoi (*parts++);
1261 assembly->assembly.aname.minor = atoi (*parts++);
1262 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1263 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1265 g_strfreev (version);
1268 assembly->assembly.aname.major = 0;
1269 assembly->assembly.aname.minor = 0;
1270 assembly->assembly.aname.build = 0;
1271 assembly->assembly.aname.revision = 0;
1274 assembly->run = assemblyb->access != 2;
1275 assembly->save = assemblyb->access != 1;
1276 assembly->domain = domain;
1278 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1279 if (mono_error_set_pending_exception (&error))
1281 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1282 image->initial_image = TRUE;
1283 assembly->assembly.aname.name = image->image.name;
1284 assembly->assembly.image = &image->image;
1285 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1286 /* -1 to correct for the trailing NULL byte */
1287 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1288 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1290 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1293 mono_domain_assemblies_lock (domain);
1294 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1295 mono_domain_assemblies_unlock (domain);
1297 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1299 mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1301 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1304 #endif /* !DISABLE_REFLECTION_EMIT */
1306 #ifndef DISABLE_REFLECTION_EMIT
1308 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1310 return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1314 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
1316 return CACHE_OBJECT (MonoReflectionModuleBuilder *, module, &res->module.obj, NULL);
1320 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
1322 MonoDynamicImage *image = moduleb->dynamic_image;
1323 MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
1324 mono_error_init (error);
1327 MonoImage **new_modules;
1329 char *name, *fqname;
1331 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1332 * we don't know which module it belongs to, since that is only
1333 * determined at assembly save time.
1335 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1336 name = mono_string_to_utf8_checked (ab->name, error);
1337 return_val_if_nok (error, FALSE);
1338 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
1339 if (!is_ok (error)) {
1343 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
1345 moduleb->module.image = &image->image;
1346 moduleb->dynamic_image = image;
1347 register_module (mono_object_domain (moduleb), moduleb, image);
1349 /* register the module with the assembly */
1350 ass = ab->dynamic_assembly->assembly.image;
1351 module_count = ass->module_count;
1352 new_modules = g_new0 (MonoImage *, module_count + 1);
1355 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1356 new_modules [module_count] = &image->image;
1357 mono_image_addref (&image->image);
1359 g_free (ass->modules);
1360 ass->modules = new_modules;
1361 ass->module_count ++;
1367 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
1370 (void) image_module_basic_init (moduleb, &error);
1371 mono_error_set_pending_exception (&error);
1377 is_corlib_type (MonoClass *klass)
1379 return klass->image == mono_defaults.corlib;
1382 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1383 static MonoClass *cached_class; \
1385 return cached_class == _class; \
1386 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1387 cached_class = _class; \
1395 #ifndef DISABLE_REFLECTION_EMIT
1397 is_sre_array (MonoClass *klass)
1399 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1403 is_sre_byref (MonoClass *klass)
1405 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1409 is_sre_pointer (MonoClass *klass)
1411 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1415 is_sre_generic_instance (MonoClass *klass)
1417 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1421 is_sre_type_builder (MonoClass *klass)
1423 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1427 is_sre_method_builder (MonoClass *klass)
1429 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1433 mono_is_sre_ctor_builder (MonoClass *klass)
1435 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1439 is_sre_field_builder (MonoClass *klass)
1441 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1445 is_sre_gparam_builder (MonoClass *klass)
1447 check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1451 is_sre_enum_builder (MonoClass *klass)
1453 check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1457 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1459 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1463 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1465 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1468 static MonoReflectionType*
1469 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
1471 static MonoMethod *method_get_underlying_system_type = NULL;
1472 MonoReflectionType *rt;
1473 MonoMethod *usertype_method;
1475 mono_error_init (error);
1477 if (!method_get_underlying_system_type)
1478 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1480 usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
1482 rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
1488 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
1491 mono_error_init (error);
1498 if (mono_reflection_is_usertype (ref)) {
1499 ref = mono_reflection_type_get_underlying_system_type (ref, error);
1500 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
1506 klass = mono_object_class (ref);
1508 if (is_sre_array (klass)) {
1510 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
1511 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
1512 return_val_if_nok (error, NULL);
1514 if (sre_array->rank == 0) //single dimentional array
1515 res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
1517 res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
1518 sre_array->type.type = res;
1520 } else if (is_sre_byref (klass)) {
1522 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
1523 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
1524 return_val_if_nok (error, NULL);
1526 res = &mono_class_from_mono_type (base)->this_arg;
1527 sre_byref->type.type = res;
1529 } else if (is_sre_pointer (klass)) {
1531 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
1532 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
1533 return_val_if_nok (error, NULL);
1535 res = &mono_ptr_class_get (base)->byval_arg;
1536 sre_pointer->type.type = res;
1538 } else if (is_sre_generic_instance (klass)) {
1539 MonoType *res, **types;
1540 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
1543 count = mono_array_length (gclass->type_arguments);
1544 types = g_new0 (MonoType*, count);
1545 for (i = 0; i < count; ++i) {
1546 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
1547 types [i] = mono_reflection_type_get_handle (t, error);
1548 if (!types[i] || !is_ok (error)) {
1553 /* Need to resolve the generic_type in order for it to create its generic context. */
1554 MonoType *gtd = mono_reflection_type_get_handle (gclass->generic_type, error);
1555 if (!is_ok (error)) {
1559 MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
1560 if (is_sre_type_builder (mono_object_class (gclass->generic_type))) {
1561 reflection_create_generic_class ((MonoReflectionTypeBuilder*)gclass->generic_type, error);
1562 if (!is_ok (error)) {
1567 g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1568 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
1571 gclass->type.type = res;
1573 } else if (is_sre_gparam_builder (klass)) {
1574 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)ref;
1575 MonoGenericParamFull *param;
1579 image = &gparam->tbuilder->module->dynamic_image->image;
1581 param = mono_image_new0 (image, MonoGenericParamFull, 1);
1583 param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
1584 mono_error_assert_ok (error);
1585 param->param.num = gparam->index;
1587 if (gparam->mbuilder) {
1588 if (!gparam->mbuilder->generic_container) {
1589 gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1590 gparam->mbuilder->generic_container->is_method = TRUE;
1592 * Cannot set owner.method, since the MonoMethod is not created yet.
1593 * Set the image field instead, so type_in_image () works.
1595 gparam->mbuilder->generic_container->is_anonymous = TRUE;
1596 gparam->mbuilder->generic_container->owner.image = image;
1598 param->param.owner = gparam->mbuilder->generic_container;
1599 } else if (gparam->tbuilder) {
1600 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)(gparam->tbuilder), error);
1601 mono_error_assert_ok (error);
1602 MonoClass *owner = mono_class_from_mono_type (type);
1603 g_assert (mono_class_is_gtd (owner));
1604 param->param.owner = mono_class_get_generic_container (owner);
1607 pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1609 gparam->type.type = &pklass->byval_arg;
1611 mono_class_set_ref_info (pklass, gparam);
1612 mono_image_append_class_to_reflection_info_set (pklass);
1614 return &pklass->byval_arg;
1615 } else if (is_sre_enum_builder (klass)) {
1616 MonoReflectionEnumBuilder *ebuilder = (MonoReflectionEnumBuilder *)ref;
1618 return mono_reflection_type_get_handle ((MonoReflectionType*)ebuilder->tb, error);
1619 } else if (is_sre_type_builder (klass)) {
1620 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)ref;
1622 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1623 reflection_setup_internal_class (tb, error);
1624 mono_error_assert_ok (error);
1625 g_assert (ref->type);
1629 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1634 * LOCKING: Assumes the loader lock is held.
1636 static MonoMethodSignature*
1637 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
1638 MonoMethodSignature *sig;
1641 mono_error_init (error);
1643 count = parameters? mono_array_length (parameters): 0;
1645 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1646 sig->param_count = count;
1647 sig->sentinelpos = -1; /* FIXME */
1648 for (i = 0; i < count; ++i) {
1649 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1650 if (!is_ok (error)) {
1651 image_g_free (image, sig);
1659 * LOCKING: Assumes the loader lock is held.
1661 static MonoMethodSignature*
1662 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
1663 MonoMethodSignature *sig;
1665 mono_error_init (error);
1667 sig = parameters_to_signature (image, ctor->parameters, error);
1668 return_val_if_nok (error, NULL);
1669 sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1670 sig->ret = &mono_defaults.void_class->byval_arg;
1675 * LOCKING: Assumes the loader lock is held.
1677 static MonoMethodSignature*
1678 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
1679 MonoMethodSignature *sig;
1681 mono_error_init (error);
1683 sig = parameters_to_signature (image, method->parameters, error);
1684 return_val_if_nok (error, NULL);
1685 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1686 if (method->rtype) {
1687 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
1688 if (!is_ok (error)) {
1689 image_g_free (image, sig);
1693 sig->ret = &mono_defaults.void_class->byval_arg;
1695 sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
1699 static MonoMethodSignature*
1700 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
1701 MonoMethodSignature *sig;
1703 mono_error_init (error);
1705 sig = parameters_to_signature (NULL, method->parameters, error);
1706 return_val_if_nok (error, NULL);
1707 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1708 if (method->rtype) {
1709 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
1710 if (!is_ok (error)) {
1715 sig->ret = &mono_defaults.void_class->byval_arg;
1717 sig->generic_param_count = 0;
1722 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1724 mono_error_init (error);
1725 MonoClass *klass = mono_object_class (prop);
1726 if (strcmp (klass->name, "PropertyBuilder") == 0) {
1727 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1728 *name = mono_string_to_utf8_checked (pb->name, error);
1729 return_if_nok (error);
1730 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1732 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1733 *name = g_strdup (p->property->name);
1734 if (p->property->get)
1735 *type = mono_method_signature (p->property->get)->ret;
1737 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1742 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1744 mono_error_init (error);
1745 MonoClass *klass = mono_object_class (field);
1746 if (strcmp (klass->name, "FieldBuilder") == 0) {
1747 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1748 *name = mono_string_to_utf8_checked (fb->name, error);
1749 return_if_nok (error);
1750 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1752 MonoReflectionField *f = (MonoReflectionField *)field;
1753 *name = g_strdup (mono_field_get_name (f->field));
1754 *type = f->field->type;
1758 #else /* DISABLE_REFLECTION_EMIT */
1761 is_sre_type_builder (MonoClass *klass)
1767 is_sre_generic_instance (MonoClass *klass)
1773 mono_is_sre_ctor_builder (MonoClass *klass)
1779 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1785 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1790 #endif /* !DISABLE_REFLECTION_EMIT */
1794 is_sr_mono_field (MonoClass *klass)
1796 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1800 mono_is_sr_mono_property (MonoClass *klass)
1802 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1806 is_sr_mono_method (MonoClass *klass)
1808 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1812 mono_is_sr_mono_cmethod (MonoClass *klass)
1814 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1818 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1820 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1824 mono_is_sre_type_builder (MonoClass *klass)
1826 return is_sre_type_builder (klass);
1830 mono_is_sre_generic_instance (MonoClass *klass)
1832 return is_sre_generic_instance (klass);
1838 * encode_cattr_value:
1839 * Encode a value in a custom attribute stream of bytes.
1840 * The value to encode is either supplied as an object in argument val
1841 * (valuetypes are boxed), or as a pointer to the data in the
1843 * @type represents the type of the value
1844 * @buffer is the start of the buffer
1845 * @p the current position in the buffer
1846 * @buflen contains the size of the buffer and is used to return the new buffer size
1847 * if this needs to be realloced.
1848 * @retbuffer and @retp return the start and the position of the buffer
1849 * @error set on error.
1852 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
1854 MonoTypeEnum simple_type;
1856 mono_error_init (error);
1857 if ((p-buffer) + 10 >= *buflen) {
1860 newbuf = (char *)g_realloc (buffer, *buflen);
1861 p = newbuf + (p-buffer);
1865 argval = ((char*)arg + sizeof (MonoObject));
1866 simple_type = type->type;
1868 switch (simple_type) {
1869 case MONO_TYPE_BOOLEAN:
1874 case MONO_TYPE_CHAR:
1877 swap_with_size (p, argval, 2, 1);
1883 swap_with_size (p, argval, 4, 1);
1887 swap_with_size (p, argval, 8, 1);
1892 swap_with_size (p, argval, 8, 1);
1895 case MONO_TYPE_VALUETYPE:
1896 if (type->data.klass->enumtype) {
1897 simple_type = mono_class_enum_basetype (type->data.klass)->type;
1900 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
1903 case MONO_TYPE_STRING: {
1910 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
1911 return_if_nok (error);
1912 slen = strlen (str);
1913 if ((p-buffer) + 10 + slen >= *buflen) {
1917 newbuf = (char *)g_realloc (buffer, *buflen);
1918 p = newbuf + (p-buffer);
1921 mono_metadata_encode_value (slen, p, &p);
1922 memcpy (p, str, slen);
1927 case MONO_TYPE_CLASS: {
1936 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
1937 return_if_nok (error);
1939 str = type_get_qualified_name (arg_type, NULL);
1940 slen = strlen (str);
1941 if ((p-buffer) + 10 + slen >= *buflen) {
1945 newbuf = (char *)g_realloc (buffer, *buflen);
1946 p = newbuf + (p-buffer);
1949 mono_metadata_encode_value (slen, p, &p);
1950 memcpy (p, str, slen);
1955 case MONO_TYPE_SZARRAY: {
1957 MonoClass *eclass, *arg_eclass;
1960 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
1963 len = mono_array_length ((MonoArray*)arg);
1965 *p++ = (len >> 8) & 0xff;
1966 *p++ = (len >> 16) & 0xff;
1967 *p++ = (len >> 24) & 0xff;
1969 *retbuffer = buffer;
1970 eclass = type->data.klass;
1971 arg_eclass = mono_object_class (arg)->element_class;
1974 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
1975 eclass = mono_defaults.object_class;
1977 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
1978 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
1979 int elsize = mono_class_array_element_size (arg_eclass);
1980 for (i = 0; i < len; ++i) {
1981 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
1982 return_if_nok (error);
1985 } else if (eclass->valuetype && arg_eclass->valuetype) {
1986 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
1987 int elsize = mono_class_array_element_size (eclass);
1988 for (i = 0; i < len; ++i) {
1989 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
1990 return_if_nok (error);
1994 for (i = 0; i < len; ++i) {
1995 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
1996 return_if_nok (error);
2001 case MONO_TYPE_OBJECT: {
2007 * The parameter type is 'object' but the type of the actual
2008 * argument is not. So we have to add type information to the blob
2009 * too. This is completely undocumented in the spec.
2013 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2018 klass = mono_object_class (arg);
2020 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2024 return_if_nok (error);
2027 if (klass->enumtype) {
2029 } else if (klass == mono_defaults.string_class) {
2030 simple_type = MONO_TYPE_STRING;
2033 } else if (klass->rank == 1) {
2035 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2036 /* See Partition II, Appendix B3 */
2039 *p++ = klass->element_class->byval_arg.type;
2040 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2041 return_if_nok (error);
2043 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2044 *p++ = simple_type = klass->byval_arg.type;
2047 g_error ("unhandled type in custom attr");
2049 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2050 slen = strlen (str);
2051 if ((p-buffer) + 10 + slen >= *buflen) {
2055 newbuf = (char *)g_realloc (buffer, *buflen);
2056 p = newbuf + (p-buffer);
2059 mono_metadata_encode_value (slen, p, &p);
2060 memcpy (p, str, slen);
2063 simple_type = mono_class_enum_basetype (klass)->type;
2067 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2070 *retbuffer = buffer;
2074 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2076 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2077 char *str = type_get_qualified_name (type, NULL);
2078 int slen = strlen (str);
2082 * This seems to be optional...
2085 mono_metadata_encode_value (slen, p, &p);
2086 memcpy (p, str, slen);
2089 } else if (type->type == MONO_TYPE_OBJECT) {
2091 } else if (type->type == MONO_TYPE_CLASS) {
2092 /* it should be a type: encode_cattr_value () has the check */
2095 mono_metadata_encode_value (type->type, p, &p);
2096 if (type->type == MONO_TYPE_SZARRAY)
2097 /* See the examples in Partition VI, Annex B */
2098 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2104 #ifndef DISABLE_REFLECTION_EMIT
2106 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2110 mono_error_init (error);
2112 /* Preallocate a large enough buffer */
2113 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2114 char *str = type_get_qualified_name (type, NULL);
2117 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2118 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2124 len += strlen (name);
2126 if ((p-buffer) + 20 + len >= *buflen) {
2130 newbuf = (char *)g_realloc (buffer, *buflen);
2131 p = newbuf + (p-buffer);
2135 encode_field_or_prop_type (type, p, &p);
2137 len = strlen (name);
2138 mono_metadata_encode_value (len, p, &p);
2139 memcpy (p, name, len);
2141 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2142 return_if_nok (error);
2144 *retbuffer = buffer;
2148 * mono_reflection_get_custom_attrs_blob:
2149 * @ctor: custom attribute constructor
2150 * @ctorArgs: arguments o the constructor
2156 * Creates the blob of data that needs to be saved in the metadata and that represents
2157 * the custom attributed described by @ctor, @ctorArgs etc.
2158 * Returns: a Byte array representing the blob of data.
2161 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2164 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2165 mono_error_cleanup (&error);
2170 * mono_reflection_get_custom_attrs_blob_checked:
2171 * @ctor: custom attribute constructor
2172 * @ctorArgs: arguments o the constructor
2177 * @error: set on error
2179 * Creates the blob of data that needs to be saved in the metadata and that represents
2180 * the custom attributed described by @ctor, @ctorArgs etc.
2181 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2184 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2186 MonoArray *result = NULL;
2187 MonoMethodSignature *sig;
2192 mono_error_init (error);
2194 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2195 /* sig is freed later so allocate it in the heap */
2196 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2197 if (!is_ok (error)) {
2202 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2205 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2207 p = buffer = (char *)g_malloc (buflen);
2208 /* write the prolog */
2211 for (i = 0; i < sig->param_count; ++i) {
2212 arg = mono_array_get (ctorArgs, MonoObject*, i);
2213 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2214 if (!is_ok (error)) goto leave;
2218 i += mono_array_length (properties);
2220 i += mono_array_length (fields);
2222 *p++ = (i >> 8) & 0xff;
2225 for (i = 0; i < mono_array_length (properties); ++i) {
2229 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2230 get_prop_name_and_type (prop, &pname, &ptype, error);
2231 if (!is_ok (error)) goto leave;
2232 *p++ = 0x54; /* PROPERTY signature */
2233 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2235 if (!is_ok (error)) goto leave;
2241 for (i = 0; i < mono_array_length (fields); ++i) {
2245 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2246 get_field_name_and_type (field, &fname, &ftype, error);
2247 if (!is_ok (error)) goto leave;
2248 *p++ = 0x53; /* FIELD signature */
2249 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2251 if (!is_ok (error)) goto leave;
2255 g_assert (p - buffer <= buflen);
2256 buflen = p - buffer;
2257 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2260 p = mono_array_addr (result, char, 0);
2261 memcpy (p, buffer, buflen);
2264 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2270 * reflection_setup_internal_class:
2271 * @tb: a TypeBuilder object
2272 * @error: set on error
2274 * Creates a MonoClass that represents the TypeBuilder.
2275 * This is a trick that lets us simplify a lot of reflection code
2276 * (and will allow us to support Build and Run assemblies easier).
2278 * Returns TRUE on success. On failure, returns FALSE and sets @error.
2281 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2283 MonoClass *klass, *parent;
2285 mono_error_init (error);
2287 mono_loader_lock ();
2290 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
2291 if (!is_ok (error)) {
2292 mono_loader_unlock ();
2295 /* check so we can compile corlib correctly */
2296 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
2297 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2298 parent = parent_type->data.klass;
2300 parent = mono_class_from_mono_type (parent_type);
2306 /* the type has already being created: it means we just have to change the parent */
2307 if (tb->type.type) {
2308 klass = mono_class_from_mono_type (tb->type.type);
2309 klass->parent = NULL;
2310 /* fool mono_class_setup_parent */
2311 klass->supertypes = NULL;
2312 mono_class_setup_parent (klass, parent);
2313 mono_class_setup_mono_type (klass);
2314 mono_loader_unlock ();
2319 * The size calculation here warrants some explaining.
2320 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2321 * meaning we need to alloc enough space to morth a def into a gtd.
2323 klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2324 klass->class_kind = MONO_CLASS_DEF;
2326 klass->image = &tb->module->dynamic_image->image;
2328 klass->inited = 1; /* we lie to the runtime */
2329 klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
2332 klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
2335 klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
2336 mono_class_set_flags (klass, tb->attrs);
2338 mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2340 klass->element_class = klass;
2342 if (mono_class_get_ref_info (klass) == NULL) {
2343 mono_class_set_ref_info (klass, tb);
2345 /* Put into cache so mono_class_get_checked () will find it.
2346 Skip nested types as those should not be available on the global scope. */
2347 if (!tb->nesting_type)
2348 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
2351 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2352 by performing a mono_class_get which does the full resolution.
2354 Working around this semantics would require us to write a lot of code for no clear advantage.
2356 mono_image_append_class_to_reflection_info_set (klass);
2358 g_assert (mono_class_get_ref_info (klass) == tb);
2361 mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
2363 if (parent != NULL) {
2364 mono_class_setup_parent (klass, parent);
2365 } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
2366 const char *old_n = klass->name;
2367 /* trick to get relative numbering right when compiling corlib */
2368 klass->name = "BuildingObject";
2369 mono_class_setup_parent (klass, mono_defaults.object_class);
2370 klass->name = old_n;
2373 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2374 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2375 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2376 klass->instance_size = sizeof (MonoObject);
2377 klass->size_inited = 1;
2378 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2381 mono_class_setup_mono_type (klass);
2383 mono_class_setup_supertypes (klass);
2386 * FIXME: handle interfaces.
2389 tb->type.type = &klass->byval_arg;
2391 if (tb->nesting_type) {
2392 reflection_setup_internal_class ((MonoReflectionTypeBuilder*)tb->nesting_type, error);
2393 g_assert (tb->nesting_type->type);
2394 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
2395 if (!is_ok (error)) goto failure;
2396 klass->nested_in = mono_class_from_mono_type (nesting_type);
2399 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2401 mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
2403 mono_loader_unlock ();
2407 mono_loader_unlock ();
2412 * reflection_create_generic_class:
2413 * @tb: a TypeBuilder object
2414 * @error: set on error
2416 * Creates the generic class after all generic parameters have been added.
2417 * On success returns TRUE, on failure returns FALSE and sets @error.
2420 reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2425 mono_error_init (error);
2427 reflection_setup_internal_class (tb, error);
2428 return_val_if_nok (error, FALSE);
2430 klass = mono_class_from_mono_type (tb->type.type);
2432 count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
2437 if (mono_class_try_get_generic_container (klass) != NULL)
2438 return TRUE; /* already setup */
2440 MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2442 generic_container->owner.klass = klass;
2443 generic_container->type_argc = count;
2444 generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2446 klass->class_kind = MONO_CLASS_GTD;
2447 mono_class_set_generic_container (klass, generic_container);
2450 for (i = 0; i < count; i++) {
2451 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
2452 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
2453 return_val_if_nok (error, FALSE);
2454 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2455 generic_container->type_params [i] = *param;
2456 /*Make sure we are a diferent type instance */
2457 generic_container->type_params [i].param.owner = generic_container;
2458 generic_container->type_params [i].info.pklass = NULL;
2459 generic_container->type_params [i].info.flags = gparam->attrs;
2461 g_assert (generic_container->type_params [i].param.owner);
2464 generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2468 static MonoMarshalSpec*
2469 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2470 MonoReflectionMarshal *minfo, MonoError *error)
2472 MonoMarshalSpec *res;
2474 mono_error_init (error);
2476 res = image_g_new0 (image, MonoMarshalSpec, 1);
2477 res->native = (MonoMarshalNative)minfo->type;
2479 switch (minfo->type) {
2480 case MONO_NATIVE_LPARRAY:
2481 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2482 if (minfo->has_size) {
2483 res->data.array_data.param_num = minfo->param_num;
2484 res->data.array_data.num_elem = minfo->count;
2485 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2488 res->data.array_data.param_num = -1;
2489 res->data.array_data.num_elem = -1;
2490 res->data.array_data.elem_mult = -1;
2494 case MONO_NATIVE_BYVALTSTR:
2495 case MONO_NATIVE_BYVALARRAY:
2496 res->data.array_data.num_elem = minfo->count;
2499 case MONO_NATIVE_CUSTOM:
2500 if (minfo->marshaltyperef) {
2501 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2502 if (!is_ok (error)) {
2503 image_g_free (image, res);
2506 res->data.custom_data.custom_name =
2507 type_get_fully_qualified_name (marshaltyperef);
2509 if (minfo->mcookie) {
2510 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2511 if (!is_ok (error)) {
2512 image_g_free (image, res);
2524 #endif /* !DISABLE_REFLECTION_EMIT */
2526 MonoReflectionMarshalAsAttributeHandle
2527 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2528 MonoMarshalSpec *spec, MonoError *error)
2530 mono_error_init (error);
2532 MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
2535 guint32 utype = spec->native;
2536 MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2539 case MONO_NATIVE_LPARRAY:
2540 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2541 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2542 if (spec->data.array_data.param_num != -1)
2543 MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2546 case MONO_NATIVE_BYVALTSTR:
2547 case MONO_NATIVE_BYVALARRAY:
2548 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2551 case MONO_NATIVE_CUSTOM:
2552 if (spec->data.custom_data.custom_name) {
2553 MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2558 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2562 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2565 MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2568 MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2570 if (spec->data.custom_data.cookie) {
2571 MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2574 MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2584 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
2587 #ifndef DISABLE_REFLECTION_EMIT
2589 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2590 ReflectionMethodBuilder *rmb,
2591 MonoMethodSignature *sig,
2595 MonoMethodWrapper *wrapperm;
2596 MonoMarshalSpec **specs;
2597 MonoReflectionMethodAux *method_aux;
2602 mono_error_init (error);
2604 * Methods created using a MethodBuilder should have their memory allocated
2605 * inside the image mempool, while dynamic methods should have their memory
2608 dynamic = rmb->refs != NULL;
2609 image = dynamic ? NULL : klass->image;
2612 g_assert (!mono_class_is_ginst (klass));
2614 mono_loader_lock ();
2616 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2617 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2618 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2620 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
2622 wrapperm = (MonoMethodWrapper*)m;
2624 m->dynamic = dynamic;
2626 m->flags = rmb->attrs;
2627 m->iflags = rmb->iattrs;
2628 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2631 m->sre_method = TRUE;
2632 m->skip_visibility = rmb->skip_visibility;
2634 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2636 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2637 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2640 m->signature->pinvoke = 1;
2641 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2642 m->signature->pinvoke = 1;
2644 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2646 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
2647 mono_error_assert_ok (error);
2648 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
2649 mono_error_assert_ok (error);
2651 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2653 if (image_is_dynamic (klass->image))
2654 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2656 mono_loader_unlock ();
2659 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2660 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2661 MonoMethodHeader *header;
2663 gint32 max_stack, i;
2664 gint32 num_locals = 0;
2665 gint32 num_clauses = 0;
2669 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2670 code_size = rmb->ilgen->code_len;
2671 max_stack = rmb->ilgen->max_stack;
2672 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2673 if (rmb->ilgen->ex_handlers)
2674 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2677 code = mono_array_addr (rmb->code, guint8, 0);
2678 code_size = mono_array_length (rmb->code);
2679 /* we probably need to run a verifier on the code... */
2689 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2690 header->code_size = code_size;
2691 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2692 memcpy ((char*)header->code, code, code_size);
2693 header->max_stack = max_stack;
2694 header->init_locals = rmb->init_locals;
2695 header->num_locals = num_locals;
2697 for (i = 0; i < num_locals; ++i) {
2698 MonoReflectionLocalBuilder *lb =
2699 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2701 header->locals [i] = image_g_new0 (image, MonoType, 1);
2702 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2703 mono_error_assert_ok (error);
2704 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2707 header->num_clauses = num_clauses;
2709 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2710 rmb->ilgen, num_clauses, error);
2711 mono_error_assert_ok (error);
2714 wrapperm->header = header;
2717 if (rmb->generic_params) {
2718 int count = mono_array_length (rmb->generic_params);
2719 MonoGenericContainer *container;
2721 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2722 container->is_method = TRUE;
2723 container->is_anonymous = FALSE;
2724 container->type_argc = count;
2725 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2726 container->owner.method = m;
2728 m->is_generic = TRUE;
2729 mono_method_set_generic_container (m, container);
2731 for (i = 0; i < count; i++) {
2732 MonoReflectionGenericParam *gp =
2733 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2734 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2735 mono_error_assert_ok (error);
2736 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2737 container->type_params [i] = *param;
2738 container->type_params [i].param.owner = container;
2740 gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2742 MonoClass *gklass = mono_class_from_mono_type (gp_type);
2743 gklass->wastypebuilder = TRUE;
2747 * The method signature might have pointers to generic parameters that belong to other methods.
2748 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2749 * generic parameters.
2751 for (i = 0; i < m->signature->param_count; ++i) {
2752 MonoType *t = m->signature->params [i];
2753 if (t->type == MONO_TYPE_MVAR) {
2754 MonoGenericParam *gparam = t->data.generic_param;
2755 if (gparam->num < count) {
2756 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2757 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2763 if (mono_class_is_gtd (klass)) {
2764 container->parent = mono_class_get_generic_container (klass);
2765 container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2767 container->context.method_inst = mono_get_shared_generic_inst (container);
2771 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2775 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2777 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2778 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2779 for (i = 0; i < rmb->nrefs; ++i)
2780 data [i + 1] = rmb->refs [i];
2785 /* Parameter info */
2788 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2789 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2790 for (i = 0; i <= m->signature->param_count; ++i) {
2791 MonoReflectionParamBuilder *pb;
2792 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2793 if ((i > 0) && (pb->attrs)) {
2794 /* Make a copy since it might point to a shared type structure */
2795 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2796 m->signature->params [i - 1]->attrs = pb->attrs;
2799 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2800 MonoDynamicImage *assembly;
2802 MonoTypeEnum def_type;
2806 if (!method_aux->param_defaults) {
2807 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2808 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2810 assembly = (MonoDynamicImage*)klass->image;
2811 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
2812 /* Copy the data from the blob since it might get realloc-ed */
2813 p = assembly->blob.data + idx;
2814 len = mono_metadata_decode_blob_size (p, &p2);
2816 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
2817 method_aux->param_default_types [i] = def_type;
2818 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
2822 method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
2823 mono_error_assert_ok (error);
2826 if (!method_aux->param_cattr)
2827 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
2828 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
2834 /* Parameter marshalling */
2837 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
2838 MonoReflectionParamBuilder *pb;
2839 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2840 if (pb->marshal_info) {
2842 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
2843 specs [pb->position] =
2844 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
2845 if (!is_ok (error)) {
2846 mono_loader_unlock ();
2847 image_g_free (image, specs);
2848 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2854 if (specs != NULL) {
2856 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2857 method_aux->param_marshall = specs;
2860 if (image_is_dynamic (klass->image) && method_aux)
2861 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2863 mono_loader_unlock ();
2869 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
2871 ReflectionMethodBuilder rmb;
2872 MonoMethodSignature *sig;
2874 mono_loader_lock ();
2876 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
2879 g_assert (klass->image != NULL);
2880 sig = ctor_builder_to_signature (klass->image, mb, error);
2881 mono_loader_unlock ();
2882 return_val_if_nok (error, NULL);
2884 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2885 return_val_if_nok (error, NULL);
2886 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2888 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
2889 /* ilgen is no longer needed */
2897 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
2899 ReflectionMethodBuilder rmb;
2900 MonoMethodSignature *sig;
2902 mono_error_init (error);
2904 mono_loader_lock ();
2906 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
2909 g_assert (klass->image != NULL);
2910 sig = method_builder_to_signature (klass->image, mb, error);
2911 mono_loader_unlock ();
2912 return_val_if_nok (error, NULL);
2914 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2915 return_val_if_nok (error, NULL);
2916 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2918 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
2919 /* ilgen is no longer needed */
2925 #ifndef DISABLE_REFLECTION_EMIT
2928 * fix_partial_generic_class:
2929 * @klass: a generic instantiation MonoClass
2930 * @error: set on error
2932 * Assumes that the generic container of @klass has its vtable
2933 * initialized, and updates the parent class, interfaces, methods and
2934 * fields of @klass by inflating the types using the generic context.
2936 * On success returns TRUE, on failure returns FALSE and sets @error.
2940 fix_partial_generic_class (MonoClass *klass, MonoError *error)
2942 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
2945 mono_error_init (error);
2947 if (klass->wastypebuilder)
2950 if (klass->parent != gklass->parent) {
2951 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
2952 if (mono_error_ok (error)) {
2953 MonoClass *parent = mono_class_from_mono_type (parent_type);
2954 mono_metadata_free_type (parent_type);
2955 if (parent != klass->parent) {
2956 /*fool mono_class_setup_parent*/
2957 klass->supertypes = NULL;
2958 mono_class_setup_parent (klass, parent);
2961 if (gklass->wastypebuilder)
2962 klass->wastypebuilder = TRUE;
2967 if (!mono_class_get_generic_class (klass)->need_sync)
2970 int mcount = mono_class_get_method_count (klass);
2971 int gmcount = mono_class_get_method_count (gklass);
2972 if (mcount != gmcount) {
2973 mono_class_set_method_count (klass, gmcount);
2974 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
2976 for (i = 0; i < gmcount; i++) {
2977 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
2978 gklass->methods [i], klass, mono_class_get_context (klass), error);
2979 mono_error_assert_ok (error);
2983 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
2984 klass->interface_count = gklass->interface_count;
2985 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
2986 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
2988 for (i = 0; i < gklass->interface_count; ++i) {
2989 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
2990 return_val_if_nok (error, FALSE);
2992 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
2993 mono_metadata_free_type (iface_type);
2995 if (!ensure_runtime_vtable (klass->interfaces [i], error))
2998 klass->interfaces_inited = 1;
3001 int fcount = mono_class_get_field_count (klass);
3002 int gfcount = mono_class_get_field_count (gklass);
3003 if (fcount != gfcount) {
3004 mono_class_set_field_count (klass, gfcount);
3005 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3007 for (i = 0; i < gfcount; i++) {
3008 klass->fields [i] = gklass->fields [i];
3009 klass->fields [i].parent = klass;
3010 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3011 return_val_if_nok (error, FALSE);
3015 /*We can only finish with this klass once it's parent has as well*/
3016 if (gklass->wastypebuilder)
3017 klass->wastypebuilder = TRUE;
3022 * ensure_generic_class_runtime_vtable:
3023 * @klass a generic class
3024 * @error set on error
3026 * Ensures that the generic container of @klass has a vtable and
3027 * returns TRUE on success. On error returns FALSE and sets @error.
3030 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3032 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3034 mono_error_init (error);
3036 if (!ensure_runtime_vtable (gklass, error))
3039 return fix_partial_generic_class (klass, error);
3043 * ensure_runtime_vtable:
3045 * @error set on error
3047 * Ensures that @klass has a vtable and returns TRUE on success. On
3048 * error returns FALSE and sets @error.
3051 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3053 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3056 mono_error_init (error);
3058 if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3061 if (!ensure_runtime_vtable (klass->parent, error))
3065 num = tb->ctors? mono_array_length (tb->ctors): 0;
3066 num += tb->num_methods;
3067 mono_class_set_method_count (klass, num);
3068 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3069 num = tb->ctors? mono_array_length (tb->ctors): 0;
3070 for (i = 0; i < num; ++i) {
3071 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3074 klass->methods [i] = ctor;
3076 num = tb->num_methods;
3078 for (i = 0; i < num; ++i) {
3079 MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3082 klass->methods [j++] = meth;
3085 if (tb->interfaces) {
3086 klass->interface_count = mono_array_length (tb->interfaces);
3087 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3088 for (i = 0; i < klass->interface_count; ++i) {
3089 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3090 return_val_if_nok (error, FALSE);
3091 klass->interfaces [i] = mono_class_from_mono_type (iface);
3092 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3095 klass->interfaces_inited = 1;
3097 } else if (mono_class_is_ginst (klass)){
3098 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3099 mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3104 if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3106 int mcount = mono_class_get_method_count (klass);
3107 for (i = 0; i < mcount; ++i) {
3108 MonoMethod *im = klass->methods [i];
3109 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3110 im->slot = slot_num++;
3113 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3114 mono_class_setup_interface_offsets (klass);
3115 mono_class_setup_interface_id (klass);
3119 * The generic vtable is needed even if image->run is not set since some
3120 * runtime code like ves_icall_Type_GetMethodsByName depends on
3121 * method->slot being defined.
3125 * tb->methods could not be freed since it is used for determining
3126 * overrides during dynamic vtable construction.
3133 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3135 mono_error_init (error);
3136 MonoClass *klass = mono_object_class (method);
3137 if (is_sr_mono_method (klass)) {
3138 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3139 return sr_method->method;
3141 if (is_sre_method_builder (klass)) {
3142 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3145 if (mono_is_sre_method_on_tb_inst (klass)) {
3146 MonoClass *handle_class;
3148 MonoMethod *result = mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3149 return_val_if_nok (error, NULL);
3154 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3159 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3161 MonoReflectionTypeBuilder *tb;
3163 MonoReflectionMethod *m;
3165 mono_error_init (error);
3169 g_assert (image_is_dynamic (klass->image));
3171 if (!mono_class_get_ref_info (klass))
3174 g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
3176 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
3180 for (i = 0; i < tb->num_methods; ++i) {
3181 MonoReflectionMethodBuilder *mb =
3182 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3183 if (mb->override_methods)
3184 onum += mono_array_length (mb->override_methods);
3189 *overrides = g_new0 (MonoMethod*, onum * 2);
3192 for (i = 0; i < tb->num_methods; ++i) {
3193 MonoReflectionMethodBuilder *mb =
3194 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3195 if (mb->override_methods) {
3196 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3197 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3199 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3200 return_if_nok (error);
3201 (*overrides) [onum * 2 + 1] = mb->mhandle;
3203 g_assert (mb->mhandle);
3211 *num_overrides = onum;
3214 /* This initializes the same data as mono_class_setup_fields () */
3216 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3218 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3219 MonoReflectionFieldBuilder *fb;
3220 MonoClassField *field;
3221 MonoFieldDefaultValue *def_values;
3222 MonoImage *image = klass->image;
3224 int i, instance_size, packing_size = 0;
3227 if (klass->parent) {
3228 if (!klass->parent->size_inited)
3229 mono_class_init (klass->parent);
3230 instance_size = klass->parent->instance_size;
3232 instance_size = sizeof (MonoObject);
3235 int fcount = tb->num_fields;
3236 mono_class_set_field_count (klass, fcount);
3238 mono_error_init (error);
3240 if (tb->class_size) {
3241 packing_size = tb->packing_size;
3242 instance_size += tb->class_size;
3245 klass->fields = image_g_new0 (image, MonoClassField, fcount);
3246 def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3247 mono_class_set_field_def_values (klass, def_values);
3249 This is, guess what, a hack.
3250 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3251 On the static path no field class is resolved, only types are built. This is the right thing to do
3253 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3255 klass->size_inited = 1;
3257 for (i = 0; i < fcount; ++i) {
3258 MonoArray *rva_data;
3259 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3260 field = &klass->fields [i];
3261 field->parent = klass;
3262 field->name = mono_string_to_utf8_image (image, fb->name, error);
3263 if (!mono_error_ok (error))
3266 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3267 return_if_nok (error);
3268 field->type = mono_metadata_type_dup (klass->image, type);
3269 field->type->attrs = fb->attrs;
3271 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3272 return_if_nok (error);
3275 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3276 char *base = mono_array_addr (rva_data, char, 0);
3277 size_t size = mono_array_length (rva_data);
3278 char *data = (char *)mono_image_alloc (klass->image, size);
3279 memcpy (data, base, size);
3280 def_values [i].data = data;
3282 if (fb->offset != -1)
3283 field->offset = fb->offset;
3285 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3287 if (fb->def_value) {
3288 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3289 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3290 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3291 /* Copy the data from the blob since it might get realloc-ed */
3292 p = assembly->blob.data + idx;
3293 len = mono_metadata_decode_blob_size (p, &p2);
3295 def_values [i].data = (const char *)mono_image_alloc (image, len);
3296 memcpy ((gpointer)def_values [i].data, p, len);
3300 mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3304 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3306 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3307 MonoReflectionPropertyBuilder *pb;
3308 MonoImage *image = klass->image;
3309 MonoProperty *properties;
3310 MonoClassPropertyInfo *info;
3313 mono_error_init (error);
3315 info = mono_class_get_property_info (klass);
3317 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3318 mono_class_set_property_info (klass, info);
3321 info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3324 properties = image_g_new0 (image, MonoProperty, info->count);
3325 info->properties = properties;
3326 for (i = 0; i < info->count; ++i) {
3327 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3328 properties [i].parent = klass;
3329 properties [i].attrs = pb->attrs;
3330 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
3331 if (!mono_error_ok (error))
3334 properties [i].get = pb->get_method->mhandle;
3336 properties [i].set = pb->set_method->mhandle;
3338 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3339 if (pb->def_value) {
3342 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3343 if (!info->def_values)
3344 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3345 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3346 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3347 /* Copy the data from the blob since it might get realloc-ed */
3348 p = assembly->blob.data + idx;
3349 len = mono_metadata_decode_blob_size (p, &p2);
3351 info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3352 memcpy ((gpointer)info->def_values [i].data, p, len);
3358 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3360 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3361 MonoReflectionEventBuilder *eb;
3362 MonoImage *image = klass->image;
3364 MonoClassEventInfo *info;
3367 mono_error_init (error);
3369 info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3370 mono_class_set_event_info (klass, info);
3372 info->count = tb->events ? mono_array_length (tb->events) : 0;
3375 events = image_g_new0 (image, MonoEvent, info->count);
3376 info->events = events;
3377 for (i = 0; i < info->count; ++i) {
3378 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3379 events [i].parent = klass;
3380 events [i].attrs = eb->attrs;
3381 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
3382 if (!mono_error_ok (error))
3385 events [i].add = eb->add_method->mhandle;
3386 if (eb->remove_method)
3387 events [i].remove = eb->remove_method->mhandle;
3388 if (eb->raise_method)
3389 events [i].raise = eb->raise_method->mhandle;
3391 #ifndef MONO_SMALL_CONFIG
3392 if (eb->other_methods) {
3394 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3395 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3396 MonoReflectionMethodBuilder *mb =
3397 mono_array_get (eb->other_methods,
3398 MonoReflectionMethodBuilder*, j);
3399 events [i].other [j] = mb->mhandle;
3403 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3407 struct remove_instantiations_user_data
3414 remove_instantiations_of_and_ensure_contents (gpointer key,
3418 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3419 MonoType *type = (MonoType*)key;
3420 MonoClass *klass = data->klass;
3421 gboolean already_failed = !is_ok (data->error);
3423 MonoError *error = already_failed ? &lerror : data->error;
3425 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3426 MonoClass *inst_klass = mono_class_from_mono_type (type);
3427 //Ensure it's safe to use it.
3428 if (!fix_partial_generic_class (inst_klass, error)) {
3429 mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3430 // Marked the class with failure, but since some other instantiation already failed,
3431 // just report that one, and swallow the error from this one.
3433 mono_error_cleanup (error);
3441 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
3446 MonoReflectionType* res;
3449 mono_error_init (&error);
3451 reflection_create_generic_class (tb, &error);
3452 mono_error_assert_ok (&error);
3454 domain = mono_object_domain (tb);
3455 klass = mono_class_from_mono_type (tb->type.type);
3457 mono_save_custom_attrs (klass->image, klass, tb->cattrs);
3460 * we need to lock the domain because the lock will be taken inside
3461 * So, we need to keep the locking order correct.
3463 mono_loader_lock ();
3464 mono_domain_lock (domain);
3465 if (klass->wastypebuilder) {
3466 mono_domain_unlock (domain);
3467 mono_loader_unlock ();
3469 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3470 mono_error_set_pending_exception (&error);
3475 * Fields to set in klass:
3476 * the various flags: delegate/unicode/contextbound etc.
3478 mono_class_set_flags (klass, tb->attrs);
3479 klass->has_cctor = 1;
3481 mono_class_setup_parent (klass, klass->parent);
3482 /* fool mono_class_setup_supertypes */
3483 klass->supertypes = NULL;
3484 mono_class_setup_supertypes (klass);
3485 mono_class_setup_mono_type (klass);
3487 /* enums are done right away */
3488 if (!klass->enumtype)
3489 if (!ensure_runtime_vtable (klass, &error))
3493 GList *nested = NULL;
3494 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3495 MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
3497 if (!subtb->type.type) {
3498 reflection_setup_internal_class (subtb, &error);
3499 mono_error_assert_ok (&error);
3502 MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
3503 if (!is_ok (&error)) goto failure;
3504 nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3506 mono_class_set_nested_classes_property (klass, nested);
3509 klass->nested_classes_inited = TRUE;
3511 typebuilder_setup_fields (klass, &error);
3512 if (!mono_error_ok (&error))
3514 typebuilder_setup_properties (klass, &error);
3515 if (!mono_error_ok (&error))
3518 typebuilder_setup_events (klass, &error);
3519 if (!mono_error_ok (&error))
3522 klass->wastypebuilder = TRUE;
3524 if (tb->generic_params) {
3525 for (i = 0; i < mono_array_length (tb->generic_params); i++) {
3526 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3527 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error);
3528 MonoClass *gklass = mono_class_from_mono_type (param_type);
3530 gklass->wastypebuilder = TRUE;
3535 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3536 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3537 * we want to return normal System.MonoType objects, so clear these out from the cache.
3539 * Together with this we must ensure the contents of all instances to match the created type.
3541 if (domain->type_hash && mono_class_is_gtd (klass)) {
3542 struct remove_instantiations_user_data data;
3544 data.error = &error;
3545 mono_error_assert_ok (&error);
3546 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3547 if (!is_ok (&error))
3551 mono_domain_unlock (domain);
3552 mono_loader_unlock ();
3554 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3555 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3556 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
3557 goto failure_unlocked;
3560 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3561 if (!is_ok (&error))
3562 goto failure_unlocked;
3564 g_assert (res != (MonoReflectionType*)tb);
3569 mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
3570 klass->wastypebuilder = TRUE;
3571 mono_domain_unlock (domain);
3572 mono_loader_unlock ();
3574 mono_error_set_pending_exception (&error);
3581 } DynamicMethodReleaseData;
3584 * The runtime automatically clean up those after finalization.
3586 static MonoReferenceQueue *dynamic_method_queue;
3589 free_dynamic_method (void *dynamic_method)
3591 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3592 MonoDomain *domain = data->domain;
3593 MonoMethod *method = data->handle;
3596 mono_domain_lock (domain);
3597 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3598 g_hash_table_remove (domain->method_to_dyn_method, method);
3599 mono_domain_unlock (domain);
3600 g_assert (dis_link);
3601 mono_gchandle_free (dis_link);
3603 mono_runtime_free_method (domain, method);
3608 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
3610 MonoReferenceQueue *queue;
3612 DynamicMethodReleaseData *release_data;
3613 ReflectionMethodBuilder rmb;
3614 MonoMethodSignature *sig;
3620 mono_error_init (error);
3622 if (mono_runtime_is_shutting_down ()) {
3623 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3627 if (!(queue = dynamic_method_queue)) {
3628 mono_loader_lock ();
3629 if (!(queue = dynamic_method_queue))
3630 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3631 mono_loader_unlock ();
3634 sig = dynamic_method_to_signature (mb, error);
3635 return_val_if_nok (error, FALSE);
3637 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3640 * Resolve references.
3643 * Every second entry in the refs array is reserved for storing handle_class,
3644 * which is needed by the ldtoken implementation in the JIT.
3646 rmb.nrefs = mb->nrefs;
3647 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3648 for (i = 0; i < mb->nrefs; i += 2) {
3649 MonoClass *handle_class;
3651 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3653 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3654 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3656 * The referenced DynamicMethod should already be created by the managed
3657 * code, except in the case of circular references. In that case, we store
3658 * method in the refs array, and fix it up later when the referenced
3659 * DynamicMethod is created.
3661 if (method->mhandle) {
3662 ref = method->mhandle;
3664 /* FIXME: GC object stored in unmanaged memory */
3667 /* FIXME: GC object stored in unmanaged memory */
3668 method->referenced_by = g_slist_append (method->referenced_by, mb);
3670 handle_class = mono_defaults.methodhandle_class;
3672 MonoException *ex = NULL;
3673 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3674 if (!is_ok (error)) {
3679 ex = mono_get_exception_type_load (NULL, NULL);
3680 else if (mono_security_core_clr_enabled ())
3681 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3685 mono_error_set_exception_instance (error, ex);
3690 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3691 rmb.refs [i + 1] = handle_class;
3695 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3696 if (!is_ok (error)) {
3700 klass = mono_class_from_mono_type (owner_type);
3702 klass = mono_defaults.object_class;
3705 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3707 return_val_if_nok (error, FALSE);
3709 release_data = g_new (DynamicMethodReleaseData, 1);
3710 release_data->handle = handle;
3711 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3712 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3713 g_free (release_data);
3715 /* Fix up refs entries pointing at us */
3716 for (l = mb->referenced_by; l; l = l->next) {
3717 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3718 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3721 g_assert (method->mhandle);
3723 data = (gpointer*)wrapper->method_data;
3724 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3725 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3726 data [i + 1] = mb->mhandle;
3729 g_slist_free (mb->referenced_by);
3731 /* ilgen is no longer needed */
3734 domain = mono_domain_get ();
3735 mono_domain_lock (domain);
3736 if (!domain->method_to_dyn_method)
3737 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3738 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3739 mono_domain_unlock (domain);
3745 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
3748 (void) reflection_create_dynamic_method (mb, &error);
3749 mono_error_set_pending_exception (&error);
3752 #endif /* DISABLE_REFLECTION_EMIT */
3754 MonoMethodSignature *
3755 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3757 MonoMethodSignature *sig;
3758 g_assert (image_is_dynamic (image));
3760 mono_error_init (error);
3762 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
3766 return mono_method_signature_checked (method, error);
3769 #ifndef DISABLE_REFLECTION_EMIT
3772 * ensure_complete_type:
3774 * Ensure that KLASS is completed if it is a dynamic type, or references
3778 ensure_complete_type (MonoClass *klass, MonoError *error)
3780 mono_error_init (error);
3782 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
3783 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3785 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3786 return_if_nok (error);
3788 // Asserting here could break a lot of code
3789 //g_assert (klass->wastypebuilder);
3792 if (mono_class_is_ginst (klass)) {
3793 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
3796 for (i = 0; i < inst->type_argc; ++i) {
3797 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
3798 return_if_nok (error);
3804 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
3806 MonoClass *oklass = obj->vtable->klass;
3807 gpointer result = NULL;
3809 mono_error_init (error);
3811 if (strcmp (oklass->name, "String") == 0) {
3812 result = mono_string_intern_checked ((MonoString*)obj, error);
3813 return_val_if_nok (error, NULL);
3814 *handle_class = mono_defaults.string_class;
3816 } else if (strcmp (oklass->name, "RuntimeType") == 0) {
3817 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
3818 return_val_if_nok (error, NULL);
3819 MonoClass *mc = mono_class_from_mono_type (type);
3820 if (!mono_class_init (mc)) {
3821 mono_error_set_for_class_failure (error, mc);
3826 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
3827 return_val_if_nok (error, NULL);
3829 result = mono_class_from_mono_type (inflated);
3830 mono_metadata_free_type (inflated);
3832 result = mono_class_from_mono_type (type);
3834 *handle_class = mono_defaults.typehandle_class;
3836 } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
3837 strcmp (oklass->name, "MonoCMethod") == 0) {
3838 result = ((MonoReflectionMethod*)obj)->method;
3840 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
3841 mono_error_assert_ok (error);
3843 *handle_class = mono_defaults.methodhandle_class;
3845 } else if (strcmp (oklass->name, "MonoField") == 0) {
3846 MonoClassField *field = ((MonoReflectionField*)obj)->field;
3848 ensure_complete_type (field->parent, error);
3849 return_val_if_nok (error, NULL);
3852 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
3853 return_val_if_nok (error, NULL);
3855 MonoClass *klass = mono_class_from_mono_type (inflated);
3856 MonoClassField *inflated_field;
3857 gpointer iter = NULL;
3858 mono_metadata_free_type (inflated);
3859 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
3860 if (!strcmp (field->name, inflated_field->name))
3863 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
3864 result = inflated_field;
3868 *handle_class = mono_defaults.fieldhandle_class;
3870 } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
3871 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
3872 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3873 return_val_if_nok (error, NULL);
3876 klass = type->data.klass;
3877 if (klass->wastypebuilder) {
3878 /* Already created */
3882 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3883 return_val_if_nok (error, NULL);
3884 result = type->data.klass;
3887 *handle_class = mono_defaults.typehandle_class;
3888 } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
3889 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
3890 MonoMethodSignature *sig;
3893 if (helper->arguments)
3894 nargs = mono_array_length (helper->arguments);
3898 sig = mono_metadata_signature_alloc (image, nargs);
3899 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
3900 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
3902 if (helper->unmanaged_call_conv) { /* unmanaged */
3903 sig->call_convention = helper->unmanaged_call_conv - 1;
3904 sig->pinvoke = TRUE;
3905 } else if (helper->call_conv & 0x02) {
3906 sig->call_convention = MONO_CALL_VARARG;
3908 sig->call_convention = MONO_CALL_DEFAULT;
3911 sig->param_count = nargs;
3912 /* TODO: Copy type ? */
3913 sig->ret = helper->return_type->type;
3914 for (i = 0; i < nargs; ++i) {
3915 sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
3916 if (!is_ok (error)) {
3917 image_g_free (image, sig);
3923 *handle_class = NULL;
3924 } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
3925 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3926 /* Already created by the managed code */
3927 g_assert (method->mhandle);
3928 result = method->mhandle;
3929 *handle_class = mono_defaults.methodhandle_class;
3930 } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
3931 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
3938 mtype = mono_reflection_type_get_handle (m->parent, error);
3939 return_val_if_nok (error, NULL);
3940 klass = mono_class_from_mono_type (mtype);
3942 /* Find the method */
3944 name = mono_string_to_utf8_checked (m->name, error);
3945 return_val_if_nok (error, NULL);
3947 while ((method = mono_class_get_methods (klass, &iter))) {
3948 if (!strcmp (method->name, name))
3955 // FIXME: Check parameters/return value etc. match
3958 *handle_class = mono_defaults.methodhandle_class;
3959 } else if (is_sre_method_builder (oklass) ||
3960 mono_is_sre_ctor_builder (oklass) ||
3961 is_sre_field_builder (oklass) ||
3962 is_sre_gparam_builder (oklass) ||
3963 is_sre_generic_instance (oklass) ||
3964 is_sre_array (oklass) ||
3965 is_sre_byref (oklass) ||
3966 is_sre_pointer (oklass) ||
3967 !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
3968 !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
3969 !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
3970 static MonoMethod *resolve_method;
3971 if (!resolve_method) {
3972 MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
3974 mono_memory_barrier ();
3979 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
3980 mono_error_assert_ok (error);
3982 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
3984 g_print ("%s\n", obj->vtable->klass->name);
3985 g_assert_not_reached ();
3990 #else /* DISABLE_REFLECTION_EMIT */
3993 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
3995 g_assert_not_reached ();
4000 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4002 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4006 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
4008 g_assert_not_reached ();
4012 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
4014 g_assert_not_reached ();
4019 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
4021 g_assert_not_reached ();
4026 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
4027 gboolean create_open_instance, gboolean register_token, MonoError *error)
4029 g_assert_not_reached ();
4034 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4036 mono_error_init (error);
4042 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4044 g_assert_not_reached ();
4049 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4054 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4056 mono_error_init (error);
4062 #endif /* DISABLE_REFLECTION_EMIT */
4065 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4067 mono_gc_deregister_root ((char*) &entry->gparam);
4072 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
4074 MONO_CHECK_ARG_NULL (obj, 0);
4077 gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
4078 mono_error_set_pending_exception (&error);
4083 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
4084 MonoReflectionMethod *method,
4085 MonoArray *opt_param_types)
4087 MONO_CHECK_ARG_NULL (method, 0);
4090 gint32 result = mono_image_create_method_token (
4091 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
4092 mono_error_set_pending_exception (&error);
4097 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4100 mono_image_create_pefile (mb, file, &error);
4101 mono_error_set_pending_exception (&error);
4105 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4108 mono_image_build_metadata (mb, &error);
4109 mono_error_set_pending_exception (&error);
4113 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
4115 mono_image_register_token (mb->dynamic_image, token, obj);
4119 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
4123 mono_loader_lock ();
4124 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
4125 mono_loader_unlock ();
4130 #ifndef DISABLE_REFLECTION_EMIT
4132 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4135 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4136 mono_error_set_pending_exception (&error);
4142 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4144 mono_reflection_dynimage_basic_init (assemblyb);
4148 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
4149 MonoReflectionType *t)
4151 enumtype->type = t->type;
4155 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
4157 mono_image_module_basic_init (moduleb);
4161 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
4163 return mono_image_insert_string (module, str);
4167 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
4169 MonoDynamicImage *image = moduleb->dynamic_image;
4171 g_assert (type->type);
4172 image->wrappers_type = mono_class_from_mono_type (type->type);