3 * Routines for creating an image at runtime
4 * and related System.Reflection.Emit icalls
8 * Paolo Molaro (lupus@ximian.com)
10 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
12 * Copyright 2011 Rodrigo Kumpera
13 * Copyright 2016 Microsoft
15 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
19 #include "mono/metadata/assembly.h"
20 #include "mono/metadata/debug-helpers.h"
21 #include "mono/metadata/dynamic-image-internals.h"
22 #include "mono/metadata/dynamic-stream-internals.h"
23 #include "mono/metadata/exception.h"
24 #include "mono/metadata/gc-internals.h"
25 #include "mono/metadata/mono-ptr-array.h"
26 #include "mono/metadata/object-internals.h"
27 #include "mono/metadata/profiler-private.h"
28 #include "mono/metadata/reflection-internals.h"
29 #include "mono/metadata/reflection-cache.h"
30 #include "mono/metadata/sre-internals.h"
31 #include "mono/metadata/custom-attrs-internals.h"
32 #include "mono/metadata/security-manager.h"
33 #include "mono/metadata/security-core-clr.h"
34 #include "mono/metadata/tabledefs.h"
35 #include "mono/metadata/tokentype.h"
36 #include "mono/utils/checked-build.h"
37 #include "mono/utils/mono-digest.h"
38 #include "mono/utils/w32api.h"
40 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, "System.Runtime.InteropServices", "MarshalAsAttribute");
41 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", "ModuleBuilder");
43 static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
45 #ifndef DISABLE_REFLECTION_EMIT
46 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
47 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
48 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
49 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
50 static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
51 static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
54 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
57 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
58 static MonoReflectionTypeHandle mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error);
59 static gboolean is_sre_array (MonoClass *klass);
60 static gboolean is_sre_byref (MonoClass *klass);
61 static gboolean is_sre_pointer (MonoClass *klass);
62 static gboolean is_sre_generic_instance (MonoClass *klass);
63 static gboolean is_sre_type_builder (MonoClass *klass);
64 static gboolean is_sre_method_builder (MonoClass *klass);
65 static gboolean is_sre_field_builder (MonoClass *klass);
66 static gboolean is_sre_gparam_builder (MonoClass *klass);
67 static gboolean is_sre_enum_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);
73 static guint32 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error);
76 #ifndef DISABLE_REFLECTION_EMIT
77 static MonoType* mono_type_array_get_and_resolve_raw (MonoArray* array, int idx, MonoError* error);
80 static gboolean mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module, MonoError *error);
83 mono_reflection_emit_init (void)
85 mono_dynamic_images_init ();
89 string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
91 /* FIXME all callers to string_to_utf8_image_raw should use handles */
92 HANDLE_FUNCTION_ENTER ();
95 MONO_HANDLE_DCL (MonoString, s);
96 result = mono_string_to_utf8_image (image, s, error);
97 HANDLE_FUNCTION_RETURN_VAL (result);
101 type_get_fully_qualified_name (MonoType *type)
103 MONO_REQ_GC_NEUTRAL_MODE;
105 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
109 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
111 MONO_REQ_GC_UNSAFE_MODE;
116 klass = mono_class_from_mono_type (type);
118 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
119 ta = klass->image->assembly;
120 if (assembly_is_dynamic (ta) || (ta == ass)) {
121 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
122 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
123 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
125 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
128 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
131 #ifndef DISABLE_REFLECTION_EMIT
135 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
139 image_g_malloc (MonoImage *image, guint size)
141 MONO_REQ_GC_NEUTRAL_MODE;
144 return mono_image_alloc (image, size);
146 return g_malloc (size);
148 #endif /* !DISABLE_REFLECTION_EMIT */
153 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
157 mono_image_g_malloc0 (MonoImage *image, guint size)
159 MONO_REQ_GC_NEUTRAL_MODE;
162 return mono_image_alloc0 (image, size);
164 return g_malloc0 (size);
169 * @image: a MonoImage
172 * If @image is NULL, free @ptr, otherwise do nothing.
175 image_g_free (MonoImage *image, gpointer ptr)
181 #ifndef DISABLE_REFLECTION_EMIT
183 image_strdup (MonoImage *image, const char *s)
185 MONO_REQ_GC_NEUTRAL_MODE;
188 return mono_image_strdup (image, s);
194 #define image_g_new(image,struct_type, n_structs) \
195 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
197 #define image_g_new0(image,struct_type, n_structs) \
198 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
202 alloc_table (MonoDynamicTable *table, guint nrows)
204 mono_dynimage_alloc_table (table, nrows);
208 string_heap_insert (MonoDynamicStream *sh, const char *str)
210 return mono_dynstream_insert_string (sh, str);
214 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
216 return mono_dynstream_add_data (stream, data, len);
220 * Despite the name, we handle also TypeSpec (with the above helper).
223 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
225 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
229 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
230 * dest may be misaligned.
233 swap_with_size (char *dest, const char* val, int len, int nelem) {
234 MONO_REQ_GC_NEUTRAL_MODE;
235 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
238 for (elem = 0; elem < nelem; ++elem) {
264 g_assert_not_reached ();
270 memcpy (dest, val, len * nelem);
275 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
277 MONO_REQ_GC_UNSAFE_MODE;
279 guint32 num_clauses = 0;
282 MonoILExceptionInfo *ex_info;
283 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
284 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
285 if (ex_info->handlers)
286 num_clauses += mono_array_length (ex_info->handlers);
294 #ifndef DISABLE_REFLECTION_EMIT
295 static MonoExceptionClause*
296 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
298 MONO_REQ_GC_UNSAFE_MODE;
302 MonoExceptionClause *clauses;
303 MonoExceptionClause *clause;
304 MonoILExceptionInfo *ex_info;
305 MonoILExceptionBlock *ex_block;
306 guint32 finally_start;
307 int i, j, clause_index;;
309 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
312 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
313 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
314 finally_start = ex_info->start + ex_info->len;
315 if (!ex_info->handlers)
317 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
318 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
319 clause = &(clauses [clause_index]);
321 clause->flags = ex_block->type;
322 clause->try_offset = ex_info->start;
324 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
325 clause->try_len = finally_start - ex_info->start;
327 clause->try_len = ex_info->len;
328 clause->handler_offset = ex_block->start;
329 clause->handler_len = ex_block->len;
330 if (ex_block->extype) {
331 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
333 if (!is_ok (error)) {
334 image_g_free (image, clauses);
337 clause->data.catch_class = mono_class_from_mono_type (extype);
339 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
340 clause->data.filter_offset = ex_block->filter_offset;
342 clause->data.filter_offset = 0;
344 finally_start = ex_block->start + ex_block->len;
352 #endif /* !DISABLE_REFLECTION_EMIT */
354 #ifndef DISABLE_REFLECTION_EMIT
356 * LOCKING: Acquires the loader lock.
359 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
361 MONO_REQ_GC_UNSAFE_MODE;
363 MonoCustomAttrInfo *ainfo, *tmp;
365 if (!cattrs || !mono_array_length (cattrs))
368 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
371 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
373 mono_custom_attrs_free (tmp);
374 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
375 mono_loader_unlock ();
379 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
381 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
387 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
389 MONO_REQ_GC_UNSAFE_MODE;
391 MonoDynamicTable *table;
394 guint32 cols [MONO_ASSEMBLY_SIZE];
398 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
401 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
402 table = &assembly->tables [MONO_TABLE_MODULEREF];
403 token = table->next_idx ++;
405 alloc_table (table, table->rows);
406 values = table->values + token * MONO_MODULEREF_SIZE;
407 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
409 token <<= MONO_RESOLUTION_SCOPE_BITS;
410 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
411 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
416 if (assembly_is_dynamic (image->assembly))
418 memset (cols, 0, sizeof (cols));
420 /* image->assembly->image is the manifest module */
421 image = image->assembly->image;
422 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
425 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
426 token = table->next_idx ++;
428 alloc_table (table, table->rows);
429 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
430 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
431 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
432 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
433 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
434 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
435 values [MONO_ASSEMBLYREF_FLAGS] = 0;
436 values [MONO_ASSEMBLYREF_CULTURE] = 0;
437 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
439 if (strcmp ("", image->assembly->aname.culture)) {
440 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
441 image->assembly->aname.culture);
444 if ((pubkey = mono_image_get_public_key (image, &publen))) {
447 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
448 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
450 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
452 token <<= MONO_RESOLUTION_SCOPE_BITS;
453 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
454 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
458 #ifndef DISABLE_REFLECTION_EMIT
460 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
462 MONO_REQ_GC_UNSAFE_MODE;
465 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
467 rmb->ilgen = mb->ilgen;
468 rmb->rtype = (MonoReflectionType*)mb->rtype;
469 return_val_if_nok (error, FALSE);
470 rmb->parameters = mb->parameters;
471 rmb->generic_params = mb->generic_params;
472 rmb->generic_container = mb->generic_container;
473 rmb->opt_types = NULL;
474 rmb->pinfo = mb->pinfo;
475 rmb->attrs = mb->attrs;
476 rmb->iattrs = mb->iattrs;
477 rmb->call_conv = mb->call_conv;
478 rmb->code = mb->code;
479 rmb->type = mb->type;
480 rmb->name = mb->name;
481 rmb->table_idx = &mb->table_idx;
482 rmb->init_locals = mb->init_locals;
483 rmb->skip_visibility = FALSE;
484 rmb->return_modreq = mb->return_modreq;
485 rmb->return_modopt = mb->return_modopt;
486 rmb->param_modreq = mb->param_modreq;
487 rmb->param_modopt = mb->param_modopt;
488 rmb->permissions = mb->permissions;
489 rmb->mhandle = mb->mhandle;
494 rmb->charset = mb->charset;
495 rmb->extra_flags = mb->extra_flags;
496 rmb->native_cc = mb->native_cc;
497 rmb->dllentry = mb->dllentry;
505 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
507 MONO_REQ_GC_UNSAFE_MODE;
509 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
513 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
515 rmb->ilgen = mb->ilgen;
516 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
517 return_val_if_nok (error, FALSE);
518 rmb->parameters = mb->parameters;
519 rmb->generic_params = NULL;
520 rmb->generic_container = NULL;
521 rmb->opt_types = NULL;
522 rmb->pinfo = mb->pinfo;
523 rmb->attrs = mb->attrs;
524 rmb->iattrs = mb->iattrs;
525 rmb->call_conv = mb->call_conv;
527 rmb->type = mb->type;
528 rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
529 return_val_if_nok (error, FALSE);
530 rmb->table_idx = &mb->table_idx;
531 rmb->init_locals = mb->init_locals;
532 rmb->skip_visibility = FALSE;
533 rmb->return_modreq = NULL;
534 rmb->return_modopt = NULL;
535 rmb->param_modreq = mb->param_modreq;
536 rmb->param_modopt = mb->param_modopt;
537 rmb->permissions = mb->permissions;
538 rmb->mhandle = mb->mhandle;
546 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
548 MONO_REQ_GC_UNSAFE_MODE;
550 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
552 rmb->ilgen = mb->ilgen;
553 rmb->rtype = mb->rtype;
554 rmb->parameters = mb->parameters;
555 rmb->generic_params = NULL;
556 rmb->generic_container = NULL;
557 rmb->opt_types = NULL;
559 rmb->attrs = mb->attrs;
561 rmb->call_conv = mb->call_conv;
563 rmb->type = (MonoObject *) mb->owner;
564 rmb->name = mb->name;
565 rmb->table_idx = NULL;
566 rmb->init_locals = mb->init_locals;
567 rmb->skip_visibility = mb->skip_visibility;
568 rmb->return_modreq = NULL;
569 rmb->return_modopt = NULL;
570 rmb->param_modreq = NULL;
571 rmb->param_modopt = NULL;
572 rmb->permissions = NULL;
573 rmb->mhandle = mb->mhandle;
577 #else /* DISABLE_REFLECTION_EMIT */
579 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
580 g_assert_not_reached ();
584 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
586 g_assert_not_reached ();
589 #endif /* DISABLE_REFLECTION_EMIT */
591 #ifndef DISABLE_REFLECTION_EMIT
593 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
595 MONO_REQ_GC_NEUTRAL_MODE;
597 MonoDynamicTable *table;
599 guint32 token, pclass;
601 switch (parent & MONO_TYPEDEFORREF_MASK) {
602 case MONO_TYPEDEFORREF_TYPEREF:
603 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
605 case MONO_TYPEDEFORREF_TYPESPEC:
606 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
608 case MONO_TYPEDEFORREF_TYPEDEF:
609 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
612 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
615 /* extract the index */
616 parent >>= MONO_TYPEDEFORREF_BITS;
618 table = &assembly->tables [MONO_TABLE_MEMBERREF];
620 if (assembly->save) {
621 alloc_table (table, table->rows + 1);
622 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
623 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
624 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
625 values [MONO_MEMBERREF_SIGNATURE] = sig;
628 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
635 * Insert a memberef row into the metadata: the token that point to the memberref
636 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
637 * mono_image_get_fieldref_token()).
638 * The sig param is an index to an already built signature.
641 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
643 MONO_REQ_GC_NEUTRAL_MODE;
645 guint32 parent = mono_image_typedef_or_ref (assembly, type);
646 return mono_image_add_memberef_row (assembly, parent, name, sig);
651 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
653 MONO_REQ_GC_NEUTRAL_MODE;
656 MonoMethodSignature *sig;
658 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
660 if (create_typespec) {
661 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
666 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
667 if (token && !create_typespec)
670 g_assert (!method->is_inflated);
673 * A methodref signature can't contain an unmanaged calling convention.
675 sig = mono_metadata_signature_dup (mono_method_signature (method));
676 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
677 sig->call_convention = MONO_CALL_DEFAULT;
678 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
679 method->name, mono_dynimage_encode_method_signature (assembly, sig));
681 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
684 if (create_typespec) {
685 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
686 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
687 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
689 if (assembly->save) {
692 alloc_table (table, table->rows + 1);
693 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
694 values [MONO_METHODSPEC_METHOD] = token;
695 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
698 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
700 /*methodspec and memberef tokens are diferent, */
701 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
708 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
709 const gchar *name, guint32 sig)
711 MonoDynamicTable *table;
715 table = &assembly->tables [MONO_TABLE_MEMBERREF];
717 if (assembly->save) {
718 alloc_table (table, table->rows + 1);
719 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
720 values [MONO_MEMBERREF_CLASS] = original;
721 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
722 values [MONO_MEMBERREF_SIGNATURE] = sig;
725 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
731 #else /* DISABLE_REFLECTION_EMIT */
734 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
736 g_assert_not_reached ();
742 is_field_on_inst (MonoClassField *field)
744 return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
747 #ifndef DISABLE_REFLECTION_EMIT
749 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
755 g_assert (field->parent);
757 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
761 if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
762 int index = field - field->parent->fields;
763 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
765 type = mono_field_get_type (field);
767 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
768 mono_field_get_name (field),
769 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
770 g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
775 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
777 MonoDynamicTable *table;
779 guint32 token, mtoken = 0, sig;
780 MonoMethodInflated *imethod;
781 MonoMethod *declaring;
783 table = &assembly->tables [MONO_TABLE_METHODSPEC];
785 g_assert (method->is_inflated);
786 imethod = (MonoMethodInflated *) method;
787 declaring = imethod->declaring;
789 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
790 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
792 if (!mono_method_signature (declaring)->generic_param_count)
795 switch (mono_metadata_token_table (mtoken)) {
796 case MONO_TABLE_MEMBERREF:
797 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
799 case MONO_TABLE_METHOD:
800 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
803 g_assert_not_reached ();
806 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
808 if (assembly->save) {
809 alloc_table (table, table->rows + 1);
810 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
811 values [MONO_METHODSPEC_METHOD] = mtoken;
812 values [MONO_METHODSPEC_SIGNATURE] = sig;
815 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
822 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
824 MonoMethodInflated *imethod;
827 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
831 g_assert (method->is_inflated);
832 imethod = (MonoMethodInflated *) method;
834 if (mono_method_signature (imethod->declaring)->generic_param_count) {
835 token = method_encode_methodspec (assembly, method);
837 guint32 sig = mono_dynimage_encode_method_signature (
838 assembly, mono_method_signature (imethod->declaring));
839 token = mono_image_get_memberref_token (
840 assembly, &method->klass->byval_arg, method->name, sig);
843 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
848 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
850 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
853 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
854 token = mono_image_get_memberref_token (
855 assembly, &m->klass->byval_arg, m->name, sig);
861 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
864 MonoDynamicTable *table;
869 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
870 idx = table->next_idx ++;
872 alloc_table (table, table->rows);
873 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
875 values [MONO_STAND_ALONE_SIGNATURE] =
876 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
877 return_val_if_nok (error, 0);
883 reflection_cc_to_file (int call_conv) {
884 switch (call_conv & 0x3) {
886 case 1: return MONO_CALL_DEFAULT;
887 case 2: return MONO_CALL_VARARG;
889 g_assert_not_reached ();
893 #endif /* !DISABLE_REFLECTION_EMIT */
895 struct _ArrayMethod {
897 MonoMethodSignature *sig;
903 mono_sre_array_method_free (ArrayMethod *am)
910 #ifndef DISABLE_REFLECTION_EMIT
912 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethodHandle m, MonoError *error)
914 MonoMethodSignature *sig = NULL;
919 MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
920 guint32 nparams = mono_array_handle_length (parameters);
921 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
923 sig->sentinelpos = -1;
924 sig->call_convention = reflection_cc_to_file (MONO_HANDLE_GETVAL (m, call_conv));
925 sig->param_count = nparams;
926 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW_GET (MonoReflectionType, m, ret);
927 if (!MONO_HANDLE_IS_NULL (ret)) {
928 sig->ret = mono_reflection_type_handle_mono_type (ret, error);
932 sig->ret = &mono_defaults.void_class->byval_arg;
934 MonoReflectionTypeHandle parent = MONO_HANDLE_NEW_GET (MonoReflectionType, m, parent);
935 MonoType *mtype = mono_reflection_type_handle_mono_type (parent, error);
939 for (int i = 0; i < nparams; ++i) {
940 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
945 MonoStringHandle mname = MONO_HANDLE_NEW_GET (MonoString, m, name);
946 name = mono_string_handle_to_utf8 (mname, error);
950 ArrayMethod *am = NULL;
951 for (GList *tmp = assembly->array_methods; tmp; tmp = tmp->next) {
952 am = (ArrayMethod *)tmp->data;
953 if (strcmp (name, am->name) == 0 &&
954 mono_metadata_type_equal (am->parent, mtype) &&
955 mono_metadata_signature_equal (am->sig, sig)) {
958 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
962 am = g_new0 (ArrayMethod, 1);
966 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
967 mono_dynimage_encode_method_signature (assembly, sig));
968 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
969 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
979 #ifndef DISABLE_REFLECTION_EMIT
982 * mono_image_insert_string:
983 * @module: module builder object
986 * Insert @str into the user string stream of @module.
989 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStringHandle str, MonoError *error)
991 HANDLE_FUNCTION_ENTER ();
997 MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
999 if (!mono_image_module_basic_init (ref_module, error))
1002 assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1004 g_assert (assembly != NULL);
1006 if (assembly->save) {
1007 int32_t length = mono_string_length (MONO_HANDLE_RAW (str));
1008 mono_metadata_encode_value (1 | (length * 2), b, &b);
1009 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1011 uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, str), TRUE);
1012 const char *p = (const char*)mono_string_chars (MONO_HANDLE_RAW (str));
1013 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1015 char *swapped = g_malloc (2 * length);
1017 swap_with_size (swapped, p, 2, length);
1018 mono_image_add_stream_data (&assembly->us, swapped, length * 2);
1022 mono_image_add_stream_data (&assembly->us, p, length * 2);
1024 mono_gchandle_free (gchandle);
1025 mono_image_add_stream_data (&assembly->us, "", 1);
1027 idx = assembly->us.index ++;
1030 token = MONO_TOKEN_STRING | idx;
1031 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
1034 HANDLE_FUNCTION_RETURN_VAL (token);
1038 create_method_token (MonoDynamicImage *assembly, MonoMethod *method, MonoArrayHandle opt_param_types, MonoError *error)
1040 guint32 sig_token, parent;
1043 int nargs = mono_array_handle_length (opt_param_types);
1044 MonoMethodSignature *old = mono_method_signature (method);
1045 MonoMethodSignature *sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1047 sig->hasthis = old->hasthis;
1048 sig->explicit_this = old->explicit_this;
1049 sig->call_convention = old->call_convention;
1050 sig->generic_param_count = old->generic_param_count;
1051 sig->param_count = old->param_count + nargs;
1052 sig->sentinelpos = old->param_count;
1053 sig->ret = old->ret;
1055 for (int i = 0; i < old->param_count; i++)
1056 sig->params [i] = old->params [i];
1058 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1059 for (int i = 0; i < nargs; i++) {
1060 MONO_HANDLE_ARRAY_GETREF (rt, opt_param_types, i);
1061 sig->params [old->param_count + i] = mono_reflection_type_handle_mono_type (rt, error);
1062 if (!is_ok (error)) goto fail;
1065 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1066 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1067 parent >>= MONO_TYPEDEFORREF_BITS;
1069 parent <<= MONO_MEMBERREF_PARENT_BITS;
1070 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1072 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1073 guint32 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1074 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1081 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
1087 MonoClass *klass = mono_handle_class (obj);
1088 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1089 MonoReflectionMethodHandle ref_method = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1090 MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
1091 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types) && (mono_method_signature (method)->sentinelpos >= 0));
1092 token = create_method_token (assembly, method, opt_param_types, error);
1095 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1096 g_assert_not_reached ();
1098 g_error ("requested method token for %s\n", klass->name);
1101 mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
1104 g_assert (!mono_error_ok (error));
1109 * mono_image_create_token:
1110 * @assembly: a dynamic assembly
1112 * @register_token: Whenever to register the token in the assembly->tokens hash.
1114 * Get a token to insert in the IL code stream for the given MemberInfo.
1115 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1116 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1120 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
1121 gboolean create_open_instance, gboolean register_token,
1124 HANDLE_FUNCTION_ENTER ();
1129 MonoClass *klass = mono_handle_class (obj);
1130 MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
1131 MONO_HANDLE_ASSIGN (register_obj, obj);
1133 /* Check for user defined reflection objects */
1134 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1135 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1136 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1140 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1141 int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
1143 if (strcmp (klass->name, "RuntimeType") == 0) {
1144 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
1147 MonoClass *mc = mono_class_from_mono_type (type);
1148 token = mono_metadata_token_from_dor (
1149 mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1150 /* If it's a RuntimeType now, we could have registered a
1151 * TypeBuilder for it before, so replacing is okay. */
1152 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1153 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1154 strcmp (klass->name, "MonoMethod") == 0) {
1155 MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1156 MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
1157 if (method->is_inflated) {
1158 if (create_open_instance)
1159 token = mono_image_get_methodspec_token (assembly, method);
1161 token = mono_image_get_inflated_method_token (assembly, method);
1162 } else if ((method->klass->image == &assembly->image) &&
1163 !mono_class_is_ginst (method->klass)) {
1164 static guint32 method_table_idx = 0xffffff;
1165 if (method->klass->wastypebuilder) {
1166 /* we use the same token as the one that was assigned
1167 * to the Methodbuilder.
1168 * FIXME: do the equivalent for Fields.
1170 token = method->token;
1171 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1174 * Each token should have a unique index, but the indexes are
1175 * assigned by managed code, so we don't know about them. An
1176 * easy solution is to count backwards...
1178 method_table_idx --;
1179 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1180 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1183 guint32 methodref_token = mono_image_get_methodref_token (assembly, method, create_open_instance);
1184 /* We need to register a 'canonical' object. The same
1185 * MonoMethod could have been reflected via different
1186 * classes so the MonoReflectionMethod:reftype could be
1187 * different, and the object lookup in
1188 * dynamic_image_register_token would assert assert. So
1189 * we pick the MonoReflectionMethod object that has the
1190 * reflected type as NULL (ie, take the declaring type
1192 MonoReflectionMethodHandle canonical_obj =
1193 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
1196 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1197 token = methodref_token;
1199 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1200 } else if (strcmp (klass->name, "MonoField") == 0) {
1201 MonoReflectionFieldHandle f = MONO_HANDLE_CAST (MonoReflectionField, obj);
1202 MonoClassField *field = MONO_HANDLE_GETVAL (f, field);
1203 if ((field->parent->image == &assembly->image) && !is_field_on_inst (field)) {
1204 static guint32 field_table_idx = 0xffffff;
1206 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1207 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1209 guint32 fieldref_token = mono_image_get_fieldref_token (assembly, field);
1210 /* Same as methodref: get a canonical object to
1211 * register with the token. */
1212 MonoReflectionFieldHandle canonical_obj =
1213 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj), field->parent, field, error);
1216 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1217 token = fieldref_token;
1219 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1220 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1221 MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
1222 /* always returns a fresh token */
1223 guint32 array_token = mono_image_get_array_token (assembly, m, error);
1226 token = array_token;
1227 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1228 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1229 MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
1230 /* always returns a fresh token */
1231 guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1235 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1237 g_error ("requested token for %s\n", klass->name);
1241 mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
1244 HANDLE_FUNCTION_RETURN_VAL (token);
1250 #ifndef DISABLE_REFLECTION_EMIT
1253 assemblybuilderaccess_can_refonlyload (guint32 access)
1255 return (access & 0x4) != 0;
1259 assemblybuilderaccess_can_run (guint32 access)
1261 return (access & MonoAssemblyBuilderAccess_Run) != 0;
1265 assemblybuilderaccess_can_save (guint32 access)
1267 return (access & MonoAssemblyBuilderAccess_Save) != 0;
1272 * mono_reflection_dynimage_basic_init:
1273 * @assembly: an assembly builder object
1275 * Create the MonoImage that represents the assembly builder and setup some
1276 * of the helper hash table and the basic metadata streams.
1279 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1282 MonoDynamicAssembly *assembly;
1283 MonoDynamicImage *image;
1284 MonoDomain *domain = mono_object_domain (assemblyb);
1286 if (assemblyb->dynamic_assembly)
1289 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1291 MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
1293 assembly->assembly.ref_count = 1;
1294 assembly->assembly.dynamic = TRUE;
1295 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1296 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1297 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1298 if (mono_error_set_pending_exception (&error))
1300 if (assemblyb->culture) {
1301 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1302 if (mono_error_set_pending_exception (&error))
1305 assembly->assembly.aname.culture = g_strdup ("");
1307 if (assemblyb->version) {
1308 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1309 if (mono_error_set_pending_exception (&error))
1311 char **version = g_strsplit (vstr, ".", 4);
1312 char **parts = version;
1313 assembly->assembly.aname.major = atoi (*parts++);
1314 assembly->assembly.aname.minor = atoi (*parts++);
1315 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1316 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1318 g_strfreev (version);
1321 assembly->assembly.aname.major = 0;
1322 assembly->assembly.aname.minor = 0;
1323 assembly->assembly.aname.build = 0;
1324 assembly->assembly.aname.revision = 0;
1327 assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
1328 assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
1329 assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
1330 assembly->domain = domain;
1332 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1333 if (mono_error_set_pending_exception (&error))
1335 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1336 image->initial_image = TRUE;
1337 assembly->assembly.aname.name = image->image.name;
1338 assembly->assembly.image = &image->image;
1339 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1340 /* -1 to correct for the trailing NULL byte */
1341 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1342 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1344 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1347 mono_domain_assemblies_lock (domain);
1348 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1349 mono_domain_assemblies_unlock (domain);
1351 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1353 MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
1355 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1358 #endif /* !DISABLE_REFLECTION_EMIT */
1360 #ifndef DISABLE_REFLECTION_EMIT
1362 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1364 return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1367 static MonoReflectionModuleBuilderHandle
1368 register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, MonoDynamicImage *module)
1370 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilderHandle, module, MONO_HANDLE_CAST (MonoObject, res), NULL);
1374 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1377 MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
1378 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
1379 MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
1380 MONO_HANDLE_GET (ab, moduleb, assemblyb);
1383 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1384 * we don't know which module it belongs to, since that is only
1385 * determined at assembly save time.
1387 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1388 MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name);
1389 char *name = mono_string_handle_to_utf8 (abname, error);
1390 return_val_if_nok (error, FALSE);
1391 MonoStringHandle modfqname = MONO_HANDLE_NEW_GET (MonoString, MONO_HANDLE_CAST (MonoReflectionModule, moduleb), fqname);
1392 char *fqname = mono_string_handle_to_utf8 (modfqname, error);
1393 if (!is_ok (error)) {
1397 MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly);
1398 image = mono_dynamic_image_create (dynamic_assembly, name, fqname);
1400 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image);
1401 MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image);
1402 register_module (domain, moduleb, image);
1404 /* register the module with the assembly */
1405 MonoImage *ass = dynamic_assembly->assembly.image;
1406 int module_count = ass->module_count;
1407 MonoImage **new_modules = g_new0 (MonoImage *, module_count + 1);
1410 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1411 new_modules [module_count] = &image->image;
1412 mono_image_addref (&image->image);
1414 g_free (ass->modules);
1415 ass->modules = new_modules;
1416 ass->module_count ++;
1422 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1425 return image_module_basic_init (moduleb, error);
1431 is_corlib_type (MonoClass *klass)
1433 return klass->image == mono_defaults.corlib;
1436 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1437 static MonoClass *cached_class; \
1439 return cached_class == _class; \
1440 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1441 cached_class = _class; \
1449 mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
1451 HANDLE_FUNCTION_ENTER();
1453 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1454 MONO_HANDLE_ARRAY_GETREF (t, array, idx);
1455 MonoType *result = mono_reflection_type_handle_mono_type (t, error);
1456 HANDLE_FUNCTION_RETURN_VAL (result);
1460 #ifndef DISABLE_REFLECTION_EMIT
1462 is_sre_array (MonoClass *klass)
1464 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1468 is_sre_byref (MonoClass *klass)
1470 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1474 is_sre_pointer (MonoClass *klass)
1476 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1480 is_sre_generic_instance (MonoClass *klass)
1482 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1486 is_sre_type_builder (MonoClass *klass)
1488 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1492 is_sre_method_builder (MonoClass *klass)
1494 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1498 mono_is_sre_ctor_builder (MonoClass *klass)
1500 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1504 is_sre_field_builder (MonoClass *klass)
1506 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1510 is_sre_gparam_builder (MonoClass *klass)
1512 check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1516 is_sre_enum_builder (MonoClass *klass)
1518 check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1522 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1524 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1528 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1530 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1533 static MonoReflectionTypeHandle
1534 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error)
1536 static MonoMethod *method_get_underlying_system_type = NULL;
1537 HANDLE_FUNCTION_ENTER ();
1541 if (!method_get_underlying_system_type)
1542 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1544 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1546 MonoMethod *usertype_method = mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject, t), method_get_underlying_system_type, error);
1550 MONO_HANDLE_ASSIGN (rt, MONO_HANDLE_NEW (MonoReflectionType, mono_runtime_invoke_checked (usertype_method, MONO_HANDLE_RAW (t), NULL, error)));
1553 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType, rt);
1557 mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
1559 HANDLE_FUNCTION_ENTER ();
1561 MONO_HANDLE_DCL (MonoReflectionType, ref);
1562 MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
1563 HANDLE_FUNCTION_RETURN_VAL (result);
1567 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass, MonoError *error)
1569 HANDLE_FUNCTION_ENTER ();
1570 MonoType *result = NULL;
1571 MonoType **types = NULL;
1573 MonoArrayHandle typeargs = MONO_HANDLE_NEW_GET (MonoArray, ref_gclass, type_arguments);
1574 int count = mono_array_handle_length (typeargs);
1575 types = g_new0 (MonoType*, count);
1576 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1577 for (int i = 0; i < count; ++i) {
1578 MONO_HANDLE_ARRAY_GETREF (t, typeargs, i);
1579 types [i] = mono_reflection_type_handle_mono_type (t, error);
1580 if (!types[i] || !is_ok (error)) {
1584 /* Need to resolve the generic_type in order for it to create its generic context. */
1585 MonoReflectionTypeHandle ref_gtd = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_gclass, generic_type);
1586 MonoType *gtd = mono_reflection_type_handle_mono_type (ref_gtd, error);
1587 if (!is_ok (error)) {
1590 MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
1591 if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
1592 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
1593 if (!is_ok (error)) {
1597 g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1598 result = mono_reflection_bind_generic_parameters (ref_gtd, count, types, error);
1602 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gclass), type, MonoType*, result);
1605 HANDLE_FUNCTION_RETURN_VAL (result);
1609 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
1611 HANDLE_FUNCTION_ENTER ();
1613 MonoType *result = NULL;
1616 MonoReflectionTypeBuilderHandle ref_tbuilder = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_gparam, tbuilder);
1617 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tbuilder, module);
1618 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1619 MonoImage *image = &dynamic_image->image;
1621 MonoGenericParamFull *param = mono_image_new0 (image, MonoGenericParamFull, 1);
1623 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_gparam, name);
1624 param->info.name = mono_string_to_utf8_image (image, ref_name, error);
1625 mono_error_assert_ok (error);
1626 param->param.num = MONO_HANDLE_GETVAL (ref_gparam, index);
1628 MonoReflectionMethodBuilderHandle ref_mbuilder = MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder, ref_gparam, mbuilder);
1629 if (!MONO_HANDLE_IS_NULL (ref_mbuilder)) {
1630 MonoGenericContainer *generic_container = MONO_HANDLE_GETVAL (ref_mbuilder, generic_container);
1631 if (!generic_container) {
1632 generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1633 generic_container->is_method = TRUE;
1635 * Cannot set owner.method, since the MonoMethod is not created yet.
1636 * Set the image field instead, so type_in_image () works.
1638 generic_container->is_anonymous = TRUE;
1639 generic_container->owner.image = image;
1640 MONO_HANDLE_SETVAL (ref_mbuilder, generic_container, MonoGenericContainer*, generic_container);
1642 param->param.owner = generic_container;
1644 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_tbuilder), error);
1647 MonoClass *owner = mono_class_from_mono_type (type);
1648 g_assert (mono_class_is_gtd (owner));
1649 param->param.owner = mono_class_get_generic_container (owner);
1652 MonoClass *pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1654 result = &pklass->byval_arg;
1656 mono_class_set_ref_info (pklass, MONO_HANDLE_CAST (MonoObject, ref_gparam));
1657 mono_image_append_class_to_reflection_info_set (pklass);
1659 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), type, MonoType*, result);
1662 HANDLE_FUNCTION_RETURN_VAL (result);
1666 mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
1668 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1670 MONO_HANDLE_DCL (MonoArray, array);
1671 MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
1672 HANDLE_FUNCTION_RETURN_VAL (result);
1676 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
1678 HANDLE_FUNCTION_ENTER ();
1681 MonoType* result = NULL;
1684 if (MONO_HANDLE_IS_NULL (ref))
1686 MonoType *t = MONO_HANDLE_GETVAL (ref, type);
1692 if (mono_reflection_is_usertype (ref)) {
1693 MONO_HANDLE_ASSIGN (ref, mono_reflection_type_get_underlying_system_type (ref, error));
1694 if (!is_ok (error) || MONO_HANDLE_IS_NULL (ref) || mono_reflection_is_usertype (ref))
1696 t = MONO_HANDLE_GETVAL (ref, type);
1703 MonoClass *klass = mono_handle_class (ref);
1705 if (is_sre_array (klass)) {
1706 MonoReflectionArrayTypeHandle sre_array = MONO_HANDLE_CAST (MonoReflectionArrayType, ref);
1707 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_array, element_type);
1708 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1712 gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
1713 MonoClass *eclass = mono_class_from_mono_type (base);
1714 result = mono_image_new0 (eclass->image, MonoType, 1);
1716 result->type = MONO_TYPE_SZARRAY;
1717 result->data.klass = eclass;
1719 MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
1720 result->type = MONO_TYPE_ARRAY;
1721 result->data.array = at;
1722 at->eklass = eclass;
1725 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1726 } else if (is_sre_byref (klass)) {
1727 MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1728 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_byref, element_type);
1729 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1733 result = &mono_class_from_mono_type (base)->this_arg;
1734 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1735 } else if (is_sre_pointer (klass)) {
1736 MonoReflectionDerivedTypeHandle sre_pointer = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1737 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_pointer, element_type);
1738 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1742 result = &mono_ptr_class_get (base)->byval_arg;
1743 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1744 } else if (is_sre_generic_instance (klass)) {
1745 result = reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass, ref), error);
1746 } else if (is_sre_gparam_builder (klass)) {
1747 result = reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam, ref), error);
1748 } else if (is_sre_enum_builder (klass)) {
1749 MonoReflectionEnumBuilderHandle ref_ebuilder = MONO_HANDLE_CAST (MonoReflectionEnumBuilder, ref);
1751 MonoReflectionTypeHandle ref_tb = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_ebuilder, tb);
1752 result = mono_reflection_type_handle_mono_type (ref_tb, error);
1753 } else if (is_sre_type_builder (klass)) {
1754 MonoReflectionTypeBuilderHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref);
1756 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1757 reflection_setup_internal_class (ref_tb, error);
1758 mono_error_assert_ok (error);
1759 result = MONO_HANDLE_GETVAL (ref, type);
1761 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1764 HANDLE_FUNCTION_RETURN_VAL (result);
1768 * LOCKING: Assumes the loader lock is held.
1770 static MonoMethodSignature*
1771 parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError *error) {
1772 MonoMethodSignature *sig;
1777 count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
1779 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1780 sig->param_count = count;
1781 sig->sentinelpos = -1; /* FIXME */
1782 for (i = 0; i < count; ++i) {
1783 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1784 if (!is_ok (error)) {
1785 image_g_free (image, sig);
1793 * LOCKING: Assumes the loader lock is held.
1795 static MonoMethodSignature*
1796 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
1797 MonoMethodSignature *sig;
1801 sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
1802 return_val_if_nok (error, NULL);
1803 sig->hasthis = MONO_HANDLE_GETVAL (ctor, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1804 sig->ret = &mono_defaults.void_class->byval_arg;
1808 static MonoMethodSignature*
1809 ctor_builder_to_signature_raw (MonoImage *image, MonoReflectionCtorBuilder* ctor_raw, MonoError *error) {
1810 HANDLE_FUNCTION_ENTER();
1811 MONO_HANDLE_DCL (MonoReflectionCtorBuilder, ctor);
1812 MonoMethodSignature *sig = ctor_builder_to_signature (image, ctor, error);
1813 HANDLE_FUNCTION_RETURN_VAL (sig);
1816 * LOCKING: Assumes the loader lock is held.
1818 static MonoMethodSignature*
1819 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error) {
1820 MonoMethodSignature *sig;
1824 sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, method, parameters), error);
1825 return_val_if_nok (error, NULL);
1826 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1827 MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1828 if (!MONO_HANDLE_IS_NULL (rtype)) {
1829 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1830 if (!is_ok (error)) {
1831 image_g_free (image, sig);
1835 sig->ret = &mono_defaults.void_class->byval_arg;
1837 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, method, generic_params);
1838 sig->generic_param_count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
1842 static MonoMethodSignature*
1843 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError *error) {
1844 HANDLE_FUNCTION_ENTER ();
1845 MonoMethodSignature *sig = NULL;
1849 sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
1852 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1853 MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1854 if (!MONO_HANDLE_IS_NULL (rtype)) {
1855 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1856 if (!is_ok (error)) {
1862 sig->ret = &mono_defaults.void_class->byval_arg;
1864 sig->generic_param_count = 0;
1866 HANDLE_FUNCTION_RETURN_VAL (sig);
1870 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1873 MonoClass *klass = mono_object_class (prop);
1874 if (strcmp (klass->name, "PropertyBuilder") == 0) {
1875 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1876 *name = mono_string_to_utf8_checked (pb->name, error);
1877 return_if_nok (error);
1878 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1880 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1881 *name = g_strdup (p->property->name);
1882 if (p->property->get)
1883 *type = mono_method_signature (p->property->get)->ret;
1885 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1890 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1893 MonoClass *klass = mono_object_class (field);
1894 if (strcmp (klass->name, "FieldBuilder") == 0) {
1895 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1896 *name = mono_string_to_utf8_checked (fb->name, error);
1897 return_if_nok (error);
1898 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1900 MonoReflectionField *f = (MonoReflectionField *)field;
1901 *name = g_strdup (mono_field_get_name (f->field));
1902 *type = f->field->type;
1906 #else /* DISABLE_REFLECTION_EMIT */
1909 is_sre_type_builder (MonoClass *klass)
1915 is_sre_generic_instance (MonoClass *klass)
1921 mono_is_sre_ctor_builder (MonoClass *klass)
1927 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1933 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1938 #endif /* !DISABLE_REFLECTION_EMIT */
1942 is_sr_mono_field (MonoClass *klass)
1944 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1948 mono_is_sr_mono_property (MonoClass *klass)
1950 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1954 is_sr_mono_method (MonoClass *klass)
1956 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1960 mono_is_sr_mono_cmethod (MonoClass *klass)
1962 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1966 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1968 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1972 mono_is_sre_type_builder (MonoClass *klass)
1974 return is_sre_type_builder (klass);
1978 mono_is_sre_generic_instance (MonoClass *klass)
1980 return is_sre_generic_instance (klass);
1986 * encode_cattr_value:
1987 * Encode a value in a custom attribute stream of bytes.
1988 * The value to encode is either supplied as an object in argument val
1989 * (valuetypes are boxed), or as a pointer to the data in the
1991 * @type represents the type of the value
1992 * @buffer is the start of the buffer
1993 * @p the current position in the buffer
1994 * @buflen contains the size of the buffer and is used to return the new buffer size
1995 * if this needs to be realloced.
1996 * @retbuffer and @retp return the start and the position of the buffer
1997 * @error set on error.
2000 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2002 MonoTypeEnum simple_type;
2005 if ((p-buffer) + 10 >= *buflen) {
2008 newbuf = (char *)g_realloc (buffer, *buflen);
2009 p = newbuf + (p-buffer);
2013 argval = ((char*)arg + sizeof (MonoObject));
2014 simple_type = type->type;
2016 switch (simple_type) {
2017 case MONO_TYPE_BOOLEAN:
2022 case MONO_TYPE_CHAR:
2025 swap_with_size (p, argval, 2, 1);
2031 swap_with_size (p, argval, 4, 1);
2035 swap_with_size (p, argval, 8, 1);
2040 swap_with_size (p, argval, 8, 1);
2043 case MONO_TYPE_VALUETYPE:
2044 if (type->data.klass->enumtype) {
2045 simple_type = mono_class_enum_basetype (type->data.klass)->type;
2048 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2051 case MONO_TYPE_STRING: {
2058 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2059 return_if_nok (error);
2060 slen = strlen (str);
2061 if ((p-buffer) + 10 + slen >= *buflen) {
2065 newbuf = (char *)g_realloc (buffer, *buflen);
2066 p = newbuf + (p-buffer);
2069 mono_metadata_encode_value (slen, p, &p);
2070 memcpy (p, str, slen);
2075 case MONO_TYPE_CLASS: {
2084 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2085 return_if_nok (error);
2087 str = type_get_qualified_name (arg_type, NULL);
2088 slen = strlen (str);
2089 if ((p-buffer) + 10 + slen >= *buflen) {
2093 newbuf = (char *)g_realloc (buffer, *buflen);
2094 p = newbuf + (p-buffer);
2097 mono_metadata_encode_value (slen, p, &p);
2098 memcpy (p, str, slen);
2103 case MONO_TYPE_SZARRAY: {
2105 MonoClass *eclass, *arg_eclass;
2108 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2111 len = mono_array_length ((MonoArray*)arg);
2113 *p++ = (len >> 8) & 0xff;
2114 *p++ = (len >> 16) & 0xff;
2115 *p++ = (len >> 24) & 0xff;
2117 *retbuffer = buffer;
2118 eclass = type->data.klass;
2119 arg_eclass = mono_object_class (arg)->element_class;
2122 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2123 eclass = mono_defaults.object_class;
2125 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2126 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2127 int elsize = mono_class_array_element_size (arg_eclass);
2128 for (i = 0; i < len; ++i) {
2129 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2130 return_if_nok (error);
2133 } else if (eclass->valuetype && arg_eclass->valuetype) {
2134 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2135 int elsize = mono_class_array_element_size (eclass);
2136 for (i = 0; i < len; ++i) {
2137 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2138 return_if_nok (error);
2142 for (i = 0; i < len; ++i) {
2143 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2144 return_if_nok (error);
2149 case MONO_TYPE_OBJECT: {
2155 * The parameter type is 'object' but the type of the actual
2156 * argument is not. So we have to add type information to the blob
2157 * too. This is completely undocumented in the spec.
2161 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2166 klass = mono_object_class (arg);
2168 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2172 return_if_nok (error);
2175 if (klass->enumtype) {
2177 } else if (klass == mono_defaults.string_class) {
2178 simple_type = MONO_TYPE_STRING;
2181 } else if (klass->rank == 1) {
2183 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2184 /* See Partition II, Appendix B3 */
2187 *p++ = klass->element_class->byval_arg.type;
2188 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2189 return_if_nok (error);
2191 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2192 *p++ = simple_type = klass->byval_arg.type;
2195 g_error ("unhandled type in custom attr");
2197 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2198 slen = strlen (str);
2199 if ((p-buffer) + 10 + slen >= *buflen) {
2203 newbuf = (char *)g_realloc (buffer, *buflen);
2204 p = newbuf + (p-buffer);
2207 mono_metadata_encode_value (slen, p, &p);
2208 memcpy (p, str, slen);
2211 simple_type = mono_class_enum_basetype (klass)->type;
2215 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2218 *retbuffer = buffer;
2222 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2224 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2225 char *str = type_get_qualified_name (type, NULL);
2226 int slen = strlen (str);
2230 * This seems to be optional...
2233 mono_metadata_encode_value (slen, p, &p);
2234 memcpy (p, str, slen);
2237 } else if (type->type == MONO_TYPE_OBJECT) {
2239 } else if (type->type == MONO_TYPE_CLASS) {
2240 /* it should be a type: encode_cattr_value () has the check */
2243 mono_metadata_encode_value (type->type, p, &p);
2244 if (type->type == MONO_TYPE_SZARRAY)
2245 /* See the examples in Partition VI, Annex B */
2246 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2252 #ifndef DISABLE_REFLECTION_EMIT
2254 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2260 /* Preallocate a large enough buffer */
2261 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2262 char *str = type_get_qualified_name (type, NULL);
2265 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2266 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2272 len += strlen (name);
2274 if ((p-buffer) + 20 + len >= *buflen) {
2278 newbuf = (char *)g_realloc (buffer, *buflen);
2279 p = newbuf + (p-buffer);
2283 encode_field_or_prop_type (type, p, &p);
2285 len = strlen (name);
2286 mono_metadata_encode_value (len, p, &p);
2287 memcpy (p, name, len);
2289 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2290 return_if_nok (error);
2292 *retbuffer = buffer;
2296 * mono_reflection_get_custom_attrs_blob:
2297 * \param ctor custom attribute constructor
2298 * \param ctorArgs arguments o the constructor
2302 * \param fieldValues
2303 * Creates the blob of data that needs to be saved in the metadata and that represents
2304 * the custom attributed described by \p ctor, \p ctorArgs etc.
2305 * \returns a \c Byte array representing the blob of data.
2308 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2311 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2312 mono_error_cleanup (&error);
2317 * mono_reflection_get_custom_attrs_blob_checked:
2318 * \param ctor custom attribute constructor
2319 * \param ctorArgs arguments o the constructor
2323 * \param fieldValues
2324 * \param error set on error
2325 * Creates the blob of data that needs to be saved in the metadata and that represents
2326 * the custom attributed described by \p ctor, \p ctorArgs etc.
2327 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2330 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2332 MonoArray *result = NULL;
2333 MonoMethodSignature *sig;
2340 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2341 /* sig is freed later so allocate it in the heap */
2342 sig = ctor_builder_to_signature_raw (NULL, (MonoReflectionCtorBuilder*)ctor, error); /* FIXME use handles */
2343 if (!is_ok (error)) {
2348 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2351 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2353 p = buffer = (char *)g_malloc (buflen);
2354 /* write the prolog */
2357 for (i = 0; i < sig->param_count; ++i) {
2358 arg = mono_array_get (ctorArgs, MonoObject*, i);
2359 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2360 if (!is_ok (error)) goto leave;
2364 i += mono_array_length (properties);
2366 i += mono_array_length (fields);
2368 *p++ = (i >> 8) & 0xff;
2371 for (i = 0; i < mono_array_length (properties); ++i) {
2375 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2376 get_prop_name_and_type (prop, &pname, &ptype, error);
2377 if (!is_ok (error)) goto leave;
2378 *p++ = 0x54; /* PROPERTY signature */
2379 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2381 if (!is_ok (error)) goto leave;
2387 for (i = 0; i < mono_array_length (fields); ++i) {
2391 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2392 get_field_name_and_type (field, &fname, &ftype, error);
2393 if (!is_ok (error)) goto leave;
2394 *p++ = 0x53; /* FIELD signature */
2395 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2397 if (!is_ok (error)) goto leave;
2401 g_assert (p - buffer <= buflen);
2402 buflen = p - buffer;
2403 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2406 p = mono_array_addr (result, char, 0);
2407 memcpy (p, buffer, buflen);
2410 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2416 reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
2420 mono_loader_lock ();
2422 MonoType *parent_type;
2423 MonoType *child_type;
2424 GHashTableIter iter;
2426 g_hash_table_iter_init (&iter, unparented);
2428 while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
2429 MonoClass *child_class = mono_class_from_mono_type (child_type);
2430 if (parent_type != NULL) {
2431 MonoClass *parent_class = mono_class_from_mono_type (parent_type);
2432 child_class->parent = NULL;
2433 /* fool mono_class_setup_parent */
2434 child_class->supertypes = NULL;
2435 mono_class_setup_parent (child_class, parent_class);
2436 } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
2437 const char *old_n = child_class->name;
2438 /* trick to get relative numbering right when compiling corlib */
2439 child_class->name = "BuildingObject";
2440 mono_class_setup_parent (child_class, mono_defaults.object_class);
2441 child_class->name = old_n;
2443 mono_class_setup_mono_type (child_class);
2444 mono_class_setup_supertypes (child_class);
2447 mono_loader_unlock ();
2448 return is_ok (error);
2452 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2454 HANDLE_FUNCTION_ENTER ();
2457 mono_loader_lock ();
2459 gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
2460 if (entering_state != MonoTypeBuilderNew) {
2461 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
2465 MONO_HANDLE_SETVAL (ref_tb, state, MonoTypeBuilderState, MonoTypeBuilderEntered);
2466 MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2467 GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
2469 // If this type is already setup, exit. We'll fix the parenting later
2470 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2474 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2475 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
2477 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_tb, name);
2478 MonoStringHandle ref_nspace = MONO_HANDLE_NEW_GET (MonoString, ref_tb, nspace);
2480 guint32 table_idx = MONO_HANDLE_GETVAL (ref_tb, table_idx);
2482 * The size calculation here warrants some explaining.
2483 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2484 * meaning we need to alloc enough space to morth a def into a gtd.
2486 MonoClass *klass = (MonoClass *)mono_image_alloc0 (&dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2487 klass->class_kind = MONO_CLASS_DEF;
2489 klass->image = &dynamic_image->image;
2491 klass->inited = 1; /* we lie to the runtime */
2492 klass->name = mono_string_to_utf8_image (klass->image, ref_name, error);
2495 klass->name_space = mono_string_to_utf8_image (klass->image, ref_nspace, error);
2498 klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
2499 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
2501 MONO_PROFILER_RAISE (class_loading, (klass));
2503 klass->element_class = klass;
2505 g_assert (!mono_class_has_ref_info (klass));
2506 mono_class_set_ref_info (klass, MONO_HANDLE_CAST (MonoObject, ref_tb));
2508 MonoReflectionTypeHandle ref_nesting_type = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, nesting_type);
2509 /* Put into cache so mono_class_get_checked () will find it.
2510 Skip nested types as those should not be available on the global scope. */
2511 if (MONO_HANDLE_IS_NULL (ref_nesting_type))
2512 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, table_idx);
2515 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2516 by performing a mono_class_get which does the full resolution.
2518 Working around this semantics would require us to write a lot of code for no clear advantage.
2520 mono_image_append_class_to_reflection_info_set (klass);
2522 mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
2524 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2525 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2526 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2527 klass->instance_size = sizeof (MonoObject);
2528 klass->size_inited = 1;
2529 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2532 mono_class_setup_mono_type (klass);
2535 * FIXME: handle interfaces.
2537 MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
2538 MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
2539 MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
2541 reflection_init_generic_class (ref_tb, error);
2545 // Do here so that the search inside of the parent can see the above type that's been set.
2546 MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
2547 MonoType *parent_type = NULL;
2548 if (!MONO_HANDLE_IS_NULL (ref_parent)) {
2549 MonoClass *parent_klass = mono_handle_class (ref_parent);
2550 gboolean recursive_init = TRUE;
2552 if (is_sre_type_builder (parent_klass)) {
2553 MonoTypeBuilderState parent_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
2555 if (parent_state != MonoTypeBuilderNew) {
2556 // Initialize types reachable from parent recursively
2557 // We'll fix the type hierarchy later
2558 recursive_init = FALSE;
2562 if (recursive_init) {
2563 // If we haven't encountered a cycle, force the creation of ref_parent's type
2564 mono_reflection_type_handle_mono_type (ref_parent, error);
2569 parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
2571 // If we failed to create the parent, fail the child
2576 // Push the child type and parent type to process later
2577 // Note: parent_type may be null.
2578 g_assert (!g_hash_table_lookup (unparented_classes, &klass->byval_arg));
2579 g_hash_table_insert (unparented_classes, &klass->byval_arg, parent_type);
2581 if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
2582 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
2585 MonoType *nesting_type = mono_reflection_type_handle_mono_type (ref_nesting_type, error);
2588 klass->nested_in = mono_class_from_mono_type (nesting_type);
2591 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2593 MONO_PROFILER_RAISE (class_loaded, (klass));
2596 mono_loader_unlock ();
2597 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2601 * reflection_init_generic_class:
2602 * @tb: a TypeBuilder object
2603 * @error: set on error
2605 * Creates the generic class after all generic parameters have been added.
2606 * On success returns TRUE, on failure returns FALSE and sets @error.
2608 * This assumes that reflection_setup_internal_class has already set up
2612 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2614 HANDLE_FUNCTION_ENTER ();
2618 MonoTypeBuilderState ref_state = MONO_HANDLE_GETVAL (ref_tb, state);
2619 g_assert (ref_state == MonoTypeBuilderFinished);
2621 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2622 MonoClass *klass = mono_class_from_mono_type (type);
2624 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
2625 int count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
2630 if (mono_class_try_get_generic_container (klass) != NULL)
2631 goto leave; /* already setup */
2633 MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2635 generic_container->owner.klass = klass;
2636 generic_container->type_argc = count;
2637 generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2639 klass->class_kind = MONO_CLASS_GTD;
2640 mono_class_set_generic_container (klass, generic_container);
2643 MonoReflectionGenericParamHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionGenericParam, NULL);
2644 for (int i = 0; i < count; i++) {
2645 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
2646 MonoType *param_type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), error);
2649 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2650 generic_container->type_params [i] = *param;
2651 /*Make sure we are a diferent type instance */
2652 generic_container->type_params [i].param.owner = generic_container;
2653 generic_container->type_params [i].info.pklass = NULL;
2654 generic_container->type_params [i].info.flags = MONO_HANDLE_GETVAL (ref_gparam, attrs);
2656 g_assert (generic_container->type_params [i].param.owner);
2659 generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2660 MonoGenericContext* context = &generic_container->context;
2661 MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
2662 canonical_inst->type = MONO_TYPE_GENERICINST;
2663 canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
2666 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2669 static MonoMarshalSpec*
2670 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2671 MonoReflectionMarshal *minfo, MonoError *error)
2673 MonoMarshalSpec *res;
2677 res = image_g_new0 (image, MonoMarshalSpec, 1);
2678 res->native = (MonoMarshalNative)minfo->type;
2680 switch (minfo->type) {
2681 case MONO_NATIVE_LPARRAY:
2682 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2683 if (minfo->has_size) {
2684 res->data.array_data.param_num = minfo->param_num;
2685 res->data.array_data.num_elem = minfo->count;
2686 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2689 res->data.array_data.param_num = -1;
2690 res->data.array_data.num_elem = -1;
2691 res->data.array_data.elem_mult = -1;
2695 case MONO_NATIVE_BYVALTSTR:
2696 case MONO_NATIVE_BYVALARRAY:
2697 res->data.array_data.num_elem = minfo->count;
2700 case MONO_NATIVE_CUSTOM:
2701 if (minfo->marshaltyperef) {
2702 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2703 if (!is_ok (error)) {
2704 image_g_free (image, res);
2707 res->data.custom_data.custom_name =
2708 type_get_fully_qualified_name (marshaltyperef);
2710 if (minfo->mcookie) {
2711 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2712 if (!is_ok (error)) {
2713 image_g_free (image, res);
2725 #endif /* !DISABLE_REFLECTION_EMIT */
2727 MonoReflectionMarshalAsAttributeHandle
2728 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2729 MonoMarshalSpec *spec, MonoError *error)
2733 MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
2736 guint32 utype = spec->native;
2737 MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2740 case MONO_NATIVE_LPARRAY:
2741 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2742 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2743 if (spec->data.array_data.param_num != -1)
2744 MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2747 case MONO_NATIVE_BYVALTSTR:
2748 case MONO_NATIVE_BYVALARRAY:
2749 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2752 case MONO_NATIVE_CUSTOM:
2753 if (spec->data.custom_data.custom_name) {
2754 MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2759 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2763 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2766 MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2769 MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2771 if (spec->data.custom_data.cookie) {
2772 MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2775 MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2785 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
2788 #ifndef DISABLE_REFLECTION_EMIT
2790 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2791 ReflectionMethodBuilder *rmb,
2792 MonoMethodSignature *sig,
2796 MonoMethodWrapper *wrapperm;
2797 MonoMarshalSpec **specs;
2798 MonoReflectionMethodAux *method_aux;
2805 * Methods created using a MethodBuilder should have their memory allocated
2806 * inside the image mempool, while dynamic methods should have their memory
2809 dynamic = rmb->refs != NULL;
2810 image = dynamic ? NULL : klass->image;
2813 g_assert (!mono_class_is_ginst (klass));
2815 mono_loader_lock ();
2817 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2818 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2819 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2821 m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
2823 wrapperm = (MonoMethodWrapper*)m;
2825 m->dynamic = dynamic;
2827 m->flags = rmb->attrs;
2828 m->iflags = rmb->iattrs;
2829 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2832 m->sre_method = TRUE;
2833 m->skip_visibility = rmb->skip_visibility;
2835 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2837 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2838 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2841 m->signature->pinvoke = 1;
2842 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2843 m->signature->pinvoke = 1;
2845 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2847 method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
2848 mono_error_assert_ok (error);
2849 method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
2850 mono_error_assert_ok (error);
2852 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2854 if (image_is_dynamic (klass->image))
2855 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2857 mono_loader_unlock ();
2860 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2861 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2862 MonoMethodHeader *header;
2864 gint32 max_stack, i;
2865 gint32 num_locals = 0;
2866 gint32 num_clauses = 0;
2870 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2871 code_size = rmb->ilgen->code_len;
2872 max_stack = rmb->ilgen->max_stack;
2873 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2874 if (rmb->ilgen->ex_handlers)
2875 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2878 code = mono_array_addr (rmb->code, guint8, 0);
2879 code_size = mono_array_length (rmb->code);
2880 /* we probably need to run a verifier on the code... */
2890 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2891 header->code_size = code_size;
2892 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2893 memcpy ((char*)header->code, code, code_size);
2894 header->max_stack = max_stack;
2895 header->init_locals = rmb->init_locals;
2896 header->num_locals = num_locals;
2898 for (i = 0; i < num_locals; ++i) {
2899 MonoReflectionLocalBuilder *lb =
2900 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2902 header->locals [i] = image_g_new0 (image, MonoType, 1);
2903 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2904 mono_error_assert_ok (error);
2905 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2908 header->num_clauses = num_clauses;
2910 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2911 rmb->ilgen, num_clauses, error);
2912 mono_error_assert_ok (error);
2915 wrapperm->header = header;
2916 MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
2917 dm->assembly = klass->image->assembly;
2920 if (rmb->generic_params) {
2921 int count = mono_array_length (rmb->generic_params);
2922 MonoGenericContainer *container;
2924 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2925 container->is_method = TRUE;
2926 container->is_anonymous = FALSE;
2927 container->type_argc = count;
2928 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2929 container->owner.method = m;
2931 m->is_generic = TRUE;
2932 mono_method_set_generic_container (m, container);
2934 for (i = 0; i < count; i++) {
2935 MonoReflectionGenericParam *gp =
2936 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2937 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2938 mono_error_assert_ok (error);
2939 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2940 container->type_params [i] = *param;
2941 container->type_params [i].param.owner = container;
2943 gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2945 MonoClass *gklass = mono_class_from_mono_type (gp_type);
2946 gklass->wastypebuilder = TRUE;
2950 * The method signature might have pointers to generic parameters that belong to other methods.
2951 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2952 * generic parameters.
2954 for (i = 0; i < m->signature->param_count; ++i) {
2955 MonoType *t = m->signature->params [i];
2956 if (t->type == MONO_TYPE_MVAR) {
2957 MonoGenericParam *gparam = t->data.generic_param;
2958 if (gparam->num < count) {
2959 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2960 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2966 if (mono_class_is_gtd (klass)) {
2967 container->parent = mono_class_get_generic_container (klass);
2968 container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2970 container->context.method_inst = mono_get_shared_generic_inst (container);
2974 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2978 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2980 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2981 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2982 for (i = 0; i < rmb->nrefs; ++i)
2983 data [i + 1] = rmb->refs [i];
2988 /* Parameter info */
2991 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2992 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2993 for (i = 0; i <= m->signature->param_count; ++i) {
2994 MonoReflectionParamBuilder *pb;
2995 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2996 if ((i > 0) && (pb->attrs)) {
2997 /* Make a copy since it might point to a shared type structure */
2998 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2999 m->signature->params [i - 1]->attrs = pb->attrs;
3002 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3003 MonoDynamicImage *assembly;
3005 MonoTypeEnum def_type;
3009 if (!method_aux->param_defaults) {
3010 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3011 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3013 assembly = (MonoDynamicImage*)klass->image;
3014 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3015 /* Copy the data from the blob since it might get realloc-ed */
3016 p = assembly->blob.data + idx;
3017 len = mono_metadata_decode_blob_size (p, &p2);
3019 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3020 method_aux->param_default_types [i] = def_type;
3021 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3025 method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
3026 mono_error_assert_ok (error);
3029 if (!method_aux->param_cattr)
3030 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3031 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3037 /* Parameter marshalling */
3040 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3041 MonoReflectionParamBuilder *pb;
3042 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3043 if (pb->marshal_info) {
3045 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3046 specs [pb->position] =
3047 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3048 if (!is_ok (error)) {
3049 mono_loader_unlock ();
3050 image_g_free (image, specs);
3051 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3057 if (specs != NULL) {
3059 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3060 method_aux->param_marshall = specs;
3063 if (image_is_dynamic (klass->image) && method_aux)
3064 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3066 mono_loader_unlock ();
3072 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3074 ReflectionMethodBuilder rmb;
3075 MonoMethodSignature *sig;
3077 mono_loader_lock ();
3079 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3082 g_assert (klass->image != NULL);
3083 sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
3084 mono_loader_unlock ();
3085 return_val_if_nok (error, NULL);
3087 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3088 return_val_if_nok (error, NULL);
3089 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3091 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
3092 /* ilgen is no longer needed */
3100 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
3102 ReflectionMethodBuilder rmb;
3103 MonoMethodSignature *sig;
3107 mono_loader_lock ();
3109 MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
3110 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3113 g_assert (klass->image != NULL);
3114 sig = method_builder_to_signature (klass->image, ref_mb, error);
3115 mono_loader_unlock ();
3116 return_val_if_nok (error, NULL);
3118 MonoMethod *method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3119 return_val_if_nok (error, NULL);
3120 MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
3121 mono_save_custom_attrs (klass->image, method, mb->cattrs);
3123 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
3124 /* ilgen is no longer needed */
3130 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
3132 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3134 MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
3135 MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
3136 HANDLE_FUNCTION_RETURN_VAL (result);
3141 #ifndef DISABLE_REFLECTION_EMIT
3144 * fix_partial_generic_class:
3145 * @klass: a generic instantiation MonoClass
3146 * @error: set on error
3148 * Assumes that the generic container of @klass has its vtable
3149 * initialized, and updates the parent class, interfaces, methods and
3150 * fields of @klass by inflating the types using the generic context.
3152 * On success returns TRUE, on failure returns FALSE and sets @error.
3156 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3158 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3163 if (klass->wastypebuilder)
3166 if (klass->parent != gklass->parent) {
3167 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
3168 if (mono_error_ok (error)) {
3169 MonoClass *parent = mono_class_from_mono_type (parent_type);
3170 mono_metadata_free_type (parent_type);
3171 if (parent != klass->parent) {
3172 /*fool mono_class_setup_parent*/
3173 klass->supertypes = NULL;
3174 mono_class_setup_parent (klass, parent);
3177 if (gklass->wastypebuilder)
3178 klass->wastypebuilder = TRUE;
3183 if (!mono_class_get_generic_class (klass)->need_sync)
3186 int mcount = mono_class_get_method_count (klass);
3187 int gmcount = mono_class_get_method_count (gklass);
3188 if (mcount != gmcount) {
3189 mono_class_set_method_count (klass, gmcount);
3190 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
3192 for (i = 0; i < gmcount; i++) {
3193 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3194 gklass->methods [i], klass, mono_class_get_context (klass), error);
3195 mono_error_assert_ok (error);
3199 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3200 klass->interface_count = gklass->interface_count;
3201 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3202 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3204 for (i = 0; i < gklass->interface_count; ++i) {
3205 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3206 return_val_if_nok (error, FALSE);
3208 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3209 mono_metadata_free_type (iface_type);
3211 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3214 klass->interfaces_inited = 1;
3217 int fcount = mono_class_get_field_count (klass);
3218 int gfcount = mono_class_get_field_count (gklass);
3219 if (fcount != gfcount) {
3220 mono_class_set_field_count (klass, gfcount);
3221 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3223 for (i = 0; i < gfcount; i++) {
3224 klass->fields [i] = gklass->fields [i];
3225 klass->fields [i].parent = klass;
3226 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3227 return_val_if_nok (error, FALSE);
3231 /*We can only finish with this klass once it's parent has as well*/
3232 if (gklass->wastypebuilder)
3233 klass->wastypebuilder = TRUE;
3238 * ensure_generic_class_runtime_vtable:
3239 * @klass a generic class
3240 * @error set on error
3242 * Ensures that the generic container of @klass has a vtable and
3243 * returns TRUE on success. On error returns FALSE and sets @error.
3246 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3248 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3252 if (!ensure_runtime_vtable (gklass, error))
3255 return fix_partial_generic_class (klass, error);
3259 * ensure_runtime_vtable:
3261 * @error set on error
3263 * Ensures that @klass has a vtable and returns TRUE on success. On
3264 * error returns FALSE and sets @error.
3267 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3269 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3274 if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3277 if (!ensure_runtime_vtable (klass->parent, error))
3281 num = tb->ctors? mono_array_length (tb->ctors): 0;
3282 num += tb->num_methods;
3283 mono_class_set_method_count (klass, num);
3284 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3285 num = tb->ctors? mono_array_length (tb->ctors): 0;
3286 for (i = 0; i < num; ++i) {
3287 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3290 klass->methods [i] = ctor;
3292 num = tb->num_methods;
3294 for (i = 0; i < num; ++i) {
3295 MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
3298 klass->methods [j++] = meth;
3301 if (tb->interfaces) {
3302 klass->interface_count = mono_array_length (tb->interfaces);
3303 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3304 for (i = 0; i < klass->interface_count; ++i) {
3305 MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
3306 return_val_if_nok (error, FALSE);
3307 klass->interfaces [i] = mono_class_from_mono_type (iface);
3308 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3311 klass->interfaces_inited = 1;
3313 } else if (mono_class_is_ginst (klass)){
3314 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3315 mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3320 if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3322 int mcount = mono_class_get_method_count (klass);
3323 for (i = 0; i < mcount; ++i) {
3324 MonoMethod *im = klass->methods [i];
3325 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3326 im->slot = slot_num++;
3329 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3330 mono_class_setup_interface_offsets (klass);
3331 mono_class_setup_interface_id (klass);
3335 * The generic vtable is needed even if image->run is not set since some
3336 * runtime code like ves_icall_Type_GetMethodsByName depends on
3337 * method->slot being defined.
3341 * tb->methods could not be freed since it is used for determining
3342 * overrides during dynamic vtable construction.
3349 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3352 MonoClass *klass = mono_object_class (method);
3353 if (is_sr_mono_method (klass)) {
3354 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3355 return sr_method->method;
3357 if (is_sre_method_builder (klass)) {
3358 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3361 if (mono_is_sre_method_on_tb_inst (klass)) {
3362 MonoClass *handle_class;
3364 MonoMethod *result = mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3365 return_val_if_nok (error, NULL);
3370 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3375 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3377 MonoReflectionTypeBuilder *tb;
3379 MonoReflectionMethod *m;
3385 g_assert (image_is_dynamic (klass->image));
3387 if (!mono_class_has_ref_info (klass))
3390 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3391 g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
3395 for (i = 0; i < tb->num_methods; ++i) {
3396 MonoReflectionMethodBuilder *mb =
3397 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3398 if (mb->override_methods)
3399 onum += mono_array_length (mb->override_methods);
3404 *overrides = g_new0 (MonoMethod*, onum * 2);
3407 for (i = 0; i < tb->num_methods; ++i) {
3408 MonoReflectionMethodBuilder *mb =
3409 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3410 if (mb->override_methods) {
3411 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3412 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3414 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3415 return_if_nok (error);
3416 (*overrides) [onum * 2 + 1] = mb->mhandle;
3418 g_assert (mb->mhandle);
3426 *num_overrides = onum;
3429 /* This initializes the same data as mono_class_setup_fields () */
3431 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3433 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3434 MonoReflectionFieldBuilder *fb;
3435 MonoClassField *field;
3436 MonoFieldDefaultValue *def_values;
3437 MonoImage *image = klass->image;
3439 int i, instance_size, packing_size = 0;
3442 if (klass->parent) {
3443 if (!klass->parent->size_inited)
3444 mono_class_init (klass->parent);
3445 instance_size = klass->parent->instance_size;
3447 instance_size = sizeof (MonoObject);
3450 int fcount = tb->num_fields;
3451 mono_class_set_field_count (klass, fcount);
3455 if (tb->class_size) {
3456 packing_size = tb->packing_size;
3457 instance_size += tb->class_size;
3460 klass->fields = image_g_new0 (image, MonoClassField, fcount);
3461 def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3462 mono_class_set_field_def_values (klass, def_values);
3464 This is, guess what, a hack.
3465 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3466 On the static path no field class is resolved, only types are built. This is the right thing to do
3468 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3470 klass->size_inited = 1;
3472 for (i = 0; i < fcount; ++i) {
3473 MonoArray *rva_data;
3474 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3475 field = &klass->fields [i];
3476 field->parent = klass;
3477 field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
3478 if (!mono_error_ok (error))
3481 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3482 return_if_nok (error);
3483 field->type = mono_metadata_type_dup (klass->image, type);
3484 field->type->attrs = fb->attrs;
3486 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3487 return_if_nok (error);
3490 if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
3491 mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
3495 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3496 char *base = mono_array_addr (rva_data, char, 0);
3497 size_t size = mono_array_length (rva_data);
3498 char *data = (char *)mono_image_alloc (klass->image, size);
3499 memcpy (data, base, size);
3500 def_values [i].data = data;
3502 if (fb->offset != -1)
3503 field->offset = fb->offset;
3505 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3507 if (fb->def_value) {
3508 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3509 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3510 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3511 /* Copy the data from the blob since it might get realloc-ed */
3512 p = assembly->blob.data + idx;
3513 len = mono_metadata_decode_blob_size (p, &p2);
3515 def_values [i].data = (const char *)mono_image_alloc (image, len);
3516 memcpy ((gpointer)def_values [i].data, p, len);
3520 if (!mono_class_has_failure (klass)) {
3521 mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3526 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3528 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3529 MonoReflectionPropertyBuilder *pb;
3530 MonoImage *image = klass->image;
3531 MonoProperty *properties;
3532 MonoClassPropertyInfo *info;
3537 info = mono_class_get_property_info (klass);
3539 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3540 mono_class_set_property_info (klass, info);
3543 info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3546 properties = image_g_new0 (image, MonoProperty, info->count);
3547 info->properties = properties;
3548 for (i = 0; i < info->count; ++i) {
3549 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3550 properties [i].parent = klass;
3551 properties [i].attrs = pb->attrs;
3552 properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
3553 if (!mono_error_ok (error))
3556 properties [i].get = pb->get_method->mhandle;
3558 properties [i].set = pb->set_method->mhandle;
3560 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3561 if (pb->def_value) {
3564 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3565 if (!info->def_values)
3566 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3567 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3568 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3569 /* Copy the data from the blob since it might get realloc-ed */
3570 p = assembly->blob.data + idx;
3571 len = mono_metadata_decode_blob_size (p, &p2);
3573 info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3574 memcpy ((gpointer)info->def_values [i].data, p, len);
3580 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3582 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3583 MonoReflectionEventBuilder *eb;
3584 MonoImage *image = klass->image;
3586 MonoClassEventInfo *info;
3591 info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3592 mono_class_set_event_info (klass, info);
3594 info->count = tb->events ? mono_array_length (tb->events) : 0;
3597 events = image_g_new0 (image, MonoEvent, info->count);
3598 info->events = events;
3599 for (i = 0; i < info->count; ++i) {
3600 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3601 events [i].parent = klass;
3602 events [i].attrs = eb->attrs;
3603 events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
3604 if (!mono_error_ok (error))
3607 events [i].add = eb->add_method->mhandle;
3608 if (eb->remove_method)
3609 events [i].remove = eb->remove_method->mhandle;
3610 if (eb->raise_method)
3611 events [i].raise = eb->raise_method->mhandle;
3613 #ifndef MONO_SMALL_CONFIG
3614 if (eb->other_methods) {
3616 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3617 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3618 MonoReflectionMethodBuilder *mb =
3619 mono_array_get (eb->other_methods,
3620 MonoReflectionMethodBuilder*, j);
3621 events [i].other [j] = mb->mhandle;
3625 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3629 struct remove_instantiations_user_data
3636 remove_instantiations_of_and_ensure_contents (gpointer key,
3640 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3641 MonoType *type = (MonoType*)key;
3642 MonoClass *klass = data->klass;
3643 gboolean already_failed = !is_ok (data->error);
3645 MonoError *error = already_failed ? &lerror : data->error;
3647 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3648 MonoClass *inst_klass = mono_class_from_mono_type (type);
3649 //Ensure it's safe to use it.
3650 if (!fix_partial_generic_class (inst_klass, error)) {
3651 mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3652 // Marked the class with failure, but since some other instantiation already failed,
3653 // just report that one, and swallow the error from this one.
3655 mono_error_cleanup (error);
3663 * reflection_setup_internal_class:
3664 * @tb: a TypeBuilder object
3665 * @error: set on error
3667 * Creates a MonoClass that represents the TypeBuilder.
3668 * This is a trick that lets us simplify a lot of reflection code
3669 * (and will allow us to support Build and Run assemblies easier).
3671 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3674 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3676 MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
3677 GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
3679 if (unparented_classes) {
3680 return reflection_setup_internal_class_internal (ref_tb, error);
3682 // If we're not being called recursively
3683 unparented_classes = g_hash_table_new (NULL, NULL);
3684 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
3686 gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
3687 mono_error_assert_ok (error);
3689 // Fix the relationship between the created classes and their parents
3690 reflection_setup_class_hierarchy (unparented_classes, error);
3691 mono_error_assert_ok (error);
3693 g_hash_table_destroy (unparented_classes);
3694 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
3701 MonoReflectionTypeHandle
3702 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3706 reflection_setup_internal_class (ref_tb, error);
3707 mono_error_assert_ok (error);
3709 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
3710 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
3711 MonoClass *klass = mono_class_from_mono_type (type);
3713 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
3714 mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
3717 * we need to lock the domain because the lock will be taken inside
3718 * So, we need to keep the locking order correct.
3720 mono_loader_lock ();
3721 mono_domain_lock (domain);
3722 if (klass->wastypebuilder) {
3723 mono_domain_unlock (domain);
3724 mono_loader_unlock ();
3726 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
3729 * Fields to set in klass:
3730 * the various flags: delegate/unicode/contextbound etc.
3732 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
3733 klass->has_cctor = 1;
3735 mono_class_setup_parent (klass, klass->parent);
3736 /* fool mono_class_setup_supertypes */
3737 klass->supertypes = NULL;
3738 mono_class_setup_supertypes (klass);
3739 mono_class_setup_mono_type (klass);
3741 /* enums are done right away */
3742 if (!klass->enumtype)
3743 if (!ensure_runtime_vtable (klass, error))
3746 MonoArrayHandle nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
3747 if (!MONO_HANDLE_IS_NULL (nested_types)) {
3748 GList *nested = NULL;
3749 int num_nested = mono_array_handle_length (nested_types);
3750 MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3751 for (int i = 0; i < num_nested; ++i) {
3752 MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
3754 if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
3755 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
3756 mono_error_assert_ok (error);
3759 MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
3760 if (!is_ok (error)) goto failure;
3761 nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3763 mono_class_set_nested_classes_property (klass, nested);
3766 klass->nested_classes_inited = TRUE;
3768 typebuilder_setup_fields (klass, error);
3771 typebuilder_setup_properties (klass, error);
3775 typebuilder_setup_events (klass, error);
3779 klass->wastypebuilder = TRUE;
3781 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
3782 if (!MONO_HANDLE_IS_NULL (generic_params)) {
3783 int num_params = mono_array_handle_length (generic_params);
3784 MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3785 for (int i = 0; i < num_params; i++) {
3786 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
3787 MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
3790 MonoClass *gklass = mono_class_from_mono_type (param_type);
3792 gklass->wastypebuilder = TRUE;
3797 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3798 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3799 * we want to return normal System.MonoType objects, so clear these out from the cache.
3801 * Together with this we must ensure the contents of all instances to match the created type.
3803 if (domain->type_hash && mono_class_is_gtd (klass)) {
3804 struct remove_instantiations_user_data data;
3807 mono_error_assert_ok (error);
3808 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3813 mono_domain_unlock (domain);
3814 mono_loader_unlock ();
3816 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3817 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3818 mono_error_set_type_load_class (error, klass, "Not a valid enumeration");
3819 goto failure_unlocked;
3822 MonoReflectionTypeHandle res = mono_type_get_object_handle (domain, &klass->byval_arg, error);
3824 goto failure_unlocked;
3829 mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
3830 klass->wastypebuilder = TRUE;
3831 mono_domain_unlock (domain);
3832 mono_loader_unlock ();
3840 } DynamicMethodReleaseData;
3843 * The runtime automatically clean up those after finalization.
3845 static MonoReferenceQueue *dynamic_method_queue;
3848 free_dynamic_method (void *dynamic_method)
3850 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3851 MonoDomain *domain = data->domain;
3852 MonoMethod *method = data->handle;
3855 mono_domain_lock (domain);
3856 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3857 g_hash_table_remove (domain->method_to_dyn_method, method);
3858 mono_domain_unlock (domain);
3859 g_assert (dis_link);
3860 mono_gchandle_free (dis_link);
3862 mono_runtime_free_method (domain, method);
3867 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
3869 MonoReferenceQueue *queue;
3871 DynamicMethodReleaseData *release_data;
3872 ReflectionMethodBuilder rmb;
3873 MonoMethodSignature *sig;
3881 if (mono_runtime_is_shutting_down ()) {
3882 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3886 if (!(queue = dynamic_method_queue)) {
3887 mono_loader_lock ();
3888 if (!(queue = dynamic_method_queue))
3889 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3890 mono_loader_unlock ();
3893 sig = dynamic_method_to_signature (ref_mb, error);
3894 return_val_if_nok (error, FALSE);
3896 MonoReflectionDynamicMethod *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
3897 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3900 * Resolve references.
3903 * Every second entry in the refs array is reserved for storing handle_class,
3904 * which is needed by the ldtoken implementation in the JIT.
3906 rmb.nrefs = mb->nrefs;
3907 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3908 for (i = 0; i < mb->nrefs; i += 2) {
3909 MonoClass *handle_class;
3911 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3913 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3914 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3916 * The referenced DynamicMethod should already be created by the managed
3917 * code, except in the case of circular references. In that case, we store
3918 * method in the refs array, and fix it up later when the referenced
3919 * DynamicMethod is created.
3921 if (method->mhandle) {
3922 ref = method->mhandle;
3924 /* FIXME: GC object stored in unmanaged memory */
3927 /* FIXME: GC object stored in unmanaged memory */
3928 method->referenced_by = g_slist_append (method->referenced_by, mb);
3930 handle_class = mono_defaults.methodhandle_class;
3932 MonoException *ex = NULL;
3933 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3934 if (!is_ok (error)) {
3939 ex = mono_get_exception_type_load (NULL, NULL);
3940 else if (mono_security_core_clr_enabled ())
3941 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3945 mono_error_set_exception_instance (error, ex);
3950 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3951 rmb.refs [i + 1] = handle_class;
3954 MonoAssembly *ass = NULL;
3956 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3957 if (!is_ok (error)) {
3961 klass = mono_class_from_mono_type (owner_type);
3962 ass = klass->image->assembly;
3964 klass = mono_defaults.object_class;
3965 ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
3968 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3969 ((MonoDynamicMethod*)handle)->assembly = ass;
3971 return_val_if_nok (error, FALSE);
3973 release_data = g_new (DynamicMethodReleaseData, 1);
3974 release_data->handle = handle;
3975 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3976 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3977 g_free (release_data);
3979 /* Fix up refs entries pointing at us */
3980 for (l = mb->referenced_by; l; l = l->next) {
3981 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3982 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3985 g_assert (method->mhandle);
3987 data = (gpointer*)wrapper->method_data;
3988 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3989 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3990 data [i + 1] = mb->mhandle;
3993 g_slist_free (mb->referenced_by);
3995 /* ilgen is no longer needed */
3998 domain = mono_domain_get ();
3999 mono_domain_lock (domain);
4000 if (!domain->method_to_dyn_method)
4001 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4002 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4003 mono_domain_unlock (domain);
4009 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4011 (void) reflection_create_dynamic_method (mb, error);
4014 #endif /* DISABLE_REFLECTION_EMIT */
4016 MonoMethodSignature *
4017 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4019 MonoMethodSignature *sig;
4020 g_assert (image_is_dynamic (image));
4024 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4028 return mono_method_signature_checked (method, error);
4031 #ifndef DISABLE_REFLECTION_EMIT
4034 * ensure_complete_type:
4036 * Ensure that KLASS is completed if it is a dynamic type, or references
4040 ensure_complete_type (MonoClass *klass, MonoError *error)
4044 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
4045 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
4047 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4048 return_if_nok (error);
4050 // Asserting here could break a lot of code
4051 //g_assert (klass->wastypebuilder);
4054 if (mono_class_is_ginst (klass)) {
4055 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
4058 for (i = 0; i < inst->type_argc; ++i) {
4059 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4060 return_if_nok (error);
4066 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4068 MonoClass *oklass = obj->vtable->klass;
4069 gpointer result = NULL;
4073 if (strcmp (oklass->name, "String") == 0) {
4074 result = mono_string_intern_checked ((MonoString*)obj, error);
4075 return_val_if_nok (error, NULL);
4076 *handle_class = mono_defaults.string_class;
4078 } else if (strcmp (oklass->name, "RuntimeType") == 0) {
4079 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4080 return_val_if_nok (error, NULL);
4081 MonoClass *mc = mono_class_from_mono_type (type);
4082 if (!mono_class_init (mc)) {
4083 mono_error_set_for_class_failure (error, mc);
4088 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4089 return_val_if_nok (error, NULL);
4091 result = mono_class_from_mono_type (inflated);
4092 mono_metadata_free_type (inflated);
4094 result = mono_class_from_mono_type (type);
4096 *handle_class = mono_defaults.typehandle_class;
4098 } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
4099 strcmp (oklass->name, "MonoCMethod") == 0) {
4100 result = ((MonoReflectionMethod*)obj)->method;
4102 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4103 mono_error_assert_ok (error);
4105 *handle_class = mono_defaults.methodhandle_class;
4107 } else if (strcmp (oklass->name, "MonoField") == 0) {
4108 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4110 ensure_complete_type (field->parent, error);
4111 return_val_if_nok (error, NULL);
4114 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
4115 return_val_if_nok (error, NULL);
4117 MonoClass *klass = mono_class_from_mono_type (inflated);
4118 MonoClassField *inflated_field;
4119 gpointer iter = NULL;
4120 mono_metadata_free_type (inflated);
4121 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
4122 if (!strcmp (field->name, inflated_field->name))
4125 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4126 result = inflated_field;
4130 *handle_class = mono_defaults.fieldhandle_class;
4132 } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
4133 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
4134 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4135 return_val_if_nok (error, NULL);
4138 klass = type->data.klass;
4139 if (klass->wastypebuilder) {
4140 /* Already created */
4144 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4145 return_val_if_nok (error, NULL);
4146 result = type->data.klass;
4149 *handle_class = mono_defaults.typehandle_class;
4150 } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
4151 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4152 MonoMethodSignature *sig;
4155 if (helper->arguments)
4156 nargs = mono_array_length (helper->arguments);
4160 sig = mono_metadata_signature_alloc (image, nargs);
4161 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4162 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4164 if (helper->unmanaged_call_conv) { /* unmanaged */
4165 sig->call_convention = helper->unmanaged_call_conv - 1;
4166 sig->pinvoke = TRUE;
4167 } else if (helper->call_conv & 0x02) {
4168 sig->call_convention = MONO_CALL_VARARG;
4170 sig->call_convention = MONO_CALL_DEFAULT;
4173 sig->param_count = nargs;
4174 /* TODO: Copy type ? */
4175 sig->ret = helper->return_type->type;
4176 for (i = 0; i < nargs; ++i) {
4177 sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
4178 if (!is_ok (error)) {
4179 image_g_free (image, sig);
4185 *handle_class = NULL;
4186 } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4187 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4188 /* Already created by the managed code */
4189 g_assert (method->mhandle);
4190 result = method->mhandle;
4191 *handle_class = mono_defaults.methodhandle_class;
4192 } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4193 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4200 mtype = mono_reflection_type_get_handle (m->parent, error);
4201 return_val_if_nok (error, NULL);
4202 klass = mono_class_from_mono_type (mtype);
4204 /* Find the method */
4206 name = mono_string_to_utf8_checked (m->name, error);
4207 return_val_if_nok (error, NULL);
4209 while ((method = mono_class_get_methods (klass, &iter))) {
4210 if (!strcmp (method->name, name))
4217 // FIXME: Check parameters/return value etc. match
4220 *handle_class = mono_defaults.methodhandle_class;
4221 } else if (is_sre_method_builder (oklass) ||
4222 mono_is_sre_ctor_builder (oklass) ||
4223 is_sre_field_builder (oklass) ||
4224 is_sre_gparam_builder (oklass) ||
4225 is_sre_generic_instance (oklass) ||
4226 is_sre_array (oklass) ||
4227 is_sre_byref (oklass) ||
4228 is_sre_pointer (oklass) ||
4229 !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4230 !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4231 !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4232 static MonoMethod *resolve_method;
4233 if (!resolve_method) {
4234 MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4236 mono_memory_barrier ();
4241 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4242 mono_error_assert_ok (error);
4244 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
4246 g_print ("%s\n", obj->vtable->klass->name);
4247 g_assert_not_reached ();
4252 #else /* DISABLE_REFLECTION_EMIT */
4255 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4257 g_assert_not_reached ();
4262 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4264 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4268 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4270 g_assert_not_reached ();
4275 mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4277 g_assert_not_reached ();
4282 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
4284 g_assert_not_reached ();
4289 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
4290 gboolean create_open_instance, gboolean register_token, MonoError *error)
4292 g_assert_not_reached ();
4297 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4304 MonoReflectionTypeHandle
4305 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
4307 g_assert_not_reached ();
4312 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4318 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4327 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
4330 if (MONO_HANDLE_IS_NULL (ref))
4332 return MONO_HANDLE_GETVAL (ref, type);
4336 #endif /* DISABLE_REFLECTION_EMIT */
4339 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4341 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
4346 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
4349 if (MONO_HANDLE_IS_NULL (obj)) {
4350 mono_error_set_argument_null (error, "obj", "");
4353 return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
4357 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
4358 MonoReflectionMethodHandle method,
4359 MonoArrayHandle opt_param_types,
4363 if (MONO_HANDLE_IS_NULL (method)) {
4364 mono_error_set_argument_null (error, "method", "");
4368 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
4372 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4375 mono_image_create_pefile (mb, file, &error);
4376 mono_error_set_pending_exception (&error);
4380 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4383 mono_image_build_metadata (mb, &error);
4384 mono_error_set_pending_exception (&error);
4388 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
4391 /* This function may be called by ModuleBuilder.FixupTokens to update
4392 * an existing token, so replace is okay here. */
4393 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
4397 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
4400 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4401 return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
4404 #ifndef DISABLE_REFLECTION_EMIT
4406 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4409 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4410 mono_error_set_pending_exception (&error);
4416 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4418 mono_reflection_dynimage_basic_init (assemblyb);
4422 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
4424 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
4426 MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
4427 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
4428 g_assert (assembly);
4430 mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
4434 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
4435 MonoReflectionTypeHandle t,
4439 MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
4443 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4446 mono_image_module_basic_init (moduleb, error);
4450 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4452 return mono_image_insert_string (module, str, error);
4456 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
4459 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
4460 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4463 image->wrappers_type = mono_class_from_mono_type (type);