2 * sre.c: Routines for creating an image at runtime
3 * and related System.Reflection.Emit icalls
7 * Paolo Molaro (lupus@ximian.com)
9 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
11 * Copyright 2011 Rodrigo Kumpera
12 * Copyright 2016 Microsoft
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
18 #include "mono/metadata/assembly.h"
19 #include "mono/metadata/debug-helpers.h"
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/exception.h"
23 #include "mono/metadata/gc-internals.h"
24 #include "mono/metadata/mono-ptr-array.h"
25 #include "mono/metadata/object-internals.h"
26 #include "mono/metadata/profiler-private.h"
27 #include "mono/metadata/reflection-internals.h"
28 #include "mono/metadata/reflection-cache.h"
29 #include "mono/metadata/sre-internals.h"
30 #include "mono/metadata/custom-attrs-internals.h"
31 #include "mono/metadata/security-manager.h"
32 #include "mono/metadata/security-core-clr.h"
33 #include "mono/metadata/tabledefs.h"
34 #include "mono/metadata/tokentype.h"
35 #include "mono/utils/checked-build.h"
36 #include "mono/utils/mono-digest.h"
39 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
41 mono_gc_deregister_root ((char*) &entry->gparam);
45 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
46 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder);
48 #ifndef DISABLE_REFLECTION_EMIT
49 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
50 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
51 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
52 static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
53 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
55 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
58 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
59 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
60 static gboolean is_sre_array (MonoClass *klass);
61 static gboolean is_sre_byref (MonoClass *klass);
62 static gboolean is_sre_pointer (MonoClass *klass);
63 static gboolean is_sre_generic_instance (MonoClass *klass);
64 static gboolean is_sre_type_builder (MonoClass *klass);
65 static gboolean is_sre_method_builder (MonoClass *klass);
66 static gboolean is_sre_field_builder (MonoClass *klass);
67 static gboolean is_sre_gparam_builder (MonoClass *klass);
68 static gboolean is_sr_mono_method (MonoClass *klass);
69 static gboolean is_sr_mono_field (MonoClass *klass);
71 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
72 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
74 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
76 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
79 mono_reflection_emit_init (void)
81 mono_dynamic_images_init ();
85 type_get_fully_qualified_name (MonoType *type)
87 MONO_REQ_GC_NEUTRAL_MODE;
89 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
93 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
95 MONO_REQ_GC_UNSAFE_MODE;
100 klass = mono_class_from_mono_type (type);
102 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
103 ta = klass->image->assembly;
104 if (assembly_is_dynamic (ta) || (ta == ass)) {
105 if (klass->generic_class || klass->generic_container)
106 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
107 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
109 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
112 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
115 #ifndef DISABLE_REFLECTION_EMIT
119 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
123 image_g_malloc (MonoImage *image, guint size)
125 MONO_REQ_GC_NEUTRAL_MODE;
128 return mono_image_alloc (image, size);
130 return g_malloc (size);
132 #endif /* !DISABLE_REFLECTION_EMIT */
137 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
141 mono_image_g_malloc0 (MonoImage *image, guint size)
143 MONO_REQ_GC_NEUTRAL_MODE;
146 return mono_image_alloc0 (image, size);
148 return g_malloc0 (size);
153 * @image: a MonoImage
156 * If @image is NULL, free @ptr, otherwise do nothing.
159 image_g_free (MonoImage *image, gpointer ptr)
165 #ifndef DISABLE_REFLECTION_EMIT
167 image_strdup (MonoImage *image, const char *s)
169 MONO_REQ_GC_NEUTRAL_MODE;
172 return mono_image_strdup (image, s);
178 #define image_g_new(image,struct_type, n_structs) \
179 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
181 #define image_g_new0(image,struct_type, n_structs) \
182 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
186 alloc_table (MonoDynamicTable *table, guint nrows)
188 mono_dynimage_alloc_table (table, nrows);
192 string_heap_insert (MonoDynamicStream *sh, const char *str)
194 return mono_dynstream_insert_string (sh, str);
198 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
200 return mono_dynstream_add_data (stream, data, len);
204 * Despite the name, we handle also TypeSpec (with the above helper).
207 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
209 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
213 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
214 * dest may be misaligned.
217 swap_with_size (char *dest, const char* val, int len, int nelem) {
218 MONO_REQ_GC_NEUTRAL_MODE;
219 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
222 for (elem = 0; elem < nelem; ++elem) {
248 g_assert_not_reached ();
254 memcpy (dest, val, len * nelem);
259 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
261 MONO_REQ_GC_UNSAFE_MODE;
263 guint32 num_clauses = 0;
266 MonoILExceptionInfo *ex_info;
267 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
268 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
269 if (ex_info->handlers)
270 num_clauses += mono_array_length (ex_info->handlers);
278 #ifndef DISABLE_REFLECTION_EMIT
279 static MonoExceptionClause*
280 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
282 MONO_REQ_GC_UNSAFE_MODE;
284 mono_error_init (error);
286 MonoExceptionClause *clauses;
287 MonoExceptionClause *clause;
288 MonoILExceptionInfo *ex_info;
289 MonoILExceptionBlock *ex_block;
290 guint32 finally_start;
291 int i, j, clause_index;;
293 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
296 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
297 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
298 finally_start = ex_info->start + ex_info->len;
299 if (!ex_info->handlers)
301 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
302 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
303 clause = &(clauses [clause_index]);
305 clause->flags = ex_block->type;
306 clause->try_offset = ex_info->start;
308 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
309 clause->try_len = finally_start - ex_info->start;
311 clause->try_len = ex_info->len;
312 clause->handler_offset = ex_block->start;
313 clause->handler_len = ex_block->len;
314 if (ex_block->extype) {
315 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
317 if (!is_ok (error)) {
318 image_g_free (image, clauses);
321 clause->data.catch_class = mono_class_from_mono_type (extype);
323 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
324 clause->data.filter_offset = ex_block->filter_offset;
326 clause->data.filter_offset = 0;
328 finally_start = ex_block->start + ex_block->len;
336 #endif /* !DISABLE_REFLECTION_EMIT */
338 #ifndef DISABLE_REFLECTION_EMIT
340 * LOCKING: Acquires the loader lock.
343 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
345 MONO_REQ_GC_UNSAFE_MODE;
347 MonoCustomAttrInfo *ainfo, *tmp;
349 if (!cattrs || !mono_array_length (cattrs))
352 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
355 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
357 mono_custom_attrs_free (tmp);
358 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
359 mono_loader_unlock ();
366 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
368 MONO_REQ_GC_UNSAFE_MODE;
370 MonoDynamicTable *table;
373 guint32 cols [MONO_ASSEMBLY_SIZE];
377 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
380 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
381 table = &assembly->tables [MONO_TABLE_MODULEREF];
382 token = table->next_idx ++;
384 alloc_table (table, table->rows);
385 values = table->values + token * MONO_MODULEREF_SIZE;
386 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
388 token <<= MONO_RESOLUTION_SCOPE_BITS;
389 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
390 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
395 if (assembly_is_dynamic (image->assembly))
397 memset (cols, 0, sizeof (cols));
399 /* image->assembly->image is the manifest module */
400 image = image->assembly->image;
401 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
404 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
405 token = table->next_idx ++;
407 alloc_table (table, table->rows);
408 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
409 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
410 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
411 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
412 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
413 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
414 values [MONO_ASSEMBLYREF_FLAGS] = 0;
415 values [MONO_ASSEMBLYREF_CULTURE] = 0;
416 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
418 if (strcmp ("", image->assembly->aname.culture)) {
419 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
420 image->assembly->aname.culture);
423 if ((pubkey = mono_image_get_public_key (image, &publen))) {
426 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
427 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
429 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
431 token <<= MONO_RESOLUTION_SCOPE_BITS;
432 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
433 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
437 #ifndef DISABLE_REFLECTION_EMIT
439 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
441 MONO_REQ_GC_UNSAFE_MODE;
443 mono_error_init (error);
444 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
446 rmb->ilgen = mb->ilgen;
447 rmb->rtype = (MonoReflectionType*)mb->rtype;
448 return_val_if_nok (error, FALSE);
449 rmb->parameters = mb->parameters;
450 rmb->generic_params = mb->generic_params;
451 rmb->generic_container = mb->generic_container;
452 rmb->opt_types = NULL;
453 rmb->pinfo = mb->pinfo;
454 rmb->attrs = mb->attrs;
455 rmb->iattrs = mb->iattrs;
456 rmb->call_conv = mb->call_conv;
457 rmb->code = mb->code;
458 rmb->type = mb->type;
459 rmb->name = mb->name;
460 rmb->table_idx = &mb->table_idx;
461 rmb->init_locals = mb->init_locals;
462 rmb->skip_visibility = FALSE;
463 rmb->return_modreq = mb->return_modreq;
464 rmb->return_modopt = mb->return_modopt;
465 rmb->param_modreq = mb->param_modreq;
466 rmb->param_modopt = mb->param_modopt;
467 rmb->permissions = mb->permissions;
468 rmb->mhandle = mb->mhandle;
473 rmb->charset = mb->charset;
474 rmb->extra_flags = mb->extra_flags;
475 rmb->native_cc = mb->native_cc;
476 rmb->dllentry = mb->dllentry;
484 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
486 MONO_REQ_GC_UNSAFE_MODE;
488 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
490 mono_error_init (error);
492 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
494 rmb->ilgen = mb->ilgen;
495 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
496 return_val_if_nok (error, FALSE);
497 rmb->parameters = mb->parameters;
498 rmb->generic_params = NULL;
499 rmb->generic_container = NULL;
500 rmb->opt_types = NULL;
501 rmb->pinfo = mb->pinfo;
502 rmb->attrs = mb->attrs;
503 rmb->iattrs = mb->iattrs;
504 rmb->call_conv = mb->call_conv;
506 rmb->type = mb->type;
507 rmb->name = mono_string_new (mono_domain_get (), name);
508 rmb->table_idx = &mb->table_idx;
509 rmb->init_locals = mb->init_locals;
510 rmb->skip_visibility = FALSE;
511 rmb->return_modreq = NULL;
512 rmb->return_modopt = NULL;
513 rmb->param_modreq = mb->param_modreq;
514 rmb->param_modopt = mb->param_modopt;
515 rmb->permissions = mb->permissions;
516 rmb->mhandle = mb->mhandle;
524 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
526 MONO_REQ_GC_UNSAFE_MODE;
528 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
530 rmb->ilgen = mb->ilgen;
531 rmb->rtype = mb->rtype;
532 rmb->parameters = mb->parameters;
533 rmb->generic_params = NULL;
534 rmb->generic_container = NULL;
535 rmb->opt_types = NULL;
537 rmb->attrs = mb->attrs;
539 rmb->call_conv = mb->call_conv;
541 rmb->type = (MonoObject *) mb->owner;
542 rmb->name = mb->name;
543 rmb->table_idx = NULL;
544 rmb->init_locals = mb->init_locals;
545 rmb->skip_visibility = mb->skip_visibility;
546 rmb->return_modreq = NULL;
547 rmb->return_modopt = NULL;
548 rmb->param_modreq = NULL;
549 rmb->param_modopt = NULL;
550 rmb->permissions = NULL;
551 rmb->mhandle = mb->mhandle;
555 #else /* DISABLE_REFLECTION_EMIT */
557 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
558 g_assert_not_reached ();
562 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
564 g_assert_not_reached ();
567 #endif /* DISABLE_REFLECTION_EMIT */
569 #ifndef DISABLE_REFLECTION_EMIT
571 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
573 MONO_REQ_GC_NEUTRAL_MODE;
575 MonoDynamicTable *table;
577 guint32 token, pclass;
579 switch (parent & MONO_TYPEDEFORREF_MASK) {
580 case MONO_TYPEDEFORREF_TYPEREF:
581 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
583 case MONO_TYPEDEFORREF_TYPESPEC:
584 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
586 case MONO_TYPEDEFORREF_TYPEDEF:
587 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
590 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
593 /* extract the index */
594 parent >>= MONO_TYPEDEFORREF_BITS;
596 table = &assembly->tables [MONO_TABLE_MEMBERREF];
598 if (assembly->save) {
599 alloc_table (table, table->rows + 1);
600 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
601 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
602 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
603 values [MONO_MEMBERREF_SIGNATURE] = sig;
606 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
613 * Insert a memberef row into the metadata: the token that point to the memberref
614 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
615 * mono_image_get_fieldref_token()).
616 * The sig param is an index to an already built signature.
619 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
621 MONO_REQ_GC_NEUTRAL_MODE;
623 guint32 parent = mono_image_typedef_or_ref (assembly, type);
624 return mono_image_add_memberef_row (assembly, parent, name, sig);
629 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
631 MONO_REQ_GC_NEUTRAL_MODE;
634 MonoMethodSignature *sig;
636 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
638 if (create_typespec) {
639 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
644 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
645 if (token && !create_typespec)
648 g_assert (!method->is_inflated);
651 * A methodref signature can't contain an unmanaged calling convention.
653 sig = mono_metadata_signature_dup (mono_method_signature (method));
654 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
655 sig->call_convention = MONO_CALL_DEFAULT;
656 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
657 method->name, mono_dynimage_encode_method_signature (assembly, sig));
659 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
662 if (create_typespec) {
663 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
664 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
665 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
667 if (assembly->save) {
670 alloc_table (table, table->rows + 1);
671 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
672 values [MONO_METHODSPEC_METHOD] = token;
673 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
676 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
678 /*methodspec and memberef tokens are diferent, */
679 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
686 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
688 guint32 token, parent, sig;
689 ReflectionMethodBuilder rmb;
690 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
692 mono_error_init (error);
693 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
697 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
701 * A methodref signature can't contain an unmanaged calling convention.
702 * Since some flags are encoded as part of call_conv, we need to check against it.
704 if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
705 rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
707 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
708 return_val_if_nok (error, 0);
710 if (tb->generic_params) {
711 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
712 return_val_if_nok (error, 0);
714 MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
715 return_val_if_nok (error, 0);
717 parent = mono_image_typedef_or_ref (assembly, t);
720 char *name = mono_string_to_utf8_checked (method->name, error);
721 return_val_if_nok (error, 0);
723 token = mono_image_add_memberef_row (assembly, parent, name, sig);
726 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
732 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
733 const gchar *name, guint32 sig)
735 MonoDynamicTable *table;
739 table = &assembly->tables [MONO_TABLE_MEMBERREF];
741 if (assembly->save) {
742 alloc_table (table, table->rows + 1);
743 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
744 values [MONO_MEMBERREF_CLASS] = original;
745 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
746 values [MONO_MEMBERREF_SIGNATURE] = sig;
749 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
756 mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
758 MonoDynamicTable *table;
760 guint32 token, mtoken = 0;
762 mono_error_init (error);
763 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
767 table = &assembly->tables [MONO_TABLE_METHODSPEC];
769 mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
770 if (!mono_error_ok (error))
773 switch (mono_metadata_token_table (mtoken)) {
774 case MONO_TABLE_MEMBERREF:
775 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
777 case MONO_TABLE_METHOD:
778 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
781 g_assert_not_reached ();
784 if (assembly->save) {
785 alloc_table (table, table->rows + 1);
786 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
787 values [MONO_METHODSPEC_METHOD] = mtoken;
788 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
791 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
794 mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
800 is_field_on_inst (MonoClassField *field)
802 return field->parent->generic_class && field->parent->generic_class->is_dynamic;
805 #ifndef DISABLE_REFLECTION_EMIT
807 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
813 g_assert (field->parent);
815 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
819 if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
820 int index = field - field->parent->fields;
821 type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
823 type = mono_field_get_type (field);
825 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
826 mono_field_get_name (field),
827 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
828 mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
833 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
835 MonoDynamicTable *table;
837 guint32 token, mtoken = 0, sig;
838 MonoMethodInflated *imethod;
839 MonoMethod *declaring;
841 table = &assembly->tables [MONO_TABLE_METHODSPEC];
843 g_assert (method->is_inflated);
844 imethod = (MonoMethodInflated *) method;
845 declaring = imethod->declaring;
847 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
848 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
850 if (!mono_method_signature (declaring)->generic_param_count)
853 switch (mono_metadata_token_table (mtoken)) {
854 case MONO_TABLE_MEMBERREF:
855 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
857 case MONO_TABLE_METHOD:
858 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
861 g_assert_not_reached ();
864 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
866 if (assembly->save) {
867 alloc_table (table, table->rows + 1);
868 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
869 values [MONO_METHODSPEC_METHOD] = mtoken;
870 values [MONO_METHODSPEC_SIGNATURE] = sig;
873 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
880 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
882 MonoMethodInflated *imethod;
885 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
889 g_assert (method->is_inflated);
890 imethod = (MonoMethodInflated *) method;
892 if (mono_method_signature (imethod->declaring)->generic_param_count) {
893 token = method_encode_methodspec (assembly, method);
895 guint32 sig = mono_dynimage_encode_method_signature (
896 assembly, mono_method_signature (imethod->declaring));
897 token = mono_image_get_memberref_token (
898 assembly, &method->klass->byval_arg, method->name, sig);
901 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
906 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
908 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
911 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
912 token = mono_image_get_memberref_token (
913 assembly, &m->klass->byval_arg, m->name, sig);
919 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
921 MonoReflectionTypeBuilder *tb;
923 mono_error_init (error);
925 if (!is_sre_type_builder(mono_object_class (type)))
927 tb = (MonoReflectionTypeBuilder *)type;
929 if (tb && tb->generic_container)
930 mono_reflection_create_generic_class (tb, error);
934 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
937 MonoDynamicTable *table;
940 mono_error_init (error);
942 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
943 idx = table->next_idx ++;
945 alloc_table (table, table->rows);
946 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
948 values [MONO_STAND_ALONE_SIGNATURE] =
949 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
950 return_val_if_nok (error, 0);
956 reflection_cc_to_file (int call_conv) {
957 switch (call_conv & 0x3) {
959 case 1: return MONO_CALL_DEFAULT;
960 case 2: return MONO_CALL_VARARG;
962 g_assert_not_reached ();
966 #endif /* !DISABLE_REFLECTION_EMIT */
968 struct _ArrayMethod {
970 MonoMethodSignature *sig;
976 mono_sre_array_method_free (ArrayMethod *am)
983 #ifndef DISABLE_REFLECTION_EMIT
985 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
990 MonoMethodSignature *sig;
991 ArrayMethod *am = NULL;
994 mono_error_init (error);
996 nparams = mono_array_length (m->parameters);
997 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
999 sig->sentinelpos = -1;
1000 sig->call_convention = reflection_cc_to_file (m->call_conv);
1001 sig->param_count = nparams;
1003 sig->ret = mono_reflection_type_get_handle (m->ret, error);
1007 sig->ret = &mono_defaults.void_class->byval_arg;
1009 mtype = mono_reflection_type_get_handle (m->parent, error);
1013 for (i = 0; i < nparams; ++i) {
1014 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
1019 name = mono_string_to_utf8_checked (m->name, error);
1022 for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
1023 am = (ArrayMethod *)tmp->data;
1024 if (strcmp (name, am->name) == 0 &&
1025 mono_metadata_type_equal (am->parent, mtype) &&
1026 mono_metadata_signature_equal (am->sig, sig)) {
1029 m->table_idx = am->token & 0xffffff;
1033 am = g_new0 (ArrayMethod, 1);
1037 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
1038 mono_dynimage_encode_method_signature (assembly, sig));
1039 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
1040 m->table_idx = am->token & 0xffffff;
1051 #ifndef DISABLE_REFLECTION_EMIT
1054 * mono_image_insert_string:
1055 * @module: module builder object
1058 * Insert @str into the user string stream of @module.
1061 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
1063 MonoDynamicImage *assembly;
1068 if (!module->dynamic_image)
1069 mono_image_module_basic_init (module);
1071 assembly = module->dynamic_image;
1073 if (assembly->save) {
1074 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
1075 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1076 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1078 char *swapped = g_malloc (2 * mono_string_length (str));
1079 const char *p = (const char*)mono_string_chars (str);
1081 swap_with_size (swapped, p, 2, mono_string_length (str));
1082 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
1086 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
1088 mono_image_add_stream_data (&assembly->us, "", 1);
1090 idx = assembly->us.index ++;
1093 mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
1095 return MONO_TOKEN_STRING | idx;
1099 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
1103 MonoMethodSignature *sig;
1105 mono_error_init (error);
1107 klass = obj->vtable->klass;
1108 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1109 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1110 MonoMethodSignature *old;
1111 guint32 sig_token, parent;
1114 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1116 nargs = mono_array_length (opt_param_types);
1117 old = mono_method_signature (method);
1118 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1120 sig->hasthis = old->hasthis;
1121 sig->explicit_this = old->explicit_this;
1122 sig->call_convention = old->call_convention;
1123 sig->generic_param_count = old->generic_param_count;
1124 sig->param_count = old->param_count + nargs;
1125 sig->sentinelpos = old->param_count;
1126 sig->ret = old->ret;
1128 for (i = 0; i < old->param_count; i++)
1129 sig->params [i] = old->params [i];
1131 for (i = 0; i < nargs; i++) {
1132 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1133 sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1134 if (!is_ok (error)) goto fail;
1137 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1138 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1139 parent >>= MONO_TYPEDEFORREF_BITS;
1141 parent <<= MONO_MEMBERREF_PARENT_BITS;
1142 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1144 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1145 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1146 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1147 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1148 ReflectionMethodBuilder rmb;
1149 guint32 parent, sig_token;
1150 int nopt_args, nparams, ngparams, i;
1152 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1155 rmb.opt_types = opt_param_types;
1156 nopt_args = mono_array_length (opt_param_types);
1158 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1159 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1160 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1162 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1163 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1164 sig->call_convention = rmb.call_conv;
1165 sig->generic_param_count = ngparams;
1166 sig->param_count = nparams + nopt_args;
1167 sig->sentinelpos = nparams;
1168 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1169 if (!is_ok (error)) goto fail;
1171 for (i = 0; i < nparams; i++) {
1172 MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1173 sig->params [i] = mono_reflection_type_get_handle (rt, error);
1174 if (!is_ok (error)) goto fail;
1177 for (i = 0; i < nopt_args; i++) {
1178 MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1179 sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1180 if (!is_ok (error)) goto fail;
1183 // FIXME: This doesn't work, we don't use 'sig' for anything
1184 // The token fixup doesn't work either
1185 g_assert_not_reached ();
1187 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1191 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1192 if (!mono_error_ok (error))
1194 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1196 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1197 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1199 char *name = mono_string_to_utf8_checked (rmb.name, error);
1200 if (!is_ok (error)) goto fail;
1201 token = mono_image_get_varargs_method_token (
1202 assembly, parent, name, sig_token);
1205 g_error ("requested method token for %s\n", klass->name);
1208 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1209 mono_dynamic_image_register_token (assembly, token, obj);
1212 g_assert (!mono_error_ok (error));
1217 * mono_image_create_token:
1218 * @assembly: a dynamic assembly
1220 * @register_token: Whenever to register the token in the assembly->tokens hash.
1222 * Get a token to insert in the IL code stream for the given MemberInfo.
1223 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1224 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1228 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
1229 gboolean create_open_instance, gboolean register_token,
1235 mono_error_init (error);
1237 klass = obj->vtable->klass;
1239 /* Check for user defined reflection objects */
1240 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1241 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1242 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1246 if (strcmp (klass->name, "MethodBuilder") == 0) {
1247 /* These are handled in managed code */
1248 g_assert_not_reached ();
1249 } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
1250 /* These are handled in managed code */
1251 g_assert_not_reached ();
1252 } else if (strcmp (klass->name, "FieldBuilder") == 0) {
1253 /* These are handled in managed code */
1254 g_assert_not_reached ();
1255 } else if (strcmp (klass->name, "TypeBuilder") == 0) {
1256 /* These are handled in managed code */
1257 g_assert_not_reached ();
1258 } else if (strcmp (klass->name, "RuntimeType") == 0) {
1259 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1260 return_val_if_nok (error, 0);
1261 MonoClass *mc = mono_class_from_mono_type (type);
1262 token = mono_metadata_token_from_dor (
1263 mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
1264 } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
1265 /* These are handled in managed code */
1266 g_assert_not_reached ();
1267 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1268 strcmp (klass->name, "MonoMethod") == 0) {
1269 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1270 if (m->method->is_inflated) {
1271 if (create_open_instance)
1272 token = mono_image_get_methodspec_token (assembly, m->method);
1274 token = mono_image_get_inflated_method_token (assembly, m->method);
1275 } else if ((m->method->klass->image == &assembly->image) &&
1276 !m->method->klass->generic_class) {
1277 static guint32 method_table_idx = 0xffffff;
1278 if (m->method->klass->wastypebuilder) {
1279 /* we use the same token as the one that was assigned
1280 * to the Methodbuilder.
1281 * FIXME: do the equivalent for Fields.
1283 token = m->method->token;
1286 * Each token should have a unique index, but the indexes are
1287 * assigned by managed code, so we don't know about them. An
1288 * easy solution is to count backwards...
1290 method_table_idx --;
1291 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1294 token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1296 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1297 } else if (strcmp (klass->name, "MonoField") == 0) {
1298 MonoReflectionField *f = (MonoReflectionField *)obj;
1299 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1300 static guint32 field_table_idx = 0xffffff;
1302 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1304 token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1306 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1307 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1308 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1309 token = mono_image_get_array_token (assembly, m, error);
1310 return_val_if_nok (error, 0);
1311 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1312 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1313 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1314 return_val_if_nok (error, 0);
1315 } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1316 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1317 return_val_if_nok (error, 0);
1318 token = mono_metadata_token_from_dor (
1319 mono_image_typedef_or_ref (assembly, type));
1320 } else if (is_sre_generic_instance (klass) || is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
1321 /* These are handled in managed code */
1322 g_assert_not_reached ();
1323 } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
1324 /* These are handled in managed code */
1325 g_assert_not_reached ();
1326 } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
1327 /* These are handled in managed code */
1328 g_assert_not_reached ();
1329 } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
1330 /* These are handled in managed code */
1331 g_assert_not_reached ();
1333 g_error ("requested token for %s\n", klass->name);
1337 mono_image_register_token (assembly, token, obj);
1345 #ifndef DISABLE_REFLECTION_EMIT
1348 * mono_reflection_dynimage_basic_init:
1349 * @assembly: an assembly builder object
1351 * Create the MonoImage that represents the assembly builder and setup some
1352 * of the helper hash table and the basic metadata streams.
1355 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1358 MonoDynamicAssembly *assembly;
1359 MonoDynamicImage *image;
1360 MonoDomain *domain = mono_object_domain (assemblyb);
1362 if (assemblyb->dynamic_assembly)
1366 /* assembly->assembly.image might be GC allocated */
1367 assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1369 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1372 mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1374 assembly->assembly.ref_count = 1;
1375 assembly->assembly.dynamic = TRUE;
1376 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1377 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1378 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1379 if (mono_error_set_pending_exception (&error))
1381 if (assemblyb->culture) {
1382 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1383 if (mono_error_set_pending_exception (&error))
1386 assembly->assembly.aname.culture = g_strdup ("");
1388 if (assemblyb->version) {
1389 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1390 if (mono_error_set_pending_exception (&error))
1392 char **version = g_strsplit (vstr, ".", 4);
1393 char **parts = version;
1394 assembly->assembly.aname.major = atoi (*parts++);
1395 assembly->assembly.aname.minor = atoi (*parts++);
1396 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1397 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1399 g_strfreev (version);
1402 assembly->assembly.aname.major = 0;
1403 assembly->assembly.aname.minor = 0;
1404 assembly->assembly.aname.build = 0;
1405 assembly->assembly.aname.revision = 0;
1408 assembly->run = assemblyb->access != 2;
1409 assembly->save = assemblyb->access != 1;
1410 assembly->domain = domain;
1412 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1413 if (mono_error_set_pending_exception (&error))
1415 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1416 image->initial_image = TRUE;
1417 assembly->assembly.aname.name = image->image.name;
1418 assembly->assembly.image = &image->image;
1419 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1420 /* -1 to correct for the trailing NULL byte */
1421 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1422 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1424 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1427 mono_domain_assemblies_lock (domain);
1428 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1429 mono_domain_assemblies_unlock (domain);
1431 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1433 mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1435 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1438 #endif /* !DISABLE_REFLECTION_EMIT */
1440 #ifndef DISABLE_REFLECTION_EMIT
1442 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1444 CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
1448 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
1450 CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
1454 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
1456 MonoDynamicImage *image = moduleb->dynamic_image;
1457 MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
1458 mono_error_init (error);
1461 MonoImage **new_modules;
1463 char *name, *fqname;
1465 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1466 * we don't know which module it belongs to, since that is only
1467 * determined at assembly save time.
1469 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1470 name = mono_string_to_utf8_checked (ab->name, error);
1471 return_val_if_nok (error, FALSE);
1472 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
1473 if (!is_ok (error)) {
1477 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
1479 moduleb->module.image = &image->image;
1480 moduleb->dynamic_image = image;
1481 register_module (mono_object_domain (moduleb), moduleb, image);
1483 /* register the module with the assembly */
1484 ass = ab->dynamic_assembly->assembly.image;
1485 module_count = ass->module_count;
1486 new_modules = g_new0 (MonoImage *, module_count + 1);
1489 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1490 new_modules [module_count] = &image->image;
1491 mono_image_addref (&image->image);
1493 g_free (ass->modules);
1494 ass->modules = new_modules;
1495 ass->module_count ++;
1501 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
1504 (void) image_module_basic_init (moduleb, &error);
1505 mono_error_set_pending_exception (&error);
1511 is_corlib_type (MonoClass *klass)
1513 return klass->image == mono_defaults.corlib;
1516 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1517 static MonoClass *cached_class; \
1519 return cached_class == _class; \
1520 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1521 cached_class = _class; \
1529 #ifndef DISABLE_REFLECTION_EMIT
1531 is_sre_array (MonoClass *klass)
1533 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1537 is_sre_byref (MonoClass *klass)
1539 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1543 is_sre_pointer (MonoClass *klass)
1545 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1549 is_sre_generic_instance (MonoClass *klass)
1551 check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
1555 is_sre_type_builder (MonoClass *klass)
1557 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1561 is_sre_method_builder (MonoClass *klass)
1563 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1567 mono_is_sre_ctor_builder (MonoClass *klass)
1569 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1573 is_sre_field_builder (MonoClass *klass)
1575 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1579 is_sre_gparam_builder (MonoClass *klass)
1581 check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1585 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1587 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1591 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1593 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1596 static MonoReflectionType*
1597 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
1599 static MonoMethod *method_get_underlying_system_type = NULL;
1600 MonoReflectionType *rt;
1601 MonoMethod *usertype_method;
1603 mono_error_init (error);
1605 if (!method_get_underlying_system_type)
1606 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1608 usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
1610 rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
1616 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
1619 mono_error_init (error);
1626 if (mono_reflection_is_usertype (ref)) {
1627 ref = mono_reflection_type_get_underlying_system_type (ref, error);
1628 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
1634 klass = mono_object_class (ref);
1636 if (is_sre_array (klass)) {
1638 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
1639 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
1640 return_val_if_nok (error, NULL);
1642 if (sre_array->rank == 0) //single dimentional array
1643 res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
1645 res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
1646 sre_array->type.type = res;
1648 } else if (is_sre_byref (klass)) {
1650 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
1651 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
1652 return_val_if_nok (error, NULL);
1654 res = &mono_class_from_mono_type (base)->this_arg;
1655 sre_byref->type.type = res;
1657 } else if (is_sre_pointer (klass)) {
1659 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
1660 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
1661 return_val_if_nok (error, NULL);
1663 res = &mono_ptr_class_get (base)->byval_arg;
1664 sre_pointer->type.type = res;
1666 } else if (is_sre_generic_instance (klass)) {
1667 MonoType *res, **types;
1668 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
1671 count = mono_array_length (gclass->type_arguments);
1672 types = g_new0 (MonoType*, count);
1673 for (i = 0; i < count; ++i) {
1674 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
1675 types [i] = mono_reflection_type_get_handle (t, error);
1676 if (!types[i] || !is_ok (error)) {
1682 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
1685 gclass->type.type = res;
1687 } else if (is_sre_gparam_builder (klass)) {
1688 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)ref;
1689 MonoGenericParamFull *param;
1693 image = &gparam->tbuilder->module->dynamic_image->image;
1695 param = mono_image_new0 (image, MonoGenericParamFull, 1);
1697 param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
1698 mono_error_assert_ok (error);
1699 param->param.num = gparam->index;
1701 if (gparam->mbuilder) {
1702 g_assert (gparam->mbuilder->generic_container);
1703 param->param.owner = gparam->mbuilder->generic_container;
1704 } else if (gparam->tbuilder) {
1705 g_assert (gparam->tbuilder->generic_container);
1706 param->param.owner = gparam->tbuilder->generic_container;
1709 pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1711 gparam->type.type = &pklass->byval_arg;
1713 mono_class_set_ref_info (pklass, gparam);
1714 mono_image_append_class_to_reflection_info_set (pklass);
1716 return &pklass->byval_arg;
1719 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1724 * LOCKING: Assumes the loader lock is held.
1726 static MonoMethodSignature*
1727 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
1728 MonoMethodSignature *sig;
1731 mono_error_init (error);
1733 count = parameters? mono_array_length (parameters): 0;
1735 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1736 sig->param_count = count;
1737 sig->sentinelpos = -1; /* FIXME */
1738 for (i = 0; i < count; ++i) {
1739 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1740 if (!is_ok (error)) {
1741 image_g_free (image, sig);
1749 * LOCKING: Assumes the loader lock is held.
1751 static MonoMethodSignature*
1752 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
1753 MonoMethodSignature *sig;
1755 mono_error_init (error);
1757 sig = parameters_to_signature (image, ctor->parameters, error);
1758 return_val_if_nok (error, NULL);
1759 sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1760 sig->ret = &mono_defaults.void_class->byval_arg;
1765 * LOCKING: Assumes the loader lock is held.
1767 static MonoMethodSignature*
1768 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
1769 MonoMethodSignature *sig;
1771 mono_error_init (error);
1773 sig = parameters_to_signature (image, method->parameters, error);
1774 return_val_if_nok (error, NULL);
1775 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1776 if (method->rtype) {
1777 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
1778 if (!is_ok (error)) {
1779 image_g_free (image, sig);
1783 sig->ret = &mono_defaults.void_class->byval_arg;
1785 sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
1789 static MonoMethodSignature*
1790 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
1791 MonoMethodSignature *sig;
1793 mono_error_init (error);
1795 sig = parameters_to_signature (NULL, method->parameters, error);
1796 return_val_if_nok (error, NULL);
1797 sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1798 if (method->rtype) {
1799 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
1800 if (!is_ok (error)) {
1805 sig->ret = &mono_defaults.void_class->byval_arg;
1807 sig->generic_param_count = 0;
1812 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1814 mono_error_init (error);
1815 MonoClass *klass = mono_object_class (prop);
1816 if (strcmp (klass->name, "PropertyBuilder") == 0) {
1817 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1818 *name = mono_string_to_utf8_checked (pb->name, error);
1819 return_if_nok (error);
1820 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1822 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1823 *name = g_strdup (p->property->name);
1824 if (p->property->get)
1825 *type = mono_method_signature (p->property->get)->ret;
1827 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1832 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1834 mono_error_init (error);
1835 MonoClass *klass = mono_object_class (field);
1836 if (strcmp (klass->name, "FieldBuilder") == 0) {
1837 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1838 *name = mono_string_to_utf8_checked (fb->name, error);
1839 return_if_nok (error);
1840 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1842 MonoReflectionField *f = (MonoReflectionField *)field;
1843 *name = g_strdup (mono_field_get_name (f->field));
1844 *type = f->field->type;
1848 #else /* DISABLE_REFLECTION_EMIT */
1851 is_sre_type_builder (MonoClass *klass)
1857 is_sre_generic_instance (MonoClass *klass)
1863 mono_is_sre_ctor_builder (MonoClass *klass)
1869 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1875 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1881 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
1883 mono_error_init (error);
1886 #endif /* !DISABLE_REFLECTION_EMIT */
1890 is_sr_mono_field (MonoClass *klass)
1892 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1896 mono_is_sr_mono_property (MonoClass *klass)
1898 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1902 is_sr_mono_method (MonoClass *klass)
1904 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1908 mono_is_sr_mono_cmethod (MonoClass *klass)
1910 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1914 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1916 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1920 mono_is_sre_type_builder (MonoClass *klass)
1922 return is_sre_type_builder (klass);
1926 mono_is_sre_generic_instance (MonoClass *klass)
1928 return is_sre_generic_instance (klass);
1934 * encode_cattr_value:
1935 * Encode a value in a custom attribute stream of bytes.
1936 * The value to encode is either supplied as an object in argument val
1937 * (valuetypes are boxed), or as a pointer to the data in the
1939 * @type represents the type of the value
1940 * @buffer is the start of the buffer
1941 * @p the current position in the buffer
1942 * @buflen contains the size of the buffer and is used to return the new buffer size
1943 * if this needs to be realloced.
1944 * @retbuffer and @retp return the start and the position of the buffer
1945 * @error set on error.
1948 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
1950 MonoTypeEnum simple_type;
1952 mono_error_init (error);
1953 if ((p-buffer) + 10 >= *buflen) {
1956 newbuf = (char *)g_realloc (buffer, *buflen);
1957 p = newbuf + (p-buffer);
1961 argval = ((char*)arg + sizeof (MonoObject));
1962 simple_type = type->type;
1964 switch (simple_type) {
1965 case MONO_TYPE_BOOLEAN:
1970 case MONO_TYPE_CHAR:
1973 swap_with_size (p, argval, 2, 1);
1979 swap_with_size (p, argval, 4, 1);
1983 swap_with_size (p, argval, 8, 1);
1988 swap_with_size (p, argval, 8, 1);
1991 case MONO_TYPE_VALUETYPE:
1992 if (type->data.klass->enumtype) {
1993 simple_type = mono_class_enum_basetype (type->data.klass)->type;
1996 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
1999 case MONO_TYPE_STRING: {
2006 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2007 return_if_nok (error);
2008 slen = strlen (str);
2009 if ((p-buffer) + 10 + slen >= *buflen) {
2013 newbuf = (char *)g_realloc (buffer, *buflen);
2014 p = newbuf + (p-buffer);
2017 mono_metadata_encode_value (slen, p, &p);
2018 memcpy (p, str, slen);
2023 case MONO_TYPE_CLASS: {
2032 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2033 return_if_nok (error);
2035 str = type_get_qualified_name (arg_type, NULL);
2036 slen = strlen (str);
2037 if ((p-buffer) + 10 + slen >= *buflen) {
2041 newbuf = (char *)g_realloc (buffer, *buflen);
2042 p = newbuf + (p-buffer);
2045 mono_metadata_encode_value (slen, p, &p);
2046 memcpy (p, str, slen);
2051 case MONO_TYPE_SZARRAY: {
2053 MonoClass *eclass, *arg_eclass;
2056 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2059 len = mono_array_length ((MonoArray*)arg);
2061 *p++ = (len >> 8) & 0xff;
2062 *p++ = (len >> 16) & 0xff;
2063 *p++ = (len >> 24) & 0xff;
2065 *retbuffer = buffer;
2066 eclass = type->data.klass;
2067 arg_eclass = mono_object_class (arg)->element_class;
2070 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2071 eclass = mono_defaults.object_class;
2073 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2074 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2075 int elsize = mono_class_array_element_size (arg_eclass);
2076 for (i = 0; i < len; ++i) {
2077 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2078 return_if_nok (error);
2081 } else if (eclass->valuetype && arg_eclass->valuetype) {
2082 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2083 int elsize = mono_class_array_element_size (eclass);
2084 for (i = 0; i < len; ++i) {
2085 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2086 return_if_nok (error);
2090 for (i = 0; i < len; ++i) {
2091 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2092 return_if_nok (error);
2097 case MONO_TYPE_OBJECT: {
2103 * The parameter type is 'object' but the type of the actual
2104 * argument is not. So we have to add type information to the blob
2105 * too. This is completely undocumented in the spec.
2109 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2114 klass = mono_object_class (arg);
2116 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2120 return_if_nok (error);
2123 if (klass->enumtype) {
2125 } else if (klass == mono_defaults.string_class) {
2126 simple_type = MONO_TYPE_STRING;
2129 } else if (klass->rank == 1) {
2131 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2132 /* See Partition II, Appendix B3 */
2135 *p++ = klass->element_class->byval_arg.type;
2136 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2137 return_if_nok (error);
2139 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2140 *p++ = simple_type = klass->byval_arg.type;
2143 g_error ("unhandled type in custom attr");
2145 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2146 slen = strlen (str);
2147 if ((p-buffer) + 10 + slen >= *buflen) {
2151 newbuf = (char *)g_realloc (buffer, *buflen);
2152 p = newbuf + (p-buffer);
2155 mono_metadata_encode_value (slen, p, &p);
2156 memcpy (p, str, slen);
2159 simple_type = mono_class_enum_basetype (klass)->type;
2163 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2166 *retbuffer = buffer;
2170 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2172 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2173 char *str = type_get_qualified_name (type, NULL);
2174 int slen = strlen (str);
2178 * This seems to be optional...
2181 mono_metadata_encode_value (slen, p, &p);
2182 memcpy (p, str, slen);
2185 } else if (type->type == MONO_TYPE_OBJECT) {
2187 } else if (type->type == MONO_TYPE_CLASS) {
2188 /* it should be a type: encode_cattr_value () has the check */
2191 mono_metadata_encode_value (type->type, p, &p);
2192 if (type->type == MONO_TYPE_SZARRAY)
2193 /* See the examples in Partition VI, Annex B */
2194 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2200 #ifndef DISABLE_REFLECTION_EMIT
2202 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2206 mono_error_init (error);
2208 /* Preallocate a large enough buffer */
2209 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2210 char *str = type_get_qualified_name (type, NULL);
2213 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2214 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2220 len += strlen (name);
2222 if ((p-buffer) + 20 + len >= *buflen) {
2226 newbuf = (char *)g_realloc (buffer, *buflen);
2227 p = newbuf + (p-buffer);
2231 encode_field_or_prop_type (type, p, &p);
2233 len = strlen (name);
2234 mono_metadata_encode_value (len, p, &p);
2235 memcpy (p, name, len);
2237 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2238 return_if_nok (error);
2240 *retbuffer = buffer;
2244 * mono_reflection_get_custom_attrs_blob:
2245 * @ctor: custom attribute constructor
2246 * @ctorArgs: arguments o the constructor
2252 * Creates the blob of data that needs to be saved in the metadata and that represents
2253 * the custom attributed described by @ctor, @ctorArgs etc.
2254 * Returns: a Byte array representing the blob of data.
2257 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2260 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2261 mono_error_cleanup (&error);
2266 * mono_reflection_get_custom_attrs_blob_checked:
2267 * @ctor: custom attribute constructor
2268 * @ctorArgs: arguments o the constructor
2273 * @error: set on error
2275 * Creates the blob of data that needs to be saved in the metadata and that represents
2276 * the custom attributed described by @ctor, @ctorArgs etc.
2277 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2280 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2282 MonoArray *result = NULL;
2283 MonoMethodSignature *sig;
2288 mono_error_init (error);
2290 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2291 /* sig is freed later so allocate it in the heap */
2292 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2293 if (!is_ok (error)) {
2298 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2301 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2303 p = buffer = (char *)g_malloc (buflen);
2304 /* write the prolog */
2307 for (i = 0; i < sig->param_count; ++i) {
2308 arg = mono_array_get (ctorArgs, MonoObject*, i);
2309 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2310 if (!is_ok (error)) goto leave;
2314 i += mono_array_length (properties);
2316 i += mono_array_length (fields);
2318 *p++ = (i >> 8) & 0xff;
2321 for (i = 0; i < mono_array_length (properties); ++i) {
2325 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2326 get_prop_name_and_type (prop, &pname, &ptype, error);
2327 if (!is_ok (error)) goto leave;
2328 *p++ = 0x54; /* PROPERTY signature */
2329 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2331 if (!is_ok (error)) goto leave;
2337 for (i = 0; i < mono_array_length (fields); ++i) {
2341 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2342 get_field_name_and_type (field, &fname, &ftype, error);
2343 if (!is_ok (error)) goto leave;
2344 *p++ = 0x53; /* FIELD signature */
2345 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2347 if (!is_ok (error)) goto leave;
2351 g_assert (p - buffer <= buflen);
2352 buflen = p - buffer;
2353 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2356 p = mono_array_addr (result, char, 0);
2357 memcpy (p, buffer, buflen);
2360 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2366 * reflection_setup_internal_class:
2367 * @tb: a TypeBuilder object
2368 * @error: set on error
2370 * Creates a MonoClass that represents the TypeBuilder.
2371 * This is a trick that lets us simplify a lot of reflection code
2372 * (and will allow us to support Build and Run assemblies easier).
2374 * Returns TRUE on success. On failure, returns FALSE and sets @error.
2377 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2379 MonoClass *klass, *parent;
2381 mono_error_init (error);
2383 mono_loader_lock ();
2386 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
2387 if (!is_ok (error)) {
2388 mono_loader_unlock ();
2391 /* check so we can compile corlib correctly */
2392 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
2393 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2394 parent = parent_type->data.klass;
2396 parent = mono_class_from_mono_type (parent_type);
2402 /* the type has already being created: it means we just have to change the parent */
2403 if (tb->type.type) {
2404 klass = mono_class_from_mono_type (tb->type.type);
2405 klass->parent = NULL;
2406 /* fool mono_class_setup_parent */
2407 klass->supertypes = NULL;
2408 mono_class_setup_parent (klass, parent);
2409 mono_class_setup_mono_type (klass);
2410 mono_loader_unlock ();
2414 klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
2416 klass->image = &tb->module->dynamic_image->image;
2418 klass->inited = 1; /* we lie to the runtime */
2419 klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
2422 klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
2425 klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
2426 klass->flags = tb->attrs;
2428 mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2430 klass->element_class = klass;
2432 if (mono_class_get_ref_info (klass) == NULL) {
2433 mono_class_set_ref_info (klass, tb);
2435 /* Put into cache so mono_class_get_checked () will find it.
2436 Skip nested types as those should not be available on the global scope. */
2437 if (!tb->nesting_type)
2438 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
2441 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2442 by performing a mono_class_get which does the full resolution.
2444 Working around this semantics would require us to write a lot of code for no clear advantage.
2446 mono_image_append_class_to_reflection_info_set (klass);
2448 g_assert (mono_class_get_ref_info (klass) == tb);
2451 mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
2453 if (parent != NULL) {
2454 mono_class_setup_parent (klass, parent);
2455 } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
2456 const char *old_n = klass->name;
2457 /* trick to get relative numbering right when compiling corlib */
2458 klass->name = "BuildingObject";
2459 mono_class_setup_parent (klass, mono_defaults.object_class);
2460 klass->name = old_n;
2463 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2464 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2465 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2466 klass->instance_size = sizeof (MonoObject);
2467 klass->size_inited = 1;
2468 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2471 mono_class_setup_mono_type (klass);
2473 mono_class_setup_supertypes (klass);
2476 * FIXME: handle interfaces.
2479 tb->type.type = &klass->byval_arg;
2481 if (tb->nesting_type) {
2482 g_assert (tb->nesting_type->type);
2483 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
2484 if (!is_ok (error)) goto failure;
2485 klass->nested_in = mono_class_from_mono_type (nesting_type);
2488 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2490 mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
2492 mono_loader_unlock ();
2496 mono_loader_unlock ();
2501 * ves_icall_TypeBuilder_setup_internal_class:
2502 * @tb: a TypeBuilder object
2505 * Creates a MonoClass that represents the TypeBuilder.
2506 * This is a trick that lets us simplify a lot of reflection code
2507 * (and will allow us to support Build and Run assemblies easier).
2511 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
2514 (void) reflection_setup_internal_class (tb, &error);
2515 mono_error_set_pending_exception (&error);
2519 * mono_reflection_create_generic_class:
2520 * @tb: a TypeBuilder object
2521 * @error: set on error
2523 * Creates the generic class after all generic parameters have been added.
2524 * On success returns TRUE, on failure returns FALSE and sets @error.
2528 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2534 mono_error_init (error);
2536 klass = mono_class_from_mono_type (tb->type.type);
2538 count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
2540 if (klass->generic_container || (count == 0))
2543 g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
2545 klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2547 klass->generic_container->owner.klass = klass;
2548 klass->generic_container->type_argc = count;
2549 klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2551 klass->is_generic = 1;
2553 for (i = 0; i < count; i++) {
2554 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
2555 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
2556 return_val_if_nok (error, FALSE);
2557 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2558 klass->generic_container->type_params [i] = *param;
2559 /*Make sure we are a diferent type instance */
2560 klass->generic_container->type_params [i].param.owner = klass->generic_container;
2561 klass->generic_container->type_params [i].info.pklass = NULL;
2562 klass->generic_container->type_params [i].info.flags = gparam->attrs;
2564 g_assert (klass->generic_container->type_params [i].param.owner);
2567 klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
2571 static MonoMarshalSpec*
2572 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2573 MonoReflectionMarshal *minfo, MonoError *error)
2575 MonoMarshalSpec *res;
2577 mono_error_init (error);
2579 res = image_g_new0 (image, MonoMarshalSpec, 1);
2580 res->native = (MonoMarshalNative)minfo->type;
2582 switch (minfo->type) {
2583 case MONO_NATIVE_LPARRAY:
2584 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2585 if (minfo->has_size) {
2586 res->data.array_data.param_num = minfo->param_num;
2587 res->data.array_data.num_elem = minfo->count;
2588 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2591 res->data.array_data.param_num = -1;
2592 res->data.array_data.num_elem = -1;
2593 res->data.array_data.elem_mult = -1;
2597 case MONO_NATIVE_BYVALTSTR:
2598 case MONO_NATIVE_BYVALARRAY:
2599 res->data.array_data.num_elem = minfo->count;
2602 case MONO_NATIVE_CUSTOM:
2603 if (minfo->marshaltyperef) {
2604 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2605 if (!is_ok (error)) {
2606 image_g_free (image, res);
2609 res->data.custom_data.custom_name =
2610 type_get_fully_qualified_name (marshaltyperef);
2612 if (minfo->mcookie) {
2613 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2614 if (!is_ok (error)) {
2615 image_g_free (image, res);
2627 #endif /* !DISABLE_REFLECTION_EMIT */
2629 MonoReflectionMarshalAsAttribute*
2630 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2631 MonoMarshalSpec *spec, MonoError *error)
2633 MonoReflectionType *rt;
2634 MonoReflectionMarshalAsAttribute *minfo;
2637 mono_error_init (error);
2639 minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
2642 minfo->utype = spec->native;
2644 switch (minfo->utype) {
2645 case MONO_NATIVE_LPARRAY:
2646 minfo->array_subtype = spec->data.array_data.elem_type;
2647 minfo->size_const = spec->data.array_data.num_elem;
2648 if (spec->data.array_data.param_num != -1)
2649 minfo->size_param_index = spec->data.array_data.param_num;
2652 case MONO_NATIVE_BYVALTSTR:
2653 case MONO_NATIVE_BYVALARRAY:
2654 minfo->size_const = spec->data.array_data.num_elem;
2657 case MONO_NATIVE_CUSTOM:
2658 if (spec->data.custom_data.custom_name) {
2659 mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2660 return_val_if_nok (error, NULL);
2663 rt = mono_type_get_object_checked (domain, mtype, error);
2667 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
2670 MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
2672 if (spec->data.custom_data.cookie)
2673 MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
2683 #ifndef DISABLE_REFLECTION_EMIT
2685 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2686 ReflectionMethodBuilder *rmb,
2687 MonoMethodSignature *sig,
2691 MonoMethodWrapper *wrapperm;
2692 MonoMarshalSpec **specs;
2693 MonoReflectionMethodAux *method_aux;
2698 mono_error_init (error);
2700 * Methods created using a MethodBuilder should have their memory allocated
2701 * inside the image mempool, while dynamic methods should have their memory
2704 dynamic = rmb->refs != NULL;
2705 image = dynamic ? NULL : klass->image;
2708 g_assert (!klass->generic_class);
2710 mono_loader_lock ();
2712 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2713 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2714 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2716 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
2718 wrapperm = (MonoMethodWrapper*)m;
2720 m->dynamic = dynamic;
2722 m->flags = rmb->attrs;
2723 m->iflags = rmb->iattrs;
2724 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2727 m->sre_method = TRUE;
2728 m->skip_visibility = rmb->skip_visibility;
2730 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2732 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2733 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2736 m->signature->pinvoke = 1;
2737 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2738 m->signature->pinvoke = 1;
2740 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2742 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
2743 mono_error_assert_ok (error);
2744 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
2745 mono_error_assert_ok (error);
2747 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2749 if (image_is_dynamic (klass->image))
2750 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2752 mono_loader_unlock ();
2755 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2756 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2757 MonoMethodHeader *header;
2759 gint32 max_stack, i;
2760 gint32 num_locals = 0;
2761 gint32 num_clauses = 0;
2765 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2766 code_size = rmb->ilgen->code_len;
2767 max_stack = rmb->ilgen->max_stack;
2768 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2769 if (rmb->ilgen->ex_handlers)
2770 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2773 code = mono_array_addr (rmb->code, guint8, 0);
2774 code_size = mono_array_length (rmb->code);
2775 /* we probably need to run a verifier on the code... */
2785 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2786 header->code_size = code_size;
2787 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2788 memcpy ((char*)header->code, code, code_size);
2789 header->max_stack = max_stack;
2790 header->init_locals = rmb->init_locals;
2791 header->num_locals = num_locals;
2793 for (i = 0; i < num_locals; ++i) {
2794 MonoReflectionLocalBuilder *lb =
2795 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2797 header->locals [i] = image_g_new0 (image, MonoType, 1);
2798 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2799 mono_error_assert_ok (error);
2800 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2803 header->num_clauses = num_clauses;
2805 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2806 rmb->ilgen, num_clauses, error);
2807 mono_error_assert_ok (error);
2810 wrapperm->header = header;
2813 if (rmb->generic_params) {
2814 int count = mono_array_length (rmb->generic_params);
2815 MonoGenericContainer *container = rmb->generic_container;
2817 g_assert (container);
2819 container->type_argc = count;
2820 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2821 container->owner.method = m;
2822 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
2824 m->is_generic = TRUE;
2825 mono_method_set_generic_container (m, container);
2827 for (i = 0; i < count; i++) {
2828 MonoReflectionGenericParam *gp =
2829 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2830 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2831 mono_error_assert_ok (error);
2832 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2833 container->type_params [i] = *param;
2837 * The method signature might have pointers to generic parameters that belong to other methods.
2838 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2839 * generic parameters.
2841 for (i = 0; i < m->signature->param_count; ++i) {
2842 MonoType *t = m->signature->params [i];
2843 if (t->type == MONO_TYPE_MVAR) {
2844 MonoGenericParam *gparam = t->data.generic_param;
2845 if (gparam->num < count) {
2846 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2847 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2853 if (klass->generic_container) {
2854 container->parent = klass->generic_container;
2855 container->context.class_inst = klass->generic_container->context.class_inst;
2857 container->context.method_inst = mono_get_shared_generic_inst (container);
2861 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2865 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2867 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2868 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2869 for (i = 0; i < rmb->nrefs; ++i)
2870 data [i + 1] = rmb->refs [i];
2875 /* Parameter info */
2878 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2879 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2880 for (i = 0; i <= m->signature->param_count; ++i) {
2881 MonoReflectionParamBuilder *pb;
2882 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2883 if ((i > 0) && (pb->attrs)) {
2884 /* Make a copy since it might point to a shared type structure */
2885 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2886 m->signature->params [i - 1]->attrs = pb->attrs;
2889 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2890 MonoDynamicImage *assembly;
2892 MonoTypeEnum def_type;
2896 if (!method_aux->param_defaults) {
2897 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2898 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2900 assembly = (MonoDynamicImage*)klass->image;
2901 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
2902 /* Copy the data from the blob since it might get realloc-ed */
2903 p = assembly->blob.data + idx;
2904 len = mono_metadata_decode_blob_size (p, &p2);
2906 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
2907 method_aux->param_default_types [i] = def_type;
2908 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
2912 method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
2913 mono_error_assert_ok (error);
2916 if (!method_aux->param_cattr)
2917 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
2918 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
2924 /* Parameter marshalling */
2927 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
2928 MonoReflectionParamBuilder *pb;
2929 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2930 if (pb->marshal_info) {
2932 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
2933 specs [pb->position] =
2934 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
2935 if (!is_ok (error)) {
2936 mono_loader_unlock ();
2937 image_g_free (image, specs);
2938 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2944 if (specs != NULL) {
2946 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2947 method_aux->param_marshall = specs;
2950 if (image_is_dynamic (klass->image) && method_aux)
2951 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2953 mono_loader_unlock ();
2959 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
2961 ReflectionMethodBuilder rmb;
2962 MonoMethodSignature *sig;
2964 mono_loader_lock ();
2965 g_assert (klass->image != NULL);
2966 sig = ctor_builder_to_signature (klass->image, mb, error);
2967 mono_loader_unlock ();
2968 return_val_if_nok (error, NULL);
2970 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
2973 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2974 return_val_if_nok (error, NULL);
2975 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2977 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
2978 /* ilgen is no longer needed */
2986 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
2988 ReflectionMethodBuilder rmb;
2989 MonoMethodSignature *sig;
2991 mono_error_init (error);
2993 mono_loader_lock ();
2994 g_assert (klass->image != NULL);
2995 sig = method_builder_to_signature (klass->image, mb, error);
2996 mono_loader_unlock ();
2997 return_val_if_nok (error, NULL);
2999 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3002 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3003 return_val_if_nok (error, NULL);
3004 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3006 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
3007 /* ilgen is no longer needed */
3013 #ifndef DISABLE_REFLECTION_EMIT
3016 * fix_partial_generic_class:
3017 * @klass: a generic instantiation MonoClass
3018 * @error: set on error
3020 * Assumes that the generic container of @klass has its vtable
3021 * initialized, and updates the parent class, interfaces, methods and
3022 * fields of @klass by inflating the types using the generic context.
3024 * On success returns TRUE, on failure returns FALSE and sets @error.
3028 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3030 MonoClass *gklass = klass->generic_class->container_class;
3033 mono_error_init (error);
3035 if (klass->wastypebuilder)
3038 if (klass->parent != gklass->parent) {
3039 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
3040 if (mono_error_ok (error)) {
3041 MonoClass *parent = mono_class_from_mono_type (parent_type);
3042 mono_metadata_free_type (parent_type);
3043 if (parent != klass->parent) {
3044 /*fool mono_class_setup_parent*/
3045 klass->supertypes = NULL;
3046 mono_class_setup_parent (klass, parent);
3049 if (gklass->wastypebuilder)
3050 klass->wastypebuilder = TRUE;
3055 if (!klass->generic_class->need_sync)
3058 if (klass->method.count != gklass->method.count) {
3059 klass->method.count = gklass->method.count;
3060 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
3062 for (i = 0; i < klass->method.count; i++) {
3063 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3064 gklass->methods [i], klass, mono_class_get_context (klass), error);
3065 mono_error_assert_ok (error);
3069 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3070 klass->interface_count = gklass->interface_count;
3071 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3072 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3074 for (i = 0; i < gklass->interface_count; ++i) {
3075 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3076 return_val_if_nok (error, FALSE);
3078 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3079 mono_metadata_free_type (iface_type);
3081 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3084 klass->interfaces_inited = 1;
3087 if (klass->field.count != gklass->field.count) {
3088 klass->field.count = gklass->field.count;
3089 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
3091 for (i = 0; i < klass->field.count; i++) {
3092 klass->fields [i] = gklass->fields [i];
3093 klass->fields [i].parent = klass;
3094 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3095 return_val_if_nok (error, FALSE);
3099 /*We can only finish with this klass once it's parent has as well*/
3100 if (gklass->wastypebuilder)
3101 klass->wastypebuilder = TRUE;
3106 * ensure_generic_class_runtime_vtable:
3107 * @klass a generic class
3108 * @error set on error
3110 * Ensures that the generic container of @klass has a vtable and
3111 * returns TRUE on success. On error returns FALSE and sets @error.
3114 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3116 MonoClass *gklass = klass->generic_class->container_class;
3118 mono_error_init (error);
3120 if (!ensure_runtime_vtable (gklass, error))
3123 return fix_partial_generic_class (klass, error);
3127 * ensure_runtime_vtable:
3129 * @error set on error
3131 * Ensures that @klass has a vtable and returns TRUE on success. On
3132 * error returns FALSE and sets @error.
3135 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3137 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3140 mono_error_init (error);
3142 if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
3145 if (!ensure_runtime_vtable (klass->parent, error))
3149 num = tb->ctors? mono_array_length (tb->ctors): 0;
3150 num += tb->num_methods;
3151 klass->method.count = num;
3152 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3153 num = tb->ctors? mono_array_length (tb->ctors): 0;
3154 for (i = 0; i < num; ++i) {
3155 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3158 klass->methods [i] = ctor;
3160 num = tb->num_methods;
3162 for (i = 0; i < num; ++i) {
3163 MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3166 klass->methods [j++] = meth;
3169 if (tb->interfaces) {
3170 klass->interface_count = mono_array_length (tb->interfaces);
3171 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3172 for (i = 0; i < klass->interface_count; ++i) {
3173 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3174 return_val_if_nok (error, FALSE);
3175 klass->interfaces [i] = mono_class_from_mono_type (iface);
3176 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3179 klass->interfaces_inited = 1;
3181 } else if (klass->generic_class){
3182 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3183 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3188 if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
3190 for (i = 0; i < klass->method.count; ++i) {
3191 MonoMethod *im = klass->methods [i];
3192 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3193 im->slot = slot_num++;
3196 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3197 mono_class_setup_interface_offsets (klass);
3198 mono_class_setup_interface_id (klass);
3202 * The generic vtable is needed even if image->run is not set since some
3203 * runtime code like ves_icall_Type_GetMethodsByName depends on
3204 * method->slot being defined.
3208 * tb->methods could not be freed since it is used for determining
3209 * overrides during dynamic vtable construction.
3216 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3218 mono_error_init (error);
3219 MonoClass *klass = mono_object_class (method);
3220 if (is_sr_mono_method (klass)) {
3221 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3222 return sr_method->method;
3224 if (is_sre_method_builder (klass)) {
3225 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3228 if (mono_is_sre_method_on_tb_inst (klass)) {
3229 MonoClass *handle_class;
3231 MonoMethod *result = mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3232 return_val_if_nok (error, NULL);
3237 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3242 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3244 MonoReflectionTypeBuilder *tb;
3246 MonoReflectionMethod *m;
3248 mono_error_init (error);
3252 g_assert (image_is_dynamic (klass->image));
3254 if (!mono_class_get_ref_info (klass))
3257 g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
3259 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
3263 for (i = 0; i < tb->num_methods; ++i) {
3264 MonoReflectionMethodBuilder *mb =
3265 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3266 if (mb->override_methods)
3267 onum += mono_array_length (mb->override_methods);
3272 *overrides = g_new0 (MonoMethod*, onum * 2);
3275 for (i = 0; i < tb->num_methods; ++i) {
3276 MonoReflectionMethodBuilder *mb =
3277 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3278 if (mb->override_methods) {
3279 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3280 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3282 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3283 return_if_nok (error);
3284 (*overrides) [onum * 2 + 1] = mb->mhandle;
3286 g_assert (mb->mhandle);
3294 *num_overrides = onum;
3298 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3300 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3301 MonoReflectionFieldBuilder *fb;
3302 MonoClassField *field;
3303 MonoImage *image = klass->image;
3306 guint32 len, idx, real_size = 0;
3308 klass->field.count = tb->num_fields;
3309 klass->field.first = 0;
3311 mono_error_init (error);
3313 if (tb->class_size) {
3314 if ((tb->packing_size & 0xffffff00) != 0) {
3315 char *err_msg = mono_image_strdup_printf (klass->image, "Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
3316 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
3319 klass->packing_size = tb->packing_size;
3320 real_size = klass->instance_size + tb->class_size;
3323 if (!klass->field.count) {
3324 klass->instance_size = MAX (klass->instance_size, real_size);
3328 klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
3329 mono_class_alloc_ext (klass);
3330 klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
3332 This is, guess what, a hack.
3333 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3334 On the static path no field class is resolved, only types are built. This is the right thing to do
3336 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3338 klass->size_inited = 1;
3340 for (i = 0; i < klass->field.count; ++i) {
3341 MonoArray *rva_data;
3342 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3343 field = &klass->fields [i];
3344 field->name = mono_string_to_utf8_image (image, fb->name, error);
3345 if (!mono_error_ok (error))
3348 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3349 return_if_nok (error);
3350 field->type = mono_metadata_type_dup (klass->image, type);
3351 field->type->attrs = fb->attrs;
3353 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3354 return_if_nok (error);
3357 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3358 char *base = mono_array_addr (rva_data, char, 0);
3359 size_t size = mono_array_length (rva_data);
3360 char *data = (char *)mono_image_alloc (klass->image, size);
3361 memcpy (data, base, size);
3362 klass->ext->field_def_values [i].data = data;
3364 if (fb->offset != -1)
3365 field->offset = fb->offset;
3366 field->parent = klass;
3368 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3370 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
3371 klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
3373 if (fb->def_value) {
3374 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3375 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3376 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
3377 /* Copy the data from the blob since it might get realloc-ed */
3378 p = assembly->blob.data + idx;
3379 len = mono_metadata_decode_blob_size (p, &p2);
3381 klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
3382 memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
3386 klass->instance_size = MAX (klass->instance_size, real_size);
3387 mono_class_layout_fields (klass, klass->instance_size);
3391 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3393 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3394 MonoReflectionPropertyBuilder *pb;
3395 MonoImage *image = klass->image;
3396 MonoProperty *properties;
3399 mono_error_init (error);
3402 klass->ext = image_g_new0 (image, MonoClassExt, 1);
3404 klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
3405 klass->ext->property.first = 0;
3407 properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
3408 klass->ext->properties = properties;
3409 for (i = 0; i < klass->ext->property.count; ++i) {
3410 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3411 properties [i].parent = klass;
3412 properties [i].attrs = pb->attrs;
3413 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
3414 if (!mono_error_ok (error))
3417 properties [i].get = pb->get_method->mhandle;
3419 properties [i].set = pb->set_method->mhandle;
3421 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3422 if (pb->def_value) {
3425 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3426 if (!klass->ext->prop_def_values)
3427 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
3428 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3429 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
3430 /* Copy the data from the blob since it might get realloc-ed */
3431 p = assembly->blob.data + idx;
3432 len = mono_metadata_decode_blob_size (p, &p2);
3434 klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
3435 memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
3441 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3443 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3444 MonoReflectionEventBuilder *eb;
3445 MonoImage *image = klass->image;
3449 mono_error_init (error);
3452 klass->ext = image_g_new0 (image, MonoClassExt, 1);
3454 klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
3455 klass->ext->event.first = 0;
3457 events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
3458 klass->ext->events = events;
3459 for (i = 0; i < klass->ext->event.count; ++i) {
3460 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3461 events [i].parent = klass;
3462 events [i].attrs = eb->attrs;
3463 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
3464 if (!mono_error_ok (error))
3467 events [i].add = eb->add_method->mhandle;
3468 if (eb->remove_method)
3469 events [i].remove = eb->remove_method->mhandle;
3470 if (eb->raise_method)
3471 events [i].raise = eb->raise_method->mhandle;
3473 #ifndef MONO_SMALL_CONFIG
3474 if (eb->other_methods) {
3476 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3477 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3478 MonoReflectionMethodBuilder *mb =
3479 mono_array_get (eb->other_methods,
3480 MonoReflectionMethodBuilder*, j);
3481 events [i].other [j] = mb->mhandle;
3485 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3489 struct remove_instantiations_user_data
3496 remove_instantiations_of_and_ensure_contents (gpointer key,
3500 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3501 MonoType *type = (MonoType*)key;
3502 MonoClass *klass = data->klass;
3503 gboolean already_failed = !is_ok (data->error);
3505 MonoError *error = already_failed ? &lerror : data->error;
3507 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3508 MonoClass *inst_klass = mono_class_from_mono_type (type);
3509 //Ensure it's safe to use it.
3510 if (!fix_partial_generic_class (inst_klass, error)) {
3511 mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3512 // Marked the class with failure, but since some other instantiation already failed,
3513 // just report that one, and swallow the error from this one.
3515 mono_error_cleanup (error);
3523 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
3528 MonoReflectionType* res;
3531 mono_error_init (&error);
3533 domain = mono_object_domain (tb);
3534 klass = mono_class_from_mono_type (tb->type.type);
3536 mono_save_custom_attrs (klass->image, klass, tb->cattrs);
3539 * we need to lock the domain because the lock will be taken inside
3540 * So, we need to keep the locking order correct.
3542 mono_loader_lock ();
3543 mono_domain_lock (domain);
3544 if (klass->wastypebuilder) {
3545 mono_domain_unlock (domain);
3546 mono_loader_unlock ();
3548 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3549 mono_error_set_pending_exception (&error);
3554 * Fields to set in klass:
3555 * the various flags: delegate/unicode/contextbound etc.
3557 klass->flags = tb->attrs;
3558 klass->has_cctor = 1;
3560 mono_class_setup_parent (klass, klass->parent);
3561 /* fool mono_class_setup_supertypes */
3562 klass->supertypes = NULL;
3563 mono_class_setup_supertypes (klass);
3564 mono_class_setup_mono_type (klass);
3566 /* enums are done right away */
3567 if (!klass->enumtype)
3568 if (!ensure_runtime_vtable (klass, &error))
3572 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3573 MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
3574 mono_class_alloc_ext (klass);
3575 MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
3576 if (!is_ok (&error)) goto failure;
3577 klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
3581 klass->nested_classes_inited = TRUE;
3583 /* fields and object layout */
3584 if (klass->parent) {
3585 if (!klass->parent->size_inited)
3586 mono_class_init (klass->parent);
3587 klass->instance_size = klass->parent->instance_size;
3588 klass->sizes.class_size = 0;
3589 klass->min_align = klass->parent->min_align;
3590 /* if the type has no fields we won't call the field_setup
3591 * routine which sets up klass->has_references.
3593 klass->has_references |= klass->parent->has_references;
3595 klass->instance_size = sizeof (MonoObject);
3596 klass->min_align = 1;
3599 /* FIXME: handle packing_size and instance_size */
3600 typebuilder_setup_fields (klass, &error);
3601 if (!mono_error_ok (&error))
3603 typebuilder_setup_properties (klass, &error);
3604 if (!mono_error_ok (&error))
3607 typebuilder_setup_events (klass, &error);
3608 if (!mono_error_ok (&error))
3611 klass->wastypebuilder = TRUE;
3614 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3615 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3616 * we want to return normal System.MonoType objects, so clear these out from the cache.
3618 * Together with this we must ensure the contents of all instances to match the created type.
3620 if (domain->type_hash && klass->generic_container) {
3621 struct remove_instantiations_user_data data;
3623 data.error = &error;
3624 mono_error_assert_ok (&error);
3625 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3626 if (!is_ok (&error))
3630 mono_domain_unlock (domain);
3631 mono_loader_unlock ();
3633 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3634 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3635 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
3636 goto failure_unlocked;
3639 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3640 if (!is_ok (&error))
3641 goto failure_unlocked;
3643 g_assert (res != (MonoReflectionType*)tb);
3648 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3649 klass->wastypebuilder = TRUE;
3650 mono_domain_unlock (domain);
3651 mono_loader_unlock ();
3653 mono_error_set_pending_exception (&error);
3658 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
3662 mono_error_init (error);
3664 image = &gparam->tbuilder->module->dynamic_image->image;
3666 if (gparam->mbuilder) {
3667 if (!gparam->mbuilder->generic_container) {
3668 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
3669 return_val_if_nok (error, FALSE);
3671 MonoClass *klass = mono_class_from_mono_type (tb);
3672 gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3673 gparam->mbuilder->generic_container->is_method = TRUE;
3675 * Cannot set owner.method, since the MonoMethod is not created yet.
3676 * Set the image field instead, so type_in_image () works.
3678 gparam->mbuilder->generic_container->is_anonymous = TRUE;
3679 gparam->mbuilder->generic_container->owner.image = klass->image;
3681 } else if (gparam->tbuilder) {
3682 if (!gparam->tbuilder->generic_container) {
3683 MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
3684 return_val_if_nok (error, FALSE);
3685 MonoClass *klass = mono_class_from_mono_type (tb);
3686 gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3687 gparam->tbuilder->generic_container->owner.klass = klass;
3695 ves_icall_GenericTypeParameterBuilder_initialize (MonoReflectionGenericParam *gparam)
3698 (void) reflection_initialize_generic_parameter (gparam, &error);
3699 mono_error_set_pending_exception (&error);
3706 } DynamicMethodReleaseData;
3709 * The runtime automatically clean up those after finalization.
3711 static MonoReferenceQueue *dynamic_method_queue;
3714 free_dynamic_method (void *dynamic_method)
3716 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3717 MonoDomain *domain = data->domain;
3718 MonoMethod *method = data->handle;
3721 mono_domain_lock (domain);
3722 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3723 g_hash_table_remove (domain->method_to_dyn_method, method);
3724 mono_domain_unlock (domain);
3725 g_assert (dis_link);
3726 mono_gchandle_free (dis_link);
3728 mono_runtime_free_method (domain, method);
3733 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
3735 MonoReferenceQueue *queue;
3737 DynamicMethodReleaseData *release_data;
3738 ReflectionMethodBuilder rmb;
3739 MonoMethodSignature *sig;
3745 mono_error_init (error);
3747 if (mono_runtime_is_shutting_down ()) {
3748 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3752 if (!(queue = dynamic_method_queue)) {
3753 mono_loader_lock ();
3754 if (!(queue = dynamic_method_queue))
3755 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3756 mono_loader_unlock ();
3759 sig = dynamic_method_to_signature (mb, error);
3760 return_val_if_nok (error, FALSE);
3762 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3765 * Resolve references.
3768 * Every second entry in the refs array is reserved for storing handle_class,
3769 * which is needed by the ldtoken implementation in the JIT.
3771 rmb.nrefs = mb->nrefs;
3772 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3773 for (i = 0; i < mb->nrefs; i += 2) {
3774 MonoClass *handle_class;
3776 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3778 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3779 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3781 * The referenced DynamicMethod should already be created by the managed
3782 * code, except in the case of circular references. In that case, we store
3783 * method in the refs array, and fix it up later when the referenced
3784 * DynamicMethod is created.
3786 if (method->mhandle) {
3787 ref = method->mhandle;
3789 /* FIXME: GC object stored in unmanaged memory */
3792 /* FIXME: GC object stored in unmanaged memory */
3793 method->referenced_by = g_slist_append (method->referenced_by, mb);
3795 handle_class = mono_defaults.methodhandle_class;
3797 MonoException *ex = NULL;
3798 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3799 if (!is_ok (error)) {
3804 ex = mono_get_exception_type_load (NULL, NULL);
3805 else if (mono_security_core_clr_enabled ())
3806 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3810 mono_error_set_exception_instance (error, ex);
3815 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3816 rmb.refs [i + 1] = handle_class;
3820 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3821 if (!is_ok (error)) {
3825 klass = mono_class_from_mono_type (owner_type);
3827 klass = mono_defaults.object_class;
3830 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3832 return_val_if_nok (error, FALSE);
3834 release_data = g_new (DynamicMethodReleaseData, 1);
3835 release_data->handle = handle;
3836 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3837 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3838 g_free (release_data);
3840 /* Fix up refs entries pointing at us */
3841 for (l = mb->referenced_by; l; l = l->next) {
3842 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3843 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3846 g_assert (method->mhandle);
3848 data = (gpointer*)wrapper->method_data;
3849 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3850 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3851 data [i + 1] = mb->mhandle;
3854 g_slist_free (mb->referenced_by);
3856 /* ilgen is no longer needed */
3859 domain = mono_domain_get ();
3860 mono_domain_lock (domain);
3861 if (!domain->method_to_dyn_method)
3862 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3863 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3864 mono_domain_unlock (domain);
3870 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
3873 (void) reflection_create_dynamic_method (mb, &error);
3874 mono_error_set_pending_exception (&error);
3877 #endif /* DISABLE_REFLECTION_EMIT */
3879 MonoMethodSignature *
3880 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3882 MonoMethodSignature *sig;
3883 g_assert (image_is_dynamic (image));
3885 mono_error_init (error);
3887 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
3891 return mono_method_signature_checked (method, error);
3894 #ifndef DISABLE_REFLECTION_EMIT
3897 * ensure_complete_type:
3899 * Ensure that KLASS is completed if it is a dynamic type, or references
3903 ensure_complete_type (MonoClass *klass, MonoError *error)
3905 mono_error_init (error);
3907 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
3908 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3910 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3911 return_if_nok (error);
3913 // Asserting here could break a lot of code
3914 //g_assert (klass->wastypebuilder);
3917 if (klass->generic_class) {
3918 MonoGenericInst *inst = klass->generic_class->context.class_inst;
3921 for (i = 0; i < inst->type_argc; ++i) {
3922 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
3923 return_if_nok (error);
3929 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
3931 MonoClass *oklass = obj->vtable->klass;
3932 gpointer result = NULL;
3934 mono_error_init (error);
3936 if (strcmp (oklass->name, "String") == 0) {
3937 result = mono_string_intern_checked ((MonoString*)obj, error);
3938 return_val_if_nok (error, NULL);
3939 *handle_class = mono_defaults.string_class;
3941 } else if (strcmp (oklass->name, "RuntimeType") == 0) {
3942 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
3943 return_val_if_nok (error, NULL);
3944 MonoClass *mc = mono_class_from_mono_type (type);
3945 if (!mono_class_init (mc)) {
3946 mono_error_set_for_class_failure (error, mc);
3951 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
3952 return_val_if_nok (error, NULL);
3954 result = mono_class_from_mono_type (inflated);
3955 mono_metadata_free_type (inflated);
3957 result = mono_class_from_mono_type (type);
3959 *handle_class = mono_defaults.typehandle_class;
3961 } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
3962 strcmp (oklass->name, "MonoCMethod") == 0) {
3963 result = ((MonoReflectionMethod*)obj)->method;
3965 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
3966 mono_error_assert_ok (error);
3968 *handle_class = mono_defaults.methodhandle_class;
3970 } else if (strcmp (oklass->name, "MonoField") == 0) {
3971 MonoClassField *field = ((MonoReflectionField*)obj)->field;
3973 ensure_complete_type (field->parent, error);
3974 return_val_if_nok (error, NULL);
3977 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
3978 return_val_if_nok (error, NULL);
3980 MonoClass *klass = mono_class_from_mono_type (inflated);
3981 MonoClassField *inflated_field;
3982 gpointer iter = NULL;
3983 mono_metadata_free_type (inflated);
3984 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
3985 if (!strcmp (field->name, inflated_field->name))
3988 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
3989 result = inflated_field;
3993 *handle_class = mono_defaults.fieldhandle_class;
3995 } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
3996 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
3997 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3998 return_val_if_nok (error, NULL);
4001 klass = type->data.klass;
4002 if (klass->wastypebuilder) {
4003 /* Already created */
4007 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4008 return_val_if_nok (error, NULL);
4009 result = type->data.klass;
4012 *handle_class = mono_defaults.typehandle_class;
4013 } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
4014 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4015 MonoMethodSignature *sig;
4018 if (helper->arguments)
4019 nargs = mono_array_length (helper->arguments);
4023 sig = mono_metadata_signature_alloc (image, nargs);
4024 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4025 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4027 if (helper->unmanaged_call_conv) { /* unmanaged */
4028 sig->call_convention = helper->unmanaged_call_conv - 1;
4029 sig->pinvoke = TRUE;
4030 } else if (helper->call_conv & 0x02) {
4031 sig->call_convention = MONO_CALL_VARARG;
4033 sig->call_convention = MONO_CALL_DEFAULT;
4036 sig->param_count = nargs;
4037 /* TODO: Copy type ? */
4038 sig->ret = helper->return_type->type;
4039 for (i = 0; i < nargs; ++i) {
4040 sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
4041 if (!is_ok (error)) {
4042 image_g_free (image, sig);
4048 *handle_class = NULL;
4049 } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4050 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4051 /* Already created by the managed code */
4052 g_assert (method->mhandle);
4053 result = method->mhandle;
4054 *handle_class = mono_defaults.methodhandle_class;
4055 } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4056 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4063 mtype = mono_reflection_type_get_handle (m->parent, error);
4064 return_val_if_nok (error, NULL);
4065 klass = mono_class_from_mono_type (mtype);
4067 /* Find the method */
4069 name = mono_string_to_utf8_checked (m->name, error);
4070 return_val_if_nok (error, NULL);
4072 while ((method = mono_class_get_methods (klass, &iter))) {
4073 if (!strcmp (method->name, name))
4080 // FIXME: Check parameters/return value etc. match
4083 *handle_class = mono_defaults.methodhandle_class;
4084 } else if (is_sre_method_builder (oklass) ||
4085 mono_is_sre_ctor_builder (oklass) ||
4086 is_sre_field_builder (oklass) ||
4087 is_sre_gparam_builder (oklass) ||
4088 is_sre_generic_instance (oklass) ||
4089 is_sre_array (oklass) ||
4090 is_sre_byref (oklass) ||
4091 is_sre_pointer (oklass) ||
4092 !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4093 !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4094 !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4095 static MonoMethod *resolve_method;
4096 if (!resolve_method) {
4097 MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4099 mono_memory_barrier ();
4104 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4105 mono_error_assert_ok (error);
4107 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
4109 g_print ("%s\n", obj->vtable->klass->name);
4110 g_assert_not_reached ();
4115 #else /* DISABLE_REFLECTION_EMIT */
4118 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4120 g_assert_not_reached ();
4125 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
4127 g_assert_not_reached ();
4131 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
4133 g_assert_not_reached ();
4138 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4140 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4144 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
4146 g_assert_not_reached ();
4150 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
4152 g_assert_not_reached ();
4157 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
4159 g_assert_not_reached ();
4164 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
4165 gboolean create_open_instance, gboolean register_token, MonoError *error)
4167 g_assert_not_reached ();
4172 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4174 mono_error_init (error);
4180 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4182 g_assert_not_reached ();
4187 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
4189 g_assert_not_reached ();
4193 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4198 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4200 mono_error_init (error);
4206 #endif /* DISABLE_REFLECTION_EMIT */
4208 #ifndef DISABLE_REFLECTION_EMIT
4210 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
4215 tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
4216 return_val_if_nok (error, NULL);
4217 klass = mono_class_from_mono_type (tb);
4219 return methodbuilder_to_mono_method (klass, mb, error);
4221 #else /* DISABLE_REFLECTION_EMIT */
4223 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
4225 g_assert_not_reached ();
4228 #endif /* DISABLE_REFLECTION_EMIT */
4231 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
4233 MONO_CHECK_ARG_NULL (obj, 0);
4236 gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
4237 mono_error_set_pending_exception (&error);
4242 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
4243 MonoReflectionMethod *method,
4244 MonoArray *opt_param_types)
4246 MONO_CHECK_ARG_NULL (method, 0);
4249 gint32 result = mono_image_create_method_token (
4250 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
4251 mono_error_set_pending_exception (&error);
4256 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4259 mono_image_create_pefile (mb, file, &error);
4260 mono_error_set_pending_exception (&error);
4264 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4267 mono_image_build_metadata (mb, &error);
4268 mono_error_set_pending_exception (&error);
4272 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
4274 mono_image_register_token (mb->dynamic_image, token, obj);
4278 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
4282 mono_loader_lock ();
4283 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
4284 mono_loader_unlock ();
4290 * ves_icall_TypeBuilder_create_generic_class:
4291 * @tb: a TypeBuilder object
4294 * Creates the generic class after all generic parameters have been added.
4297 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
4300 (void) mono_reflection_create_generic_class (tb, &error);
4301 mono_error_set_pending_exception (&error);
4304 #ifndef DISABLE_REFLECTION_EMIT
4306 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4309 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4310 mono_error_set_pending_exception (&error);
4316 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4318 mono_reflection_dynimage_basic_init (assemblyb);
4322 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
4323 MonoReflectionType *t)
4325 enumtype->type = t->type;
4329 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
4331 mono_image_module_basic_init (moduleb);
4335 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
4337 return mono_image_insert_string (module, str);
4341 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
4343 MonoDynamicImage *image = moduleb->dynamic_image;
4345 g_assert (type->type);
4346 image->wrappers_type = mono_class_from_mono_type (type->type);