2 * sre.c: Routines for creating an image at runtime
3 * and related System.Reflection.Emit icalls
7 * Paolo Molaro (lupus@ximian.com)
9 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
11 * Copyright 2011 Rodrigo Kumpera
12 * Copyright 2016 Microsoft
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
18 #include "mono/metadata/assembly.h"
19 #include "mono/metadata/debug-helpers.h"
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/exception.h"
23 #include "mono/metadata/gc-internals.h"
24 #include "mono/metadata/mono-ptr-array.h"
25 #include "mono/metadata/object-internals.h"
26 #include "mono/metadata/profiler-private.h"
27 #include "mono/metadata/reflection-internals.h"
28 #include "mono/metadata/reflection-cache.h"
29 #include "mono/metadata/sre-internals.h"
30 #include "mono/metadata/custom-attrs-internals.h"
31 #include "mono/metadata/security-manager.h"
32 #include "mono/metadata/security-core-clr.h"
33 #include "mono/metadata/tabledefs.h"
34 #include "mono/metadata/tokentype.h"
35 #include "mono/utils/checked-build.h"
36 #include "mono/utils/mono-digest.h"
37 #include "mono/utils/w32api.h"
39 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
40 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder);
42 static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
44 #ifndef DISABLE_REFLECTION_EMIT
45 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
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_create_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
53 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
56 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
57 static MonoReflectionTypeHandle mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error);
58 static gboolean is_sre_array (MonoClass *klass);
59 static gboolean is_sre_byref (MonoClass *klass);
60 static gboolean is_sre_pointer (MonoClass *klass);
61 static gboolean is_sre_generic_instance (MonoClass *klass);
62 static gboolean is_sre_type_builder (MonoClass *klass);
63 static gboolean is_sre_method_builder (MonoClass *klass);
64 static gboolean is_sre_field_builder (MonoClass *klass);
65 static gboolean is_sre_gparam_builder (MonoClass *klass);
66 static gboolean is_sre_enum_builder (MonoClass *klass);
67 static gboolean is_sr_mono_method (MonoClass *klass);
68 static gboolean is_sr_mono_field (MonoClass *klass);
70 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
71 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
72 static guint32 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error);
75 #ifndef DISABLE_REFLECTION_EMIT
76 static MonoType* mono_type_array_get_and_resolve_raw (MonoArray* array, int idx, MonoError* error);
79 static gboolean mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module, MonoError *error);
82 mono_reflection_emit_init (void)
84 mono_dynamic_images_init ();
88 string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
90 /* FIXME all callers to string_to_utf8_image_raw should use handles */
91 HANDLE_FUNCTION_ENTER ();
93 mono_error_init (error);
94 MONO_HANDLE_DCL (MonoString, s);
95 result = mono_string_to_utf8_image (image, s, error);
96 HANDLE_FUNCTION_RETURN_VAL (result);
100 type_get_fully_qualified_name (MonoType *type)
102 MONO_REQ_GC_NEUTRAL_MODE;
104 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
108 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
110 MONO_REQ_GC_UNSAFE_MODE;
115 klass = mono_class_from_mono_type (type);
117 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
118 ta = klass->image->assembly;
119 if (assembly_is_dynamic (ta) || (ta == ass)) {
120 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
121 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
122 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
124 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
127 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
130 #ifndef DISABLE_REFLECTION_EMIT
134 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
138 image_g_malloc (MonoImage *image, guint size)
140 MONO_REQ_GC_NEUTRAL_MODE;
143 return mono_image_alloc (image, size);
145 return g_malloc (size);
147 #endif /* !DISABLE_REFLECTION_EMIT */
152 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
156 mono_image_g_malloc0 (MonoImage *image, guint size)
158 MONO_REQ_GC_NEUTRAL_MODE;
161 return mono_image_alloc0 (image, size);
163 return g_malloc0 (size);
168 * @image: a MonoImage
171 * If @image is NULL, free @ptr, otherwise do nothing.
174 image_g_free (MonoImage *image, gpointer ptr)
180 #ifndef DISABLE_REFLECTION_EMIT
182 image_strdup (MonoImage *image, const char *s)
184 MONO_REQ_GC_NEUTRAL_MODE;
187 return mono_image_strdup (image, s);
193 #define image_g_new(image,struct_type, n_structs) \
194 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
196 #define image_g_new0(image,struct_type, n_structs) \
197 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
201 alloc_table (MonoDynamicTable *table, guint nrows)
203 mono_dynimage_alloc_table (table, nrows);
207 string_heap_insert (MonoDynamicStream *sh, const char *str)
209 return mono_dynstream_insert_string (sh, str);
213 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
215 return mono_dynstream_add_data (stream, data, len);
219 * Despite the name, we handle also TypeSpec (with the above helper).
222 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
224 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
228 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
229 * dest may be misaligned.
232 swap_with_size (char *dest, const char* val, int len, int nelem) {
233 MONO_REQ_GC_NEUTRAL_MODE;
234 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
237 for (elem = 0; elem < nelem; ++elem) {
263 g_assert_not_reached ();
269 memcpy (dest, val, len * nelem);
274 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
276 MONO_REQ_GC_UNSAFE_MODE;
278 guint32 num_clauses = 0;
281 MonoILExceptionInfo *ex_info;
282 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
283 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
284 if (ex_info->handlers)
285 num_clauses += mono_array_length (ex_info->handlers);
293 #ifndef DISABLE_REFLECTION_EMIT
294 static MonoExceptionClause*
295 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
297 MONO_REQ_GC_UNSAFE_MODE;
299 mono_error_init (error);
301 MonoExceptionClause *clauses;
302 MonoExceptionClause *clause;
303 MonoILExceptionInfo *ex_info;
304 MonoILExceptionBlock *ex_block;
305 guint32 finally_start;
306 int i, j, clause_index;;
308 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
311 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
312 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
313 finally_start = ex_info->start + ex_info->len;
314 if (!ex_info->handlers)
316 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
317 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
318 clause = &(clauses [clause_index]);
320 clause->flags = ex_block->type;
321 clause->try_offset = ex_info->start;
323 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
324 clause->try_len = finally_start - ex_info->start;
326 clause->try_len = ex_info->len;
327 clause->handler_offset = ex_block->start;
328 clause->handler_len = ex_block->len;
329 if (ex_block->extype) {
330 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
332 if (!is_ok (error)) {
333 image_g_free (image, clauses);
336 clause->data.catch_class = mono_class_from_mono_type (extype);
338 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
339 clause->data.filter_offset = ex_block->filter_offset;
341 clause->data.filter_offset = 0;
343 finally_start = ex_block->start + ex_block->len;
351 #endif /* !DISABLE_REFLECTION_EMIT */
353 #ifndef DISABLE_REFLECTION_EMIT
355 * LOCKING: Acquires the loader lock.
358 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
360 MONO_REQ_GC_UNSAFE_MODE;
362 MonoCustomAttrInfo *ainfo, *tmp;
364 if (!cattrs || !mono_array_length (cattrs))
367 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
370 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
372 mono_custom_attrs_free (tmp);
373 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
374 mono_loader_unlock ();
380 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
382 MONO_REQ_GC_UNSAFE_MODE;
384 MonoDynamicTable *table;
387 guint32 cols [MONO_ASSEMBLY_SIZE];
391 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
394 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
395 table = &assembly->tables [MONO_TABLE_MODULEREF];
396 token = table->next_idx ++;
398 alloc_table (table, table->rows);
399 values = table->values + token * MONO_MODULEREF_SIZE;
400 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
402 token <<= MONO_RESOLUTION_SCOPE_BITS;
403 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
404 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
409 if (assembly_is_dynamic (image->assembly))
411 memset (cols, 0, sizeof (cols));
413 /* image->assembly->image is the manifest module */
414 image = image->assembly->image;
415 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
418 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
419 token = table->next_idx ++;
421 alloc_table (table, table->rows);
422 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
423 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
424 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
425 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
426 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
427 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
428 values [MONO_ASSEMBLYREF_FLAGS] = 0;
429 values [MONO_ASSEMBLYREF_CULTURE] = 0;
430 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
432 if (strcmp ("", image->assembly->aname.culture)) {
433 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
434 image->assembly->aname.culture);
437 if ((pubkey = mono_image_get_public_key (image, &publen))) {
440 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
441 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
443 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
445 token <<= MONO_RESOLUTION_SCOPE_BITS;
446 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
447 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
451 #ifndef DISABLE_REFLECTION_EMIT
453 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
455 MONO_REQ_GC_UNSAFE_MODE;
457 mono_error_init (error);
458 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
460 rmb->ilgen = mb->ilgen;
461 rmb->rtype = (MonoReflectionType*)mb->rtype;
462 return_val_if_nok (error, FALSE);
463 rmb->parameters = mb->parameters;
464 rmb->generic_params = mb->generic_params;
465 rmb->generic_container = mb->generic_container;
466 rmb->opt_types = NULL;
467 rmb->pinfo = mb->pinfo;
468 rmb->attrs = mb->attrs;
469 rmb->iattrs = mb->iattrs;
470 rmb->call_conv = mb->call_conv;
471 rmb->code = mb->code;
472 rmb->type = mb->type;
473 rmb->name = mb->name;
474 rmb->table_idx = &mb->table_idx;
475 rmb->init_locals = mb->init_locals;
476 rmb->skip_visibility = FALSE;
477 rmb->return_modreq = mb->return_modreq;
478 rmb->return_modopt = mb->return_modopt;
479 rmb->param_modreq = mb->param_modreq;
480 rmb->param_modopt = mb->param_modopt;
481 rmb->permissions = mb->permissions;
482 rmb->mhandle = mb->mhandle;
487 rmb->charset = mb->charset;
488 rmb->extra_flags = mb->extra_flags;
489 rmb->native_cc = mb->native_cc;
490 rmb->dllentry = mb->dllentry;
498 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
500 MONO_REQ_GC_UNSAFE_MODE;
502 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
504 mono_error_init (error);
506 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
508 rmb->ilgen = mb->ilgen;
509 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
510 return_val_if_nok (error, FALSE);
511 rmb->parameters = mb->parameters;
512 rmb->generic_params = NULL;
513 rmb->generic_container = NULL;
514 rmb->opt_types = NULL;
515 rmb->pinfo = mb->pinfo;
516 rmb->attrs = mb->attrs;
517 rmb->iattrs = mb->iattrs;
518 rmb->call_conv = mb->call_conv;
520 rmb->type = mb->type;
521 rmb->name = mono_string_new (mono_domain_get (), name);
522 rmb->table_idx = &mb->table_idx;
523 rmb->init_locals = mb->init_locals;
524 rmb->skip_visibility = FALSE;
525 rmb->return_modreq = NULL;
526 rmb->return_modopt = NULL;
527 rmb->param_modreq = mb->param_modreq;
528 rmb->param_modopt = mb->param_modopt;
529 rmb->permissions = mb->permissions;
530 rmb->mhandle = mb->mhandle;
538 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
540 MONO_REQ_GC_UNSAFE_MODE;
542 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
544 rmb->ilgen = mb->ilgen;
545 rmb->rtype = mb->rtype;
546 rmb->parameters = mb->parameters;
547 rmb->generic_params = NULL;
548 rmb->generic_container = NULL;
549 rmb->opt_types = NULL;
551 rmb->attrs = mb->attrs;
553 rmb->call_conv = mb->call_conv;
555 rmb->type = (MonoObject *) mb->owner;
556 rmb->name = mb->name;
557 rmb->table_idx = NULL;
558 rmb->init_locals = mb->init_locals;
559 rmb->skip_visibility = mb->skip_visibility;
560 rmb->return_modreq = NULL;
561 rmb->return_modopt = NULL;
562 rmb->param_modreq = NULL;
563 rmb->param_modopt = NULL;
564 rmb->permissions = NULL;
565 rmb->mhandle = mb->mhandle;
569 #else /* DISABLE_REFLECTION_EMIT */
571 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
572 g_assert_not_reached ();
576 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
578 g_assert_not_reached ();
581 #endif /* DISABLE_REFLECTION_EMIT */
583 #ifndef DISABLE_REFLECTION_EMIT
585 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
587 MONO_REQ_GC_NEUTRAL_MODE;
589 MonoDynamicTable *table;
591 guint32 token, pclass;
593 switch (parent & MONO_TYPEDEFORREF_MASK) {
594 case MONO_TYPEDEFORREF_TYPEREF:
595 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
597 case MONO_TYPEDEFORREF_TYPESPEC:
598 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
600 case MONO_TYPEDEFORREF_TYPEDEF:
601 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
604 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
607 /* extract the index */
608 parent >>= MONO_TYPEDEFORREF_BITS;
610 table = &assembly->tables [MONO_TABLE_MEMBERREF];
612 if (assembly->save) {
613 alloc_table (table, table->rows + 1);
614 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
615 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
616 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
617 values [MONO_MEMBERREF_SIGNATURE] = sig;
620 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
627 * Insert a memberef row into the metadata: the token that point to the memberref
628 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
629 * mono_image_get_fieldref_token()).
630 * The sig param is an index to an already built signature.
633 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
635 MONO_REQ_GC_NEUTRAL_MODE;
637 guint32 parent = mono_image_typedef_or_ref (assembly, type);
638 return mono_image_add_memberef_row (assembly, parent, name, sig);
643 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
645 MONO_REQ_GC_NEUTRAL_MODE;
648 MonoMethodSignature *sig;
650 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
652 if (create_typespec) {
653 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
658 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
659 if (token && !create_typespec)
662 g_assert (!method->is_inflated);
665 * A methodref signature can't contain an unmanaged calling convention.
667 sig = mono_metadata_signature_dup (mono_method_signature (method));
668 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
669 sig->call_convention = MONO_CALL_DEFAULT;
670 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
671 method->name, mono_dynimage_encode_method_signature (assembly, sig));
673 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
676 if (create_typespec) {
677 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
678 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
679 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
681 if (assembly->save) {
684 alloc_table (table, table->rows + 1);
685 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
686 values [MONO_METHODSPEC_METHOD] = token;
687 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
690 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
692 /*methodspec and memberef tokens are diferent, */
693 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
700 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
701 const gchar *name, guint32 sig)
703 MonoDynamicTable *table;
707 table = &assembly->tables [MONO_TABLE_MEMBERREF];
709 if (assembly->save) {
710 alloc_table (table, table->rows + 1);
711 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
712 values [MONO_MEMBERREF_CLASS] = original;
713 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
714 values [MONO_MEMBERREF_SIGNATURE] = sig;
717 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
726 is_field_on_inst (MonoClassField *field)
728 return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
731 #ifndef DISABLE_REFLECTION_EMIT
733 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, MonoClassField *field)
739 g_assert (field->parent);
741 token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, MONO_HANDLE_RAW (f)));
745 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) {
746 int index = field - field->parent->fields;
747 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
749 type = mono_field_get_type (field);
751 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
752 mono_field_get_name (field),
753 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
754 mono_g_hash_table_insert (assembly->handleref_managed, MONO_HANDLE_RAW (f), GUINT_TO_POINTER(token));
759 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
761 MonoDynamicTable *table;
763 guint32 token, mtoken = 0, sig;
764 MonoMethodInflated *imethod;
765 MonoMethod *declaring;
767 table = &assembly->tables [MONO_TABLE_METHODSPEC];
769 g_assert (method->is_inflated);
770 imethod = (MonoMethodInflated *) method;
771 declaring = imethod->declaring;
773 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
774 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
776 if (!mono_method_signature (declaring)->generic_param_count)
779 switch (mono_metadata_token_table (mtoken)) {
780 case MONO_TABLE_MEMBERREF:
781 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
783 case MONO_TABLE_METHOD:
784 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
787 g_assert_not_reached ();
790 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
792 if (assembly->save) {
793 alloc_table (table, table->rows + 1);
794 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
795 values [MONO_METHODSPEC_METHOD] = mtoken;
796 values [MONO_METHODSPEC_SIGNATURE] = sig;
799 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
806 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
808 MonoMethodInflated *imethod;
811 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
815 g_assert (method->is_inflated);
816 imethod = (MonoMethodInflated *) method;
818 if (mono_method_signature (imethod->declaring)->generic_param_count) {
819 token = method_encode_methodspec (assembly, method);
821 guint32 sig = mono_dynimage_encode_method_signature (
822 assembly, mono_method_signature (imethod->declaring));
823 token = mono_image_get_memberref_token (
824 assembly, &method->klass->byval_arg, method->name, sig);
827 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
832 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
834 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
837 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
838 token = mono_image_get_memberref_token (
839 assembly, &m->klass->byval_arg, m->name, sig);
845 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
848 MonoDynamicTable *table;
851 mono_error_init (error);
853 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
854 idx = table->next_idx ++;
856 alloc_table (table, table->rows);
857 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
859 values [MONO_STAND_ALONE_SIGNATURE] =
860 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
861 return_val_if_nok (error, 0);
867 reflection_cc_to_file (int call_conv) {
868 switch (call_conv & 0x3) {
870 case 1: return MONO_CALL_DEFAULT;
871 case 2: return MONO_CALL_VARARG;
873 g_assert_not_reached ();
877 #endif /* !DISABLE_REFLECTION_EMIT */
879 struct _ArrayMethod {
881 MonoMethodSignature *sig;
887 mono_sre_array_method_free (ArrayMethod *am)
894 #ifndef DISABLE_REFLECTION_EMIT
896 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethodHandle m, MonoError *error)
898 MonoMethodSignature *sig = NULL;
901 mono_error_init (error);
903 MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
904 guint32 nparams = mono_array_handle_length (parameters);
905 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
907 sig->sentinelpos = -1;
908 sig->call_convention = reflection_cc_to_file (MONO_HANDLE_GETVAL (m, call_conv));
909 sig->param_count = nparams;
910 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW_GET (MonoReflectionType, m, ret);
911 if (!MONO_HANDLE_IS_NULL (ret)) {
912 sig->ret = mono_reflection_type_handle_mono_type (ret, error);
916 sig->ret = &mono_defaults.void_class->byval_arg;
918 MonoReflectionTypeHandle parent = MONO_HANDLE_NEW_GET (MonoReflectionType, m, parent);
919 MonoType *mtype = mono_reflection_type_handle_mono_type (parent, error);
923 for (int i = 0; i < nparams; ++i) {
924 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
929 MonoStringHandle mname = MONO_HANDLE_NEW_GET (MonoString, m, name);
930 name = mono_string_handle_to_utf8 (mname, error);
934 ArrayMethod *am = NULL;
935 for (GList *tmp = assembly->array_methods; tmp; tmp = tmp->next) {
936 am = (ArrayMethod *)tmp->data;
937 if (strcmp (name, am->name) == 0 &&
938 mono_metadata_type_equal (am->parent, mtype) &&
939 mono_metadata_signature_equal (am->sig, sig)) {
942 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
946 am = g_new0 (ArrayMethod, 1);
950 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
951 mono_dynimage_encode_method_signature (assembly, sig));
952 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
953 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
963 #ifndef DISABLE_REFLECTION_EMIT
966 * mono_image_insert_string:
967 * @module: module builder object
970 * Insert @str into the user string stream of @module.
973 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStringHandle str, MonoError *error)
975 HANDLE_FUNCTION_ENTER ();
981 MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
983 if (!mono_image_module_basic_init (ref_module, error))
986 assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
988 g_assert (assembly != NULL);
990 if (assembly->save) {
991 int32_t length = mono_string_length (MONO_HANDLE_RAW (str));
992 mono_metadata_encode_value (1 | (length * 2), b, &b);
993 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
995 uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, str), TRUE);
996 const char *p = (const char*)mono_string_chars (MONO_HANDLE_RAW (str));
997 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
999 char *swapped = g_malloc (2 * length);
1001 swap_with_size (swapped, p, 2, length);
1002 mono_image_add_stream_data (&assembly->us, swapped, length * 2);
1006 mono_image_add_stream_data (&assembly->us, p, length * 2);
1008 mono_gchandle_free (gchandle);
1009 mono_image_add_stream_data (&assembly->us, "", 1);
1011 idx = assembly->us.index ++;
1014 token = MONO_TOKEN_STRING | idx;
1015 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str));
1018 HANDLE_FUNCTION_RETURN_VAL (token);
1022 create_method_token (MonoDynamicImage *assembly, MonoMethod *method, MonoArrayHandle opt_param_types, MonoError *error)
1024 guint32 sig_token, parent;
1027 int nargs = mono_array_handle_length (opt_param_types);
1028 MonoMethodSignature *old = mono_method_signature (method);
1029 MonoMethodSignature *sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1031 sig->hasthis = old->hasthis;
1032 sig->explicit_this = old->explicit_this;
1033 sig->call_convention = old->call_convention;
1034 sig->generic_param_count = old->generic_param_count;
1035 sig->param_count = old->param_count + nargs;
1036 sig->sentinelpos = old->param_count;
1037 sig->ret = old->ret;
1039 for (int i = 0; i < old->param_count; i++)
1040 sig->params [i] = old->params [i];
1042 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1043 for (int i = 0; i < nargs; i++) {
1044 MONO_HANDLE_ARRAY_GETREF (rt, opt_param_types, i);
1045 sig->params [old->param_count + i] = mono_reflection_type_handle_mono_type (rt, error);
1046 if (!is_ok (error)) goto fail;
1049 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1050 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1051 parent >>= MONO_TYPEDEFORREF_BITS;
1053 parent <<= MONO_MEMBERREF_PARENT_BITS;
1054 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1056 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1057 guint32 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1058 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1065 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
1069 mono_error_init (error);
1071 MonoClass *klass = mono_handle_class (obj);
1072 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1073 MonoReflectionMethodHandle ref_method = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1074 MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
1075 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types) && (mono_method_signature (method)->sentinelpos >= 0));
1076 token = create_method_token (assembly, method, opt_param_types, error);
1079 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1080 g_assert_not_reached ();
1082 g_error ("requested method token for %s\n", klass->name);
1085 mono_dynamic_image_register_token (assembly, token, obj);
1088 g_assert (!mono_error_ok (error));
1093 * mono_image_create_token:
1094 * @assembly: a dynamic assembly
1096 * @register_token: Whenever to register the token in the assembly->tokens hash.
1098 * Get a token to insert in the IL code stream for the given MemberInfo.
1099 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1100 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1104 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
1105 gboolean create_open_instance, gboolean register_token,
1110 mono_error_init (error);
1112 MonoClass *klass = mono_handle_class (obj);
1114 /* Check for user defined reflection objects */
1115 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1116 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1117 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1121 if (strcmp (klass->name, "RuntimeType") == 0) {
1122 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
1123 return_val_if_nok (error, 0);
1124 MonoClass *mc = mono_class_from_mono_type (type);
1125 token = mono_metadata_token_from_dor (
1126 mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1127 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1128 strcmp (klass->name, "MonoMethod") == 0) {
1129 MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1130 MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
1131 if (method->is_inflated) {
1132 if (create_open_instance)
1133 token = mono_image_get_methodspec_token (assembly, method);
1135 token = mono_image_get_inflated_method_token (assembly, method);
1136 } else if ((method->klass->image == &assembly->image) &&
1137 !mono_class_is_ginst (method->klass)) {
1138 static guint32 method_table_idx = 0xffffff;
1139 if (method->klass->wastypebuilder) {
1140 /* we use the same token as the one that was assigned
1141 * to the Methodbuilder.
1142 * FIXME: do the equivalent for Fields.
1144 token = method->token;
1147 * Each token should have a unique index, but the indexes are
1148 * assigned by managed code, so we don't know about them. An
1149 * easy solution is to count backwards...
1151 method_table_idx --;
1152 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1155 token = mono_image_get_methodref_token (assembly, method, create_open_instance);
1157 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1158 } else if (strcmp (klass->name, "MonoField") == 0) {
1159 MonoReflectionFieldHandle f = MONO_HANDLE_CAST (MonoReflectionField, obj);
1160 MonoClassField *field = MONO_HANDLE_GETVAL (f, field);
1161 if ((field->parent->image == &assembly->image) && !is_field_on_inst (field)) {
1162 static guint32 field_table_idx = 0xffffff;
1164 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1166 token = mono_image_get_fieldref_token (assembly, obj, field);
1168 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1169 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1170 MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
1171 token = mono_image_get_array_token (assembly, m, error);
1172 return_val_if_nok (error, 0);
1173 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1174 MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
1175 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1176 return_val_if_nok (error, 0);
1177 } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1178 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
1179 return_val_if_nok (error, 0);
1180 token = mono_metadata_token_from_dor (
1181 mono_image_typedef_or_ref (assembly, type));
1183 g_error ("requested token for %s\n", klass->name);
1187 mono_dynamic_image_register_token (assembly, token, obj);
1195 #ifndef DISABLE_REFLECTION_EMIT
1198 * mono_reflection_dynimage_basic_init:
1199 * @assembly: an assembly builder object
1201 * Create the MonoImage that represents the assembly builder and setup some
1202 * of the helper hash table and the basic metadata streams.
1205 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1208 MonoDynamicAssembly *assembly;
1209 MonoDynamicImage *image;
1210 MonoDomain *domain = mono_object_domain (assemblyb);
1212 if (assemblyb->dynamic_assembly)
1216 /* assembly->assembly.image might be GC allocated */
1217 assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1219 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1222 mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1224 assembly->assembly.ref_count = 1;
1225 assembly->assembly.dynamic = TRUE;
1226 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1227 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1228 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1229 if (mono_error_set_pending_exception (&error))
1231 if (assemblyb->culture) {
1232 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1233 if (mono_error_set_pending_exception (&error))
1236 assembly->assembly.aname.culture = g_strdup ("");
1238 if (assemblyb->version) {
1239 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1240 if (mono_error_set_pending_exception (&error))
1242 char **version = g_strsplit (vstr, ".", 4);
1243 char **parts = version;
1244 assembly->assembly.aname.major = atoi (*parts++);
1245 assembly->assembly.aname.minor = atoi (*parts++);
1246 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1247 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1249 g_strfreev (version);
1252 assembly->assembly.aname.major = 0;
1253 assembly->assembly.aname.minor = 0;
1254 assembly->assembly.aname.build = 0;
1255 assembly->assembly.aname.revision = 0;
1258 assembly->run = assemblyb->access != 2;
1259 assembly->save = assemblyb->access != 1;
1260 assembly->domain = domain;
1262 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1263 if (mono_error_set_pending_exception (&error))
1265 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1266 image->initial_image = TRUE;
1267 assembly->assembly.aname.name = image->image.name;
1268 assembly->assembly.image = &image->image;
1269 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1270 /* -1 to correct for the trailing NULL byte */
1271 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1272 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1274 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1277 mono_domain_assemblies_lock (domain);
1278 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1279 mono_domain_assemblies_unlock (domain);
1281 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1283 mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1285 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1288 #endif /* !DISABLE_REFLECTION_EMIT */
1290 #ifndef DISABLE_REFLECTION_EMIT
1292 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1294 return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1297 static MonoReflectionModuleBuilderHandle
1298 register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, MonoDynamicImage *module)
1300 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilderHandle, module, MONO_HANDLE_CAST (MonoObject, res), NULL);
1304 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1306 mono_error_init (error);
1307 MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
1308 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
1309 MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
1310 MONO_HANDLE_GET (ab, moduleb, assemblyb);
1313 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1314 * we don't know which module it belongs to, since that is only
1315 * determined at assembly save time.
1317 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1318 MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name);
1319 char *name = mono_string_handle_to_utf8 (abname, error);
1320 return_val_if_nok (error, FALSE);
1321 MonoStringHandle modfqname = MONO_HANDLE_NEW_GET (MonoString, MONO_HANDLE_CAST (MonoReflectionModule, moduleb), fqname);
1322 char *fqname = mono_string_handle_to_utf8 (modfqname, error);
1323 if (!is_ok (error)) {
1327 MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly);
1328 image = mono_dynamic_image_create (dynamic_assembly, name, fqname);
1330 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image);
1331 MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image);
1332 register_module (domain, moduleb, image);
1334 /* register the module with the assembly */
1335 MonoImage *ass = dynamic_assembly->assembly.image;
1336 int module_count = ass->module_count;
1337 MonoImage **new_modules = g_new0 (MonoImage *, module_count + 1);
1340 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1341 new_modules [module_count] = &image->image;
1342 mono_image_addref (&image->image);
1344 g_free (ass->modules);
1345 ass->modules = new_modules;
1346 ass->module_count ++;
1352 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1354 mono_error_init (error);
1355 return image_module_basic_init (moduleb, error);
1361 is_corlib_type (MonoClass *klass)
1363 return klass->image == mono_defaults.corlib;
1366 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1367 static MonoClass *cached_class; \
1369 return cached_class == _class; \
1370 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1371 cached_class = _class; \
1379 mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
1381 HANDLE_FUNCTION_ENTER();
1382 mono_error_init (error);
1383 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1384 MONO_HANDLE_ARRAY_GETREF (t, array, idx);
1385 MonoType *result = mono_reflection_type_handle_mono_type (t, error);
1386 HANDLE_FUNCTION_RETURN_VAL (result);
1390 #ifndef DISABLE_REFLECTION_EMIT
1392 is_sre_array (MonoClass *klass)
1394 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1398 is_sre_byref (MonoClass *klass)
1400 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1404 is_sre_pointer (MonoClass *klass)
1406 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1410 is_sre_generic_instance (MonoClass *klass)
1412 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1416 is_sre_type_builder (MonoClass *klass)
1418 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1422 is_sre_method_builder (MonoClass *klass)
1424 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1428 mono_is_sre_ctor_builder (MonoClass *klass)
1430 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1434 is_sre_field_builder (MonoClass *klass)
1436 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1440 is_sre_gparam_builder (MonoClass *klass)
1442 check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1446 is_sre_enum_builder (MonoClass *klass)
1448 check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1452 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1454 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1458 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1460 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1463 static MonoReflectionTypeHandle
1464 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error)
1466 static MonoMethod *method_get_underlying_system_type = NULL;
1467 HANDLE_FUNCTION_ENTER ();
1469 mono_error_init (error);
1471 if (!method_get_underlying_system_type)
1472 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1474 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1476 MonoMethod *usertype_method = mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject, t), method_get_underlying_system_type, error);
1480 MONO_HANDLE_ASSIGN (rt, MONO_HANDLE_NEW (MonoReflectionType, mono_runtime_invoke_checked (usertype_method, MONO_HANDLE_RAW (t), NULL, error)));
1483 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType, rt);
1487 mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
1489 HANDLE_FUNCTION_ENTER ();
1490 mono_error_init (error);
1491 MONO_HANDLE_DCL (MonoReflectionType, ref);
1492 MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
1493 HANDLE_FUNCTION_RETURN_VAL (result);
1497 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass, MonoError *error)
1499 HANDLE_FUNCTION_ENTER ();
1500 MonoType *result = NULL;
1501 MonoType **types = NULL;
1503 MonoArrayHandle typeargs = MONO_HANDLE_NEW_GET (MonoArray, ref_gclass, type_arguments);
1504 int count = mono_array_handle_length (typeargs);
1505 types = g_new0 (MonoType*, count);
1506 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1507 for (int i = 0; i < count; ++i) {
1508 MONO_HANDLE_ARRAY_GETREF (t, typeargs, i);
1509 types [i] = mono_reflection_type_handle_mono_type (t, error);
1510 if (!types[i] || !is_ok (error)) {
1514 /* Need to resolve the generic_type in order for it to create its generic context. */
1515 MonoReflectionTypeHandle ref_gtd = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_gclass, generic_type);
1516 MonoType *gtd = mono_reflection_type_handle_mono_type (ref_gtd, error);
1517 if (!is_ok (error)) {
1520 MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
1521 if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
1522 reflection_create_generic_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
1523 if (!is_ok (error)) {
1527 g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1528 result = mono_reflection_bind_generic_parameters (ref_gtd, count, types, error);
1532 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gclass), type, MonoType*, result);
1535 HANDLE_FUNCTION_RETURN_VAL (result);
1539 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
1541 HANDLE_FUNCTION_ENTER ();
1542 mono_error_init (error);
1543 MonoType *result = NULL;
1546 MonoReflectionTypeBuilderHandle ref_tbuilder = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_gparam, tbuilder);
1547 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tbuilder, module);
1548 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1549 MonoImage *image = &dynamic_image->image;
1551 MonoGenericParamFull *param = mono_image_new0 (image, MonoGenericParamFull, 1);
1553 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_gparam, name);
1554 param->info.name = mono_string_to_utf8_image (image, ref_name, error);
1555 mono_error_assert_ok (error);
1556 param->param.num = MONO_HANDLE_GETVAL (ref_gparam, index);
1558 MonoReflectionMethodBuilderHandle ref_mbuilder = MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder, ref_gparam, mbuilder);
1559 if (!MONO_HANDLE_IS_NULL (ref_mbuilder)) {
1560 MonoGenericContainer *generic_container = MONO_HANDLE_GETVAL (ref_mbuilder, generic_container);
1561 if (!generic_container) {
1562 generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1563 generic_container->is_method = TRUE;
1565 * Cannot set owner.method, since the MonoMethod is not created yet.
1566 * Set the image field instead, so type_in_image () works.
1568 generic_container->is_anonymous = TRUE;
1569 generic_container->owner.image = image;
1570 MONO_HANDLE_SETVAL (ref_mbuilder, generic_container, MonoGenericContainer*, generic_container);
1572 param->param.owner = generic_container;
1574 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_tbuilder), error);
1577 MonoClass *owner = mono_class_from_mono_type (type);
1578 g_assert (mono_class_is_gtd (owner));
1579 param->param.owner = mono_class_get_generic_container (owner);
1582 MonoClass *pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1584 result = &pklass->byval_arg;
1586 mono_class_set_ref_info (pklass, MONO_HANDLE_CAST (MonoObject, ref_gparam));
1587 mono_image_append_class_to_reflection_info_set (pklass);
1589 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), type, MonoType*, result);
1592 HANDLE_FUNCTION_RETURN_VAL (result);
1596 mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
1598 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1599 mono_error_init (error);
1600 MONO_HANDLE_DCL (MonoArray, array);
1601 MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
1602 HANDLE_FUNCTION_RETURN_VAL (result);
1606 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
1608 HANDLE_FUNCTION_ENTER ();
1609 mono_error_init (error);
1611 MonoType* result = NULL;
1614 if (MONO_HANDLE_IS_NULL (ref))
1616 MonoType *t = MONO_HANDLE_GETVAL (ref, type);
1622 if (mono_reflection_is_usertype (ref)) {
1623 MONO_HANDLE_ASSIGN (ref, mono_reflection_type_get_underlying_system_type (ref, error));
1624 if (!is_ok (error) || MONO_HANDLE_IS_NULL (ref) || mono_reflection_is_usertype (ref))
1626 t = MONO_HANDLE_GETVAL (ref, type);
1633 MonoClass *klass = mono_handle_class (ref);
1635 if (is_sre_array (klass)) {
1636 MonoReflectionArrayTypeHandle sre_array = MONO_HANDLE_CAST (MonoReflectionArrayType, ref);
1637 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_array, element_type);
1638 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1642 gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
1643 if (rank == 0) //single dimentional array
1644 result = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
1646 result = &mono_bounded_array_class_get (mono_class_from_mono_type (base), rank, TRUE)->byval_arg;
1647 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1648 } else if (is_sre_byref (klass)) {
1649 MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1650 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_byref, element_type);
1651 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1655 result = &mono_class_from_mono_type (base)->this_arg;
1656 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1657 } else if (is_sre_pointer (klass)) {
1658 MonoReflectionDerivedTypeHandle sre_pointer = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1659 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_pointer, element_type);
1660 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1664 result = &mono_ptr_class_get (base)->byval_arg;
1665 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1666 } else if (is_sre_generic_instance (klass)) {
1667 result = reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass, ref), error);
1668 } else if (is_sre_gparam_builder (klass)) {
1669 result = reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam, ref), error);
1670 } else if (is_sre_enum_builder (klass)) {
1671 MonoReflectionEnumBuilderHandle ref_ebuilder = MONO_HANDLE_CAST (MonoReflectionEnumBuilder, ref);
1673 MonoReflectionTypeHandle ref_tb = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_ebuilder, tb);
1674 result = mono_reflection_type_handle_mono_type (ref_tb, error);
1675 } else if (is_sre_type_builder (klass)) {
1676 MonoReflectionTypeBuilderHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref);
1678 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1679 reflection_setup_internal_class (ref_tb, error);
1680 mono_error_assert_ok (error);
1681 result = MONO_HANDLE_GETVAL (ref, type);
1683 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1686 HANDLE_FUNCTION_RETURN_VAL (result);
1690 * LOCKING: Assumes the loader lock is held.
1692 static MonoMethodSignature*
1693 parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError *error) {
1694 MonoMethodSignature *sig;
1697 mono_error_init (error);
1699 count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
1701 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1702 sig->param_count = count;
1703 sig->sentinelpos = -1; /* FIXME */
1704 for (i = 0; i < count; ++i) {
1705 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1706 if (!is_ok (error)) {
1707 image_g_free (image, sig);
1715 * LOCKING: Assumes the loader lock is held.
1717 static MonoMethodSignature*
1718 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
1719 MonoMethodSignature *sig;
1721 mono_error_init (error);
1723 sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
1724 return_val_if_nok (error, NULL);
1725 sig->hasthis = MONO_HANDLE_GETVAL (ctor, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1726 sig->ret = &mono_defaults.void_class->byval_arg;
1730 static MonoMethodSignature*
1731 ctor_builder_to_signature_raw (MonoImage *image, MonoReflectionCtorBuilder* ctor_raw, MonoError *error) {
1732 HANDLE_FUNCTION_ENTER();
1733 MONO_HANDLE_DCL (MonoReflectionCtorBuilder, ctor);
1734 MonoMethodSignature *sig = ctor_builder_to_signature (image, ctor, error);
1735 HANDLE_FUNCTION_RETURN_VAL (sig);
1738 * LOCKING: Assumes the loader lock is held.
1740 static MonoMethodSignature*
1741 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error) {
1742 MonoMethodSignature *sig;
1744 mono_error_init (error);
1746 sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, method, parameters), error);
1747 return_val_if_nok (error, NULL);
1748 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1749 MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1750 if (!MONO_HANDLE_IS_NULL (rtype)) {
1751 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1752 if (!is_ok (error)) {
1753 image_g_free (image, sig);
1757 sig->ret = &mono_defaults.void_class->byval_arg;
1759 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, method, generic_params);
1760 sig->generic_param_count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
1764 static MonoMethodSignature*
1765 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError *error) {
1766 HANDLE_FUNCTION_ENTER ();
1767 MonoMethodSignature *sig = NULL;
1769 mono_error_init (error);
1771 sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
1774 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1775 MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1776 if (!MONO_HANDLE_IS_NULL (rtype)) {
1777 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1778 if (!is_ok (error)) {
1784 sig->ret = &mono_defaults.void_class->byval_arg;
1786 sig->generic_param_count = 0;
1788 HANDLE_FUNCTION_RETURN_VAL (sig);
1792 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1794 mono_error_init (error);
1795 MonoClass *klass = mono_object_class (prop);
1796 if (strcmp (klass->name, "PropertyBuilder") == 0) {
1797 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1798 *name = mono_string_to_utf8_checked (pb->name, error);
1799 return_if_nok (error);
1800 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1802 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1803 *name = g_strdup (p->property->name);
1804 if (p->property->get)
1805 *type = mono_method_signature (p->property->get)->ret;
1807 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1812 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1814 mono_error_init (error);
1815 MonoClass *klass = mono_object_class (field);
1816 if (strcmp (klass->name, "FieldBuilder") == 0) {
1817 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1818 *name = mono_string_to_utf8_checked (fb->name, error);
1819 return_if_nok (error);
1820 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1822 MonoReflectionField *f = (MonoReflectionField *)field;
1823 *name = g_strdup (mono_field_get_name (f->field));
1824 *type = f->field->type;
1828 #else /* DISABLE_REFLECTION_EMIT */
1831 is_sre_type_builder (MonoClass *klass)
1837 is_sre_generic_instance (MonoClass *klass)
1843 mono_is_sre_ctor_builder (MonoClass *klass)
1849 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1855 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1860 #endif /* !DISABLE_REFLECTION_EMIT */
1864 is_sr_mono_field (MonoClass *klass)
1866 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1870 mono_is_sr_mono_property (MonoClass *klass)
1872 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1876 is_sr_mono_method (MonoClass *klass)
1878 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1882 mono_is_sr_mono_cmethod (MonoClass *klass)
1884 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1888 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1890 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1894 mono_is_sre_type_builder (MonoClass *klass)
1896 return is_sre_type_builder (klass);
1900 mono_is_sre_generic_instance (MonoClass *klass)
1902 return is_sre_generic_instance (klass);
1908 * encode_cattr_value:
1909 * Encode a value in a custom attribute stream of bytes.
1910 * The value to encode is either supplied as an object in argument val
1911 * (valuetypes are boxed), or as a pointer to the data in the
1913 * @type represents the type of the value
1914 * @buffer is the start of the buffer
1915 * @p the current position in the buffer
1916 * @buflen contains the size of the buffer and is used to return the new buffer size
1917 * if this needs to be realloced.
1918 * @retbuffer and @retp return the start and the position of the buffer
1919 * @error set on error.
1922 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
1924 MonoTypeEnum simple_type;
1926 mono_error_init (error);
1927 if ((p-buffer) + 10 >= *buflen) {
1930 newbuf = (char *)g_realloc (buffer, *buflen);
1931 p = newbuf + (p-buffer);
1935 argval = ((char*)arg + sizeof (MonoObject));
1936 simple_type = type->type;
1938 switch (simple_type) {
1939 case MONO_TYPE_BOOLEAN:
1944 case MONO_TYPE_CHAR:
1947 swap_with_size (p, argval, 2, 1);
1953 swap_with_size (p, argval, 4, 1);
1957 swap_with_size (p, argval, 8, 1);
1962 swap_with_size (p, argval, 8, 1);
1965 case MONO_TYPE_VALUETYPE:
1966 if (type->data.klass->enumtype) {
1967 simple_type = mono_class_enum_basetype (type->data.klass)->type;
1970 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
1973 case MONO_TYPE_STRING: {
1980 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
1981 return_if_nok (error);
1982 slen = strlen (str);
1983 if ((p-buffer) + 10 + slen >= *buflen) {
1987 newbuf = (char *)g_realloc (buffer, *buflen);
1988 p = newbuf + (p-buffer);
1991 mono_metadata_encode_value (slen, p, &p);
1992 memcpy (p, str, slen);
1997 case MONO_TYPE_CLASS: {
2006 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2007 return_if_nok (error);
2009 str = type_get_qualified_name (arg_type, NULL);
2010 slen = strlen (str);
2011 if ((p-buffer) + 10 + slen >= *buflen) {
2015 newbuf = (char *)g_realloc (buffer, *buflen);
2016 p = newbuf + (p-buffer);
2019 mono_metadata_encode_value (slen, p, &p);
2020 memcpy (p, str, slen);
2025 case MONO_TYPE_SZARRAY: {
2027 MonoClass *eclass, *arg_eclass;
2030 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2033 len = mono_array_length ((MonoArray*)arg);
2035 *p++ = (len >> 8) & 0xff;
2036 *p++ = (len >> 16) & 0xff;
2037 *p++ = (len >> 24) & 0xff;
2039 *retbuffer = buffer;
2040 eclass = type->data.klass;
2041 arg_eclass = mono_object_class (arg)->element_class;
2044 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2045 eclass = mono_defaults.object_class;
2047 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2048 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2049 int elsize = mono_class_array_element_size (arg_eclass);
2050 for (i = 0; i < len; ++i) {
2051 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2052 return_if_nok (error);
2055 } else if (eclass->valuetype && arg_eclass->valuetype) {
2056 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2057 int elsize = mono_class_array_element_size (eclass);
2058 for (i = 0; i < len; ++i) {
2059 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2060 return_if_nok (error);
2064 for (i = 0; i < len; ++i) {
2065 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2066 return_if_nok (error);
2071 case MONO_TYPE_OBJECT: {
2077 * The parameter type is 'object' but the type of the actual
2078 * argument is not. So we have to add type information to the blob
2079 * too. This is completely undocumented in the spec.
2083 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2088 klass = mono_object_class (arg);
2090 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2094 return_if_nok (error);
2097 if (klass->enumtype) {
2099 } else if (klass == mono_defaults.string_class) {
2100 simple_type = MONO_TYPE_STRING;
2103 } else if (klass->rank == 1) {
2105 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2106 /* See Partition II, Appendix B3 */
2109 *p++ = klass->element_class->byval_arg.type;
2110 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2111 return_if_nok (error);
2113 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2114 *p++ = simple_type = klass->byval_arg.type;
2117 g_error ("unhandled type in custom attr");
2119 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2120 slen = strlen (str);
2121 if ((p-buffer) + 10 + slen >= *buflen) {
2125 newbuf = (char *)g_realloc (buffer, *buflen);
2126 p = newbuf + (p-buffer);
2129 mono_metadata_encode_value (slen, p, &p);
2130 memcpy (p, str, slen);
2133 simple_type = mono_class_enum_basetype (klass)->type;
2137 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2140 *retbuffer = buffer;
2144 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2146 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2147 char *str = type_get_qualified_name (type, NULL);
2148 int slen = strlen (str);
2152 * This seems to be optional...
2155 mono_metadata_encode_value (slen, p, &p);
2156 memcpy (p, str, slen);
2159 } else if (type->type == MONO_TYPE_OBJECT) {
2161 } else if (type->type == MONO_TYPE_CLASS) {
2162 /* it should be a type: encode_cattr_value () has the check */
2165 mono_metadata_encode_value (type->type, p, &p);
2166 if (type->type == MONO_TYPE_SZARRAY)
2167 /* See the examples in Partition VI, Annex B */
2168 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2174 #ifndef DISABLE_REFLECTION_EMIT
2176 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2180 mono_error_init (error);
2182 /* Preallocate a large enough buffer */
2183 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2184 char *str = type_get_qualified_name (type, NULL);
2187 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2188 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2194 len += strlen (name);
2196 if ((p-buffer) + 20 + len >= *buflen) {
2200 newbuf = (char *)g_realloc (buffer, *buflen);
2201 p = newbuf + (p-buffer);
2205 encode_field_or_prop_type (type, p, &p);
2207 len = strlen (name);
2208 mono_metadata_encode_value (len, p, &p);
2209 memcpy (p, name, len);
2211 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2212 return_if_nok (error);
2214 *retbuffer = buffer;
2218 * mono_reflection_get_custom_attrs_blob:
2219 * @ctor: custom attribute constructor
2220 * @ctorArgs: arguments o the constructor
2226 * Creates the blob of data that needs to be saved in the metadata and that represents
2227 * the custom attributed described by @ctor, @ctorArgs etc.
2228 * Returns: a Byte array representing the blob of data.
2231 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2234 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2235 mono_error_cleanup (&error);
2240 * mono_reflection_get_custom_attrs_blob_checked:
2241 * @ctor: custom attribute constructor
2242 * @ctorArgs: arguments o the constructor
2247 * @error: set on error
2249 * Creates the blob of data that needs to be saved in the metadata and that represents
2250 * the custom attributed described by @ctor, @ctorArgs etc.
2251 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2254 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2256 MonoArray *result = NULL;
2257 MonoMethodSignature *sig;
2262 mono_error_init (error);
2264 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2265 /* sig is freed later so allocate it in the heap */
2266 sig = ctor_builder_to_signature_raw (NULL, (MonoReflectionCtorBuilder*)ctor, error); /* FIXME use handles */
2267 if (!is_ok (error)) {
2272 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2275 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2277 p = buffer = (char *)g_malloc (buflen);
2278 /* write the prolog */
2281 for (i = 0; i < sig->param_count; ++i) {
2282 arg = mono_array_get (ctorArgs, MonoObject*, i);
2283 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2284 if (!is_ok (error)) goto leave;
2288 i += mono_array_length (properties);
2290 i += mono_array_length (fields);
2292 *p++ = (i >> 8) & 0xff;
2295 for (i = 0; i < mono_array_length (properties); ++i) {
2299 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2300 get_prop_name_and_type (prop, &pname, &ptype, error);
2301 if (!is_ok (error)) goto leave;
2302 *p++ = 0x54; /* PROPERTY signature */
2303 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2305 if (!is_ok (error)) goto leave;
2311 for (i = 0; i < mono_array_length (fields); ++i) {
2315 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2316 get_field_name_and_type (field, &fname, &ftype, error);
2317 if (!is_ok (error)) goto leave;
2318 *p++ = 0x53; /* FIELD signature */
2319 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2321 if (!is_ok (error)) goto leave;
2325 g_assert (p - buffer <= buflen);
2326 buflen = p - buffer;
2327 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2330 p = mono_array_addr (result, char, 0);
2331 memcpy (p, buffer, buflen);
2334 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2340 * reflection_setup_internal_class:
2341 * @tb: a TypeBuilder object
2342 * @error: set on error
2344 * Creates a MonoClass that represents the TypeBuilder.
2345 * This is a trick that lets us simplify a lot of reflection code
2346 * (and will allow us to support Build and Run assemblies easier).
2348 * Returns TRUE on success. On failure, returns FALSE and sets @error.
2351 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2353 HANDLE_FUNCTION_ENTER ();
2354 mono_error_init (error);
2356 mono_loader_lock ();
2358 MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
2359 MonoClass *parent = NULL;
2360 if (!MONO_HANDLE_IS_NULL (ref_parent)) {
2361 MonoType *parent_type = mono_reflection_type_handle_mono_type (ref_parent, error);
2364 /* check so we can compile corlib correctly */
2365 if (strcmp (mono_handle_class (ref_parent)->name, "TypeBuilder") == 0) {
2366 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2367 parent = parent_type->data.klass;
2369 parent = mono_class_from_mono_type (parent_type);
2373 /* the type has already being created: it means we just have to change the parent */
2374 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2376 MonoClass *klass = mono_class_from_mono_type (type);
2377 klass->parent = NULL;
2378 /* fool mono_class_setup_parent */
2379 klass->supertypes = NULL;
2380 mono_class_setup_parent (klass, parent);
2381 mono_class_setup_mono_type (klass);
2385 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2386 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
2388 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_tb, name);
2389 MonoStringHandle ref_nspace = MONO_HANDLE_NEW_GET (MonoString, ref_tb, nspace);
2391 guint32 table_idx = MONO_HANDLE_GETVAL (ref_tb, table_idx);
2393 * The size calculation here warrants some explaining.
2394 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2395 * meaning we need to alloc enough space to morth a def into a gtd.
2397 MonoClass *klass = (MonoClass *)mono_image_alloc0 (&dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2398 klass->class_kind = MONO_CLASS_DEF;
2400 klass->image = &dynamic_image->image;
2402 klass->inited = 1; /* we lie to the runtime */
2403 klass->name = mono_string_to_utf8_image (klass->image, ref_name, error);
2406 klass->name_space = mono_string_to_utf8_image (klass->image, ref_nspace, error);
2409 klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
2410 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
2412 mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2414 klass->element_class = klass;
2416 g_assert (!mono_class_has_ref_info (klass));
2417 mono_class_set_ref_info (klass, MONO_HANDLE_CAST (MonoObject, ref_tb));
2419 MonoReflectionTypeHandle ref_nesting_type = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, nesting_type);
2420 /* Put into cache so mono_class_get_checked () will find it.
2421 Skip nested types as those should not be available on the global scope. */
2422 if (MONO_HANDLE_IS_NULL (ref_nesting_type))
2423 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, table_idx);
2426 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2427 by performing a mono_class_get which does the full resolution.
2429 Working around this semantics would require us to write a lot of code for no clear advantage.
2431 mono_image_append_class_to_reflection_info_set (klass);
2433 mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb));
2435 if (parent != NULL) {
2436 mono_class_setup_parent (klass, parent);
2437 } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
2438 const char *old_n = klass->name;
2439 /* trick to get relative numbering right when compiling corlib */
2440 klass->name = "BuildingObject";
2441 mono_class_setup_parent (klass, mono_defaults.object_class);
2442 klass->name = old_n;
2445 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2446 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2447 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2448 klass->instance_size = sizeof (MonoObject);
2449 klass->size_inited = 1;
2450 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2453 mono_class_setup_mono_type (klass);
2455 mono_class_setup_supertypes (klass);
2458 * FIXME: handle interfaces.
2461 MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
2462 MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
2464 if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
2465 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
2468 MonoType *nesting_type = mono_reflection_type_handle_mono_type (ref_nesting_type, error);
2471 klass->nested_in = mono_class_from_mono_type (nesting_type);
2474 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2476 mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
2479 mono_loader_unlock ();
2480 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2484 * reflection_create_generic_class:
2485 * @tb: a TypeBuilder object
2486 * @error: set on error
2488 * Creates the generic class after all generic parameters have been added.
2489 * On success returns TRUE, on failure returns FALSE and sets @error.
2492 reflection_create_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2494 HANDLE_FUNCTION_ENTER ();
2496 mono_error_init (error);
2498 reflection_setup_internal_class (ref_tb, error);
2502 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2503 MonoClass *klass = mono_class_from_mono_type (type);
2505 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
2506 int count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
2511 if (mono_class_try_get_generic_container (klass) != NULL)
2512 goto leave; /* already setup */
2514 MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2516 generic_container->owner.klass = klass;
2517 generic_container->type_argc = count;
2518 generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2520 klass->class_kind = MONO_CLASS_GTD;
2521 mono_class_set_generic_container (klass, generic_container);
2524 MonoReflectionGenericParamHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionGenericParam, NULL);
2525 for (int i = 0; i < count; i++) {
2526 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
2527 MonoType *param_type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), error);
2530 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2531 generic_container->type_params [i] = *param;
2532 /*Make sure we are a diferent type instance */
2533 generic_container->type_params [i].param.owner = generic_container;
2534 generic_container->type_params [i].info.pklass = NULL;
2535 generic_container->type_params [i].info.flags = MONO_HANDLE_GETVAL (ref_gparam, attrs);
2537 g_assert (generic_container->type_params [i].param.owner);
2540 generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2542 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2545 static MonoMarshalSpec*
2546 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2547 MonoReflectionMarshal *minfo, MonoError *error)
2549 MonoMarshalSpec *res;
2551 mono_error_init (error);
2553 res = image_g_new0 (image, MonoMarshalSpec, 1);
2554 res->native = (MonoMarshalNative)minfo->type;
2556 switch (minfo->type) {
2557 case MONO_NATIVE_LPARRAY:
2558 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2559 if (minfo->has_size) {
2560 res->data.array_data.param_num = minfo->param_num;
2561 res->data.array_data.num_elem = minfo->count;
2562 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2565 res->data.array_data.param_num = -1;
2566 res->data.array_data.num_elem = -1;
2567 res->data.array_data.elem_mult = -1;
2571 case MONO_NATIVE_BYVALTSTR:
2572 case MONO_NATIVE_BYVALARRAY:
2573 res->data.array_data.num_elem = minfo->count;
2576 case MONO_NATIVE_CUSTOM:
2577 if (minfo->marshaltyperef) {
2578 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2579 if (!is_ok (error)) {
2580 image_g_free (image, res);
2583 res->data.custom_data.custom_name =
2584 type_get_fully_qualified_name (marshaltyperef);
2586 if (minfo->mcookie) {
2587 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2588 if (!is_ok (error)) {
2589 image_g_free (image, res);
2601 #endif /* !DISABLE_REFLECTION_EMIT */
2603 MonoReflectionMarshalAsAttributeHandle
2604 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2605 MonoMarshalSpec *spec, MonoError *error)
2607 mono_error_init (error);
2609 MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
2612 guint32 utype = spec->native;
2613 MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2616 case MONO_NATIVE_LPARRAY:
2617 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2618 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2619 if (spec->data.array_data.param_num != -1)
2620 MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2623 case MONO_NATIVE_BYVALTSTR:
2624 case MONO_NATIVE_BYVALARRAY:
2625 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2628 case MONO_NATIVE_CUSTOM:
2629 if (spec->data.custom_data.custom_name) {
2630 MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2635 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2639 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2642 MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2645 MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2647 if (spec->data.custom_data.cookie) {
2648 MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2651 MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2661 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
2664 #ifndef DISABLE_REFLECTION_EMIT
2666 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2667 ReflectionMethodBuilder *rmb,
2668 MonoMethodSignature *sig,
2672 MonoMethodWrapper *wrapperm;
2673 MonoMarshalSpec **specs;
2674 MonoReflectionMethodAux *method_aux;
2679 mono_error_init (error);
2681 * Methods created using a MethodBuilder should have their memory allocated
2682 * inside the image mempool, while dynamic methods should have their memory
2685 dynamic = rmb->refs != NULL;
2686 image = dynamic ? NULL : klass->image;
2689 g_assert (!mono_class_is_ginst (klass));
2691 mono_loader_lock ();
2693 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2694 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2695 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2697 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
2699 wrapperm = (MonoMethodWrapper*)m;
2701 m->dynamic = dynamic;
2703 m->flags = rmb->attrs;
2704 m->iflags = rmb->iattrs;
2705 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2708 m->sre_method = TRUE;
2709 m->skip_visibility = rmb->skip_visibility;
2711 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2713 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2714 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2717 m->signature->pinvoke = 1;
2718 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2719 m->signature->pinvoke = 1;
2721 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2723 method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
2724 mono_error_assert_ok (error);
2725 method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
2726 mono_error_assert_ok (error);
2728 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2730 if (image_is_dynamic (klass->image))
2731 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2733 mono_loader_unlock ();
2736 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2737 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2738 MonoMethodHeader *header;
2740 gint32 max_stack, i;
2741 gint32 num_locals = 0;
2742 gint32 num_clauses = 0;
2746 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2747 code_size = rmb->ilgen->code_len;
2748 max_stack = rmb->ilgen->max_stack;
2749 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2750 if (rmb->ilgen->ex_handlers)
2751 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2754 code = mono_array_addr (rmb->code, guint8, 0);
2755 code_size = mono_array_length (rmb->code);
2756 /* we probably need to run a verifier on the code... */
2766 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2767 header->code_size = code_size;
2768 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2769 memcpy ((char*)header->code, code, code_size);
2770 header->max_stack = max_stack;
2771 header->init_locals = rmb->init_locals;
2772 header->num_locals = num_locals;
2774 for (i = 0; i < num_locals; ++i) {
2775 MonoReflectionLocalBuilder *lb =
2776 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2778 header->locals [i] = image_g_new0 (image, MonoType, 1);
2779 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2780 mono_error_assert_ok (error);
2781 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2784 header->num_clauses = num_clauses;
2786 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2787 rmb->ilgen, num_clauses, error);
2788 mono_error_assert_ok (error);
2791 wrapperm->header = header;
2794 if (rmb->generic_params) {
2795 int count = mono_array_length (rmb->generic_params);
2796 MonoGenericContainer *container;
2798 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2799 container->is_method = TRUE;
2800 container->is_anonymous = FALSE;
2801 container->type_argc = count;
2802 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2803 container->owner.method = m;
2805 m->is_generic = TRUE;
2806 mono_method_set_generic_container (m, container);
2808 for (i = 0; i < count; i++) {
2809 MonoReflectionGenericParam *gp =
2810 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2811 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2812 mono_error_assert_ok (error);
2813 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2814 container->type_params [i] = *param;
2815 container->type_params [i].param.owner = container;
2817 gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2819 MonoClass *gklass = mono_class_from_mono_type (gp_type);
2820 gklass->wastypebuilder = TRUE;
2824 * The method signature might have pointers to generic parameters that belong to other methods.
2825 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2826 * generic parameters.
2828 for (i = 0; i < m->signature->param_count; ++i) {
2829 MonoType *t = m->signature->params [i];
2830 if (t->type == MONO_TYPE_MVAR) {
2831 MonoGenericParam *gparam = t->data.generic_param;
2832 if (gparam->num < count) {
2833 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2834 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2840 if (mono_class_is_gtd (klass)) {
2841 container->parent = mono_class_get_generic_container (klass);
2842 container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2844 container->context.method_inst = mono_get_shared_generic_inst (container);
2848 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2852 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2854 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2855 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2856 for (i = 0; i < rmb->nrefs; ++i)
2857 data [i + 1] = rmb->refs [i];
2862 /* Parameter info */
2865 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2866 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2867 for (i = 0; i <= m->signature->param_count; ++i) {
2868 MonoReflectionParamBuilder *pb;
2869 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2870 if ((i > 0) && (pb->attrs)) {
2871 /* Make a copy since it might point to a shared type structure */
2872 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2873 m->signature->params [i - 1]->attrs = pb->attrs;
2876 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2877 MonoDynamicImage *assembly;
2879 MonoTypeEnum def_type;
2883 if (!method_aux->param_defaults) {
2884 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2885 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2887 assembly = (MonoDynamicImage*)klass->image;
2888 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
2889 /* Copy the data from the blob since it might get realloc-ed */
2890 p = assembly->blob.data + idx;
2891 len = mono_metadata_decode_blob_size (p, &p2);
2893 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
2894 method_aux->param_default_types [i] = def_type;
2895 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
2899 method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
2900 mono_error_assert_ok (error);
2903 if (!method_aux->param_cattr)
2904 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
2905 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
2911 /* Parameter marshalling */
2914 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
2915 MonoReflectionParamBuilder *pb;
2916 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2917 if (pb->marshal_info) {
2919 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
2920 specs [pb->position] =
2921 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
2922 if (!is_ok (error)) {
2923 mono_loader_unlock ();
2924 image_g_free (image, specs);
2925 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2931 if (specs != NULL) {
2933 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2934 method_aux->param_marshall = specs;
2937 if (image_is_dynamic (klass->image) && method_aux)
2938 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2940 mono_loader_unlock ();
2946 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
2948 ReflectionMethodBuilder rmb;
2949 MonoMethodSignature *sig;
2951 mono_loader_lock ();
2953 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
2956 g_assert (klass->image != NULL);
2957 sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
2958 mono_loader_unlock ();
2959 return_val_if_nok (error, NULL);
2961 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2962 return_val_if_nok (error, NULL);
2963 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2965 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
2966 /* ilgen is no longer needed */
2974 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
2976 ReflectionMethodBuilder rmb;
2977 MonoMethodSignature *sig;
2979 mono_error_init (error);
2981 mono_loader_lock ();
2983 MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
2984 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
2987 g_assert (klass->image != NULL);
2988 sig = method_builder_to_signature (klass->image, ref_mb, error);
2989 mono_loader_unlock ();
2990 return_val_if_nok (error, NULL);
2992 MonoMethod *method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2993 return_val_if_nok (error, NULL);
2994 MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
2995 mono_save_custom_attrs (klass->image, method, mb->cattrs);
2997 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
2998 /* ilgen is no longer needed */
3004 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
3006 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3007 mono_error_init (error);
3008 MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
3009 MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
3010 HANDLE_FUNCTION_RETURN_VAL (result);
3015 #ifndef DISABLE_REFLECTION_EMIT
3018 * fix_partial_generic_class:
3019 * @klass: a generic instantiation MonoClass
3020 * @error: set on error
3022 * Assumes that the generic container of @klass has its vtable
3023 * initialized, and updates the parent class, interfaces, methods and
3024 * fields of @klass by inflating the types using the generic context.
3026 * On success returns TRUE, on failure returns FALSE and sets @error.
3030 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3032 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3035 mono_error_init (error);
3037 if (klass->wastypebuilder)
3040 if (klass->parent != gklass->parent) {
3041 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
3042 if (mono_error_ok (error)) {
3043 MonoClass *parent = mono_class_from_mono_type (parent_type);
3044 mono_metadata_free_type (parent_type);
3045 if (parent != klass->parent) {
3046 /*fool mono_class_setup_parent*/
3047 klass->supertypes = NULL;
3048 mono_class_setup_parent (klass, parent);
3051 if (gklass->wastypebuilder)
3052 klass->wastypebuilder = TRUE;
3057 if (!mono_class_get_generic_class (klass)->need_sync)
3060 int mcount = mono_class_get_method_count (klass);
3061 int gmcount = mono_class_get_method_count (gklass);
3062 if (mcount != gmcount) {
3063 mono_class_set_method_count (klass, gmcount);
3064 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
3066 for (i = 0; i < gmcount; i++) {
3067 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3068 gklass->methods [i], klass, mono_class_get_context (klass), error);
3069 mono_error_assert_ok (error);
3073 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3074 klass->interface_count = gklass->interface_count;
3075 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3076 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3078 for (i = 0; i < gklass->interface_count; ++i) {
3079 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3080 return_val_if_nok (error, FALSE);
3082 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3083 mono_metadata_free_type (iface_type);
3085 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3088 klass->interfaces_inited = 1;
3091 int fcount = mono_class_get_field_count (klass);
3092 int gfcount = mono_class_get_field_count (gklass);
3093 if (fcount != gfcount) {
3094 mono_class_set_field_count (klass, gfcount);
3095 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3097 for (i = 0; i < gfcount; i++) {
3098 klass->fields [i] = gklass->fields [i];
3099 klass->fields [i].parent = klass;
3100 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3101 return_val_if_nok (error, FALSE);
3105 /*We can only finish with this klass once it's parent has as well*/
3106 if (gklass->wastypebuilder)
3107 klass->wastypebuilder = TRUE;
3112 * ensure_generic_class_runtime_vtable:
3113 * @klass a generic class
3114 * @error set on error
3116 * Ensures that the generic container of @klass has a vtable and
3117 * returns TRUE on success. On error returns FALSE and sets @error.
3120 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3122 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3124 mono_error_init (error);
3126 if (!ensure_runtime_vtable (gklass, error))
3129 return fix_partial_generic_class (klass, error);
3133 * ensure_runtime_vtable:
3135 * @error set on error
3137 * Ensures that @klass has a vtable and returns TRUE on success. On
3138 * error returns FALSE and sets @error.
3141 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3143 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3146 mono_error_init (error);
3148 if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3151 if (!ensure_runtime_vtable (klass->parent, error))
3155 num = tb->ctors? mono_array_length (tb->ctors): 0;
3156 num += tb->num_methods;
3157 mono_class_set_method_count (klass, num);
3158 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3159 num = tb->ctors? mono_array_length (tb->ctors): 0;
3160 for (i = 0; i < num; ++i) {
3161 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3164 klass->methods [i] = ctor;
3166 num = tb->num_methods;
3168 for (i = 0; i < num; ++i) {
3169 MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
3172 klass->methods [j++] = meth;
3175 if (tb->interfaces) {
3176 klass->interface_count = mono_array_length (tb->interfaces);
3177 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3178 for (i = 0; i < klass->interface_count; ++i) {
3179 MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
3180 return_val_if_nok (error, FALSE);
3181 klass->interfaces [i] = mono_class_from_mono_type (iface);
3182 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3185 klass->interfaces_inited = 1;
3187 } else if (mono_class_is_ginst (klass)){
3188 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3189 mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3194 if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3196 int mcount = mono_class_get_method_count (klass);
3197 for (i = 0; i < mcount; ++i) {
3198 MonoMethod *im = klass->methods [i];
3199 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3200 im->slot = slot_num++;
3203 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3204 mono_class_setup_interface_offsets (klass);
3205 mono_class_setup_interface_id (klass);
3209 * The generic vtable is needed even if image->run is not set since some
3210 * runtime code like ves_icall_Type_GetMethodsByName depends on
3211 * method->slot being defined.
3215 * tb->methods could not be freed since it is used for determining
3216 * overrides during dynamic vtable construction.
3223 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3225 mono_error_init (error);
3226 MonoClass *klass = mono_object_class (method);
3227 if (is_sr_mono_method (klass)) {
3228 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3229 return sr_method->method;
3231 if (is_sre_method_builder (klass)) {
3232 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3235 if (mono_is_sre_method_on_tb_inst (klass)) {
3236 MonoClass *handle_class;
3238 MonoMethod *result = mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3239 return_val_if_nok (error, NULL);
3244 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3249 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3251 MonoReflectionTypeBuilder *tb;
3253 MonoReflectionMethod *m;
3255 mono_error_init (error);
3259 g_assert (image_is_dynamic (klass->image));
3261 if (!mono_class_has_ref_info (klass))
3264 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3265 g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
3269 for (i = 0; i < tb->num_methods; ++i) {
3270 MonoReflectionMethodBuilder *mb =
3271 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3272 if (mb->override_methods)
3273 onum += mono_array_length (mb->override_methods);
3278 *overrides = g_new0 (MonoMethod*, onum * 2);
3281 for (i = 0; i < tb->num_methods; ++i) {
3282 MonoReflectionMethodBuilder *mb =
3283 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3284 if (mb->override_methods) {
3285 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3286 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3288 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3289 return_if_nok (error);
3290 (*overrides) [onum * 2 + 1] = mb->mhandle;
3292 g_assert (mb->mhandle);
3300 *num_overrides = onum;
3303 /* This initializes the same data as mono_class_setup_fields () */
3305 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3307 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3308 MonoReflectionFieldBuilder *fb;
3309 MonoClassField *field;
3310 MonoFieldDefaultValue *def_values;
3311 MonoImage *image = klass->image;
3313 int i, instance_size, packing_size = 0;
3316 if (klass->parent) {
3317 if (!klass->parent->size_inited)
3318 mono_class_init (klass->parent);
3319 instance_size = klass->parent->instance_size;
3321 instance_size = sizeof (MonoObject);
3324 int fcount = tb->num_fields;
3325 mono_class_set_field_count (klass, fcount);
3327 mono_error_init (error);
3329 if (tb->class_size) {
3330 packing_size = tb->packing_size;
3331 instance_size += tb->class_size;
3334 klass->fields = image_g_new0 (image, MonoClassField, fcount);
3335 def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3336 mono_class_set_field_def_values (klass, def_values);
3338 This is, guess what, a hack.
3339 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3340 On the static path no field class is resolved, only types are built. This is the right thing to do
3342 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3344 klass->size_inited = 1;
3346 for (i = 0; i < fcount; ++i) {
3347 MonoArray *rva_data;
3348 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3349 field = &klass->fields [i];
3350 field->parent = klass;
3351 field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
3352 if (!mono_error_ok (error))
3355 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3356 return_if_nok (error);
3357 field->type = mono_metadata_type_dup (klass->image, type);
3358 field->type->attrs = fb->attrs;
3360 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3361 return_if_nok (error);
3364 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3365 char *base = mono_array_addr (rva_data, char, 0);
3366 size_t size = mono_array_length (rva_data);
3367 char *data = (char *)mono_image_alloc (klass->image, size);
3368 memcpy (data, base, size);
3369 def_values [i].data = data;
3371 if (fb->offset != -1)
3372 field->offset = fb->offset;
3374 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3376 if (fb->def_value) {
3377 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3378 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3379 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3380 /* Copy the data from the blob since it might get realloc-ed */
3381 p = assembly->blob.data + idx;
3382 len = mono_metadata_decode_blob_size (p, &p2);
3384 def_values [i].data = (const char *)mono_image_alloc (image, len);
3385 memcpy ((gpointer)def_values [i].data, p, len);
3389 mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3393 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3395 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3396 MonoReflectionPropertyBuilder *pb;
3397 MonoImage *image = klass->image;
3398 MonoProperty *properties;
3399 MonoClassPropertyInfo *info;
3402 mono_error_init (error);
3404 info = mono_class_get_property_info (klass);
3406 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3407 mono_class_set_property_info (klass, info);
3410 info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3413 properties = image_g_new0 (image, MonoProperty, info->count);
3414 info->properties = properties;
3415 for (i = 0; i < info->count; ++i) {
3416 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3417 properties [i].parent = klass;
3418 properties [i].attrs = pb->attrs;
3419 properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
3420 if (!mono_error_ok (error))
3423 properties [i].get = pb->get_method->mhandle;
3425 properties [i].set = pb->set_method->mhandle;
3427 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3428 if (pb->def_value) {
3431 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3432 if (!info->def_values)
3433 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3434 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3435 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3436 /* Copy the data from the blob since it might get realloc-ed */
3437 p = assembly->blob.data + idx;
3438 len = mono_metadata_decode_blob_size (p, &p2);
3440 info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3441 memcpy ((gpointer)info->def_values [i].data, p, len);
3447 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3449 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3450 MonoReflectionEventBuilder *eb;
3451 MonoImage *image = klass->image;
3453 MonoClassEventInfo *info;
3456 mono_error_init (error);
3458 info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3459 mono_class_set_event_info (klass, info);
3461 info->count = tb->events ? mono_array_length (tb->events) : 0;
3464 events = image_g_new0 (image, MonoEvent, info->count);
3465 info->events = events;
3466 for (i = 0; i < info->count; ++i) {
3467 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3468 events [i].parent = klass;
3469 events [i].attrs = eb->attrs;
3470 events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
3471 if (!mono_error_ok (error))
3474 events [i].add = eb->add_method->mhandle;
3475 if (eb->remove_method)
3476 events [i].remove = eb->remove_method->mhandle;
3477 if (eb->raise_method)
3478 events [i].raise = eb->raise_method->mhandle;
3480 #ifndef MONO_SMALL_CONFIG
3481 if (eb->other_methods) {
3483 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3484 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3485 MonoReflectionMethodBuilder *mb =
3486 mono_array_get (eb->other_methods,
3487 MonoReflectionMethodBuilder*, j);
3488 events [i].other [j] = mb->mhandle;
3492 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3496 struct remove_instantiations_user_data
3503 remove_instantiations_of_and_ensure_contents (gpointer key,
3507 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3508 MonoType *type = (MonoType*)key;
3509 MonoClass *klass = data->klass;
3510 gboolean already_failed = !is_ok (data->error);
3512 MonoError *error = already_failed ? &lerror : data->error;
3514 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3515 MonoClass *inst_klass = mono_class_from_mono_type (type);
3516 //Ensure it's safe to use it.
3517 if (!fix_partial_generic_class (inst_klass, error)) {
3518 mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3519 // Marked the class with failure, but since some other instantiation already failed,
3520 // just report that one, and swallow the error from this one.
3522 mono_error_cleanup (error);
3529 MonoReflectionTypeHandle
3530 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3532 mono_error_init (error);
3534 reflection_create_generic_class (ref_tb, error);
3535 mono_error_assert_ok (error);
3537 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
3538 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
3539 MonoClass *klass = mono_class_from_mono_type (type);
3541 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
3542 mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
3545 * we need to lock the domain because the lock will be taken inside
3546 * So, we need to keep the locking order correct.
3548 mono_loader_lock ();
3549 mono_domain_lock (domain);
3550 if (klass->wastypebuilder) {
3551 mono_domain_unlock (domain);
3552 mono_loader_unlock ();
3554 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
3557 * Fields to set in klass:
3558 * the various flags: delegate/unicode/contextbound etc.
3560 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
3561 klass->has_cctor = 1;
3563 mono_class_setup_parent (klass, klass->parent);
3564 /* fool mono_class_setup_supertypes */
3565 klass->supertypes = NULL;
3566 mono_class_setup_supertypes (klass);
3567 mono_class_setup_mono_type (klass);
3569 /* enums are done right away */
3570 if (!klass->enumtype)
3571 if (!ensure_runtime_vtable (klass, error))
3574 MonoArrayHandle nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
3575 if (!MONO_HANDLE_IS_NULL (nested_types)) {
3576 GList *nested = NULL;
3577 int num_nested = mono_array_handle_length (nested_types);
3578 MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3579 for (int i = 0; i < num_nested; ++i) {
3580 MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
3582 if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
3583 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
3584 mono_error_assert_ok (error);
3587 MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
3588 if (!is_ok (error)) goto failure;
3589 nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3591 mono_class_set_nested_classes_property (klass, nested);
3594 klass->nested_classes_inited = TRUE;
3596 typebuilder_setup_fields (klass, error);
3599 typebuilder_setup_properties (klass, error);
3603 typebuilder_setup_events (klass, error);
3607 klass->wastypebuilder = TRUE;
3609 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
3610 if (!MONO_HANDLE_IS_NULL (generic_params)) {
3611 int num_params = mono_array_handle_length (generic_params);
3612 MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3613 for (int i = 0; i < num_params; i++) {
3614 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
3615 MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
3618 MonoClass *gklass = mono_class_from_mono_type (param_type);
3620 gklass->wastypebuilder = TRUE;
3625 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3626 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3627 * we want to return normal System.MonoType objects, so clear these out from the cache.
3629 * Together with this we must ensure the contents of all instances to match the created type.
3631 if (domain->type_hash && mono_class_is_gtd (klass)) {
3632 struct remove_instantiations_user_data data;
3635 mono_error_assert_ok (error);
3636 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3641 mono_domain_unlock (domain);
3642 mono_loader_unlock ();
3644 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3645 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3646 mono_error_set_type_load_class (error, klass, "Not a valid enumeration");
3647 goto failure_unlocked;
3650 MonoReflectionTypeHandle res = mono_type_get_object_handle (domain, &klass->byval_arg, error);
3652 goto failure_unlocked;
3657 mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
3658 klass->wastypebuilder = TRUE;
3659 mono_domain_unlock (domain);
3660 mono_loader_unlock ();
3668 } DynamicMethodReleaseData;
3671 * The runtime automatically clean up those after finalization.
3673 static MonoReferenceQueue *dynamic_method_queue;
3676 free_dynamic_method (void *dynamic_method)
3678 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3679 MonoDomain *domain = data->domain;
3680 MonoMethod *method = data->handle;
3683 mono_domain_lock (domain);
3684 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3685 g_hash_table_remove (domain->method_to_dyn_method, method);
3686 mono_domain_unlock (domain);
3687 g_assert (dis_link);
3688 mono_gchandle_free (dis_link);
3690 mono_runtime_free_method (domain, method);
3695 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
3697 MonoReferenceQueue *queue;
3699 DynamicMethodReleaseData *release_data;
3700 ReflectionMethodBuilder rmb;
3701 MonoMethodSignature *sig;
3707 mono_error_init (error);
3709 if (mono_runtime_is_shutting_down ()) {
3710 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3714 if (!(queue = dynamic_method_queue)) {
3715 mono_loader_lock ();
3716 if (!(queue = dynamic_method_queue))
3717 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3718 mono_loader_unlock ();
3721 sig = dynamic_method_to_signature (ref_mb, error);
3722 return_val_if_nok (error, FALSE);
3724 MonoReflectionDynamicMethod *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
3725 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3728 * Resolve references.
3731 * Every second entry in the refs array is reserved for storing handle_class,
3732 * which is needed by the ldtoken implementation in the JIT.
3734 rmb.nrefs = mb->nrefs;
3735 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3736 for (i = 0; i < mb->nrefs; i += 2) {
3737 MonoClass *handle_class;
3739 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3741 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3742 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3744 * The referenced DynamicMethod should already be created by the managed
3745 * code, except in the case of circular references. In that case, we store
3746 * method in the refs array, and fix it up later when the referenced
3747 * DynamicMethod is created.
3749 if (method->mhandle) {
3750 ref = method->mhandle;
3752 /* FIXME: GC object stored in unmanaged memory */
3755 /* FIXME: GC object stored in unmanaged memory */
3756 method->referenced_by = g_slist_append (method->referenced_by, mb);
3758 handle_class = mono_defaults.methodhandle_class;
3760 MonoException *ex = NULL;
3761 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3762 if (!is_ok (error)) {
3767 ex = mono_get_exception_type_load (NULL, NULL);
3768 else if (mono_security_core_clr_enabled ())
3769 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3773 mono_error_set_exception_instance (error, ex);
3778 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3779 rmb.refs [i + 1] = handle_class;
3783 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3784 if (!is_ok (error)) {
3788 klass = mono_class_from_mono_type (owner_type);
3790 klass = mono_defaults.object_class;
3793 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3795 return_val_if_nok (error, FALSE);
3797 release_data = g_new (DynamicMethodReleaseData, 1);
3798 release_data->handle = handle;
3799 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3800 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3801 g_free (release_data);
3803 /* Fix up refs entries pointing at us */
3804 for (l = mb->referenced_by; l; l = l->next) {
3805 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3806 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3809 g_assert (method->mhandle);
3811 data = (gpointer*)wrapper->method_data;
3812 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3813 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3814 data [i + 1] = mb->mhandle;
3817 g_slist_free (mb->referenced_by);
3819 /* ilgen is no longer needed */
3822 domain = mono_domain_get ();
3823 mono_domain_lock (domain);
3824 if (!domain->method_to_dyn_method)
3825 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3826 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3827 mono_domain_unlock (domain);
3833 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
3835 (void) reflection_create_dynamic_method (mb, error);
3838 #endif /* DISABLE_REFLECTION_EMIT */
3840 MonoMethodSignature *
3841 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3843 MonoMethodSignature *sig;
3844 g_assert (image_is_dynamic (image));
3846 mono_error_init (error);
3848 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
3852 return mono_method_signature_checked (method, error);
3855 #ifndef DISABLE_REFLECTION_EMIT
3858 * ensure_complete_type:
3860 * Ensure that KLASS is completed if it is a dynamic type, or references
3864 ensure_complete_type (MonoClass *klass, MonoError *error)
3866 mono_error_init (error);
3868 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
3869 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3871 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3872 return_if_nok (error);
3874 // Asserting here could break a lot of code
3875 //g_assert (klass->wastypebuilder);
3878 if (mono_class_is_ginst (klass)) {
3879 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
3882 for (i = 0; i < inst->type_argc; ++i) {
3883 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
3884 return_if_nok (error);
3890 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
3892 MonoClass *oklass = obj->vtable->klass;
3893 gpointer result = NULL;
3895 mono_error_init (error);
3897 if (strcmp (oklass->name, "String") == 0) {
3898 result = mono_string_intern_checked ((MonoString*)obj, error);
3899 return_val_if_nok (error, NULL);
3900 *handle_class = mono_defaults.string_class;
3902 } else if (strcmp (oklass->name, "RuntimeType") == 0) {
3903 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
3904 return_val_if_nok (error, NULL);
3905 MonoClass *mc = mono_class_from_mono_type (type);
3906 if (!mono_class_init (mc)) {
3907 mono_error_set_for_class_failure (error, mc);
3912 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
3913 return_val_if_nok (error, NULL);
3915 result = mono_class_from_mono_type (inflated);
3916 mono_metadata_free_type (inflated);
3918 result = mono_class_from_mono_type (type);
3920 *handle_class = mono_defaults.typehandle_class;
3922 } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
3923 strcmp (oklass->name, "MonoCMethod") == 0) {
3924 result = ((MonoReflectionMethod*)obj)->method;
3926 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
3927 mono_error_assert_ok (error);
3929 *handle_class = mono_defaults.methodhandle_class;
3931 } else if (strcmp (oklass->name, "MonoField") == 0) {
3932 MonoClassField *field = ((MonoReflectionField*)obj)->field;
3934 ensure_complete_type (field->parent, error);
3935 return_val_if_nok (error, NULL);
3938 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
3939 return_val_if_nok (error, NULL);
3941 MonoClass *klass = mono_class_from_mono_type (inflated);
3942 MonoClassField *inflated_field;
3943 gpointer iter = NULL;
3944 mono_metadata_free_type (inflated);
3945 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
3946 if (!strcmp (field->name, inflated_field->name))
3949 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
3950 result = inflated_field;
3954 *handle_class = mono_defaults.fieldhandle_class;
3956 } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
3957 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
3958 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3959 return_val_if_nok (error, NULL);
3962 klass = type->data.klass;
3963 if (klass->wastypebuilder) {
3964 /* Already created */
3968 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3969 return_val_if_nok (error, NULL);
3970 result = type->data.klass;
3973 *handle_class = mono_defaults.typehandle_class;
3974 } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
3975 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
3976 MonoMethodSignature *sig;
3979 if (helper->arguments)
3980 nargs = mono_array_length (helper->arguments);
3984 sig = mono_metadata_signature_alloc (image, nargs);
3985 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
3986 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
3988 if (helper->unmanaged_call_conv) { /* unmanaged */
3989 sig->call_convention = helper->unmanaged_call_conv - 1;
3990 sig->pinvoke = TRUE;
3991 } else if (helper->call_conv & 0x02) {
3992 sig->call_convention = MONO_CALL_VARARG;
3994 sig->call_convention = MONO_CALL_DEFAULT;
3997 sig->param_count = nargs;
3998 /* TODO: Copy type ? */
3999 sig->ret = helper->return_type->type;
4000 for (i = 0; i < nargs; ++i) {
4001 sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
4002 if (!is_ok (error)) {
4003 image_g_free (image, sig);
4009 *handle_class = NULL;
4010 } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4011 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4012 /* Already created by the managed code */
4013 g_assert (method->mhandle);
4014 result = method->mhandle;
4015 *handle_class = mono_defaults.methodhandle_class;
4016 } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4017 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4024 mtype = mono_reflection_type_get_handle (m->parent, error);
4025 return_val_if_nok (error, NULL);
4026 klass = mono_class_from_mono_type (mtype);
4028 /* Find the method */
4030 name = mono_string_to_utf8_checked (m->name, error);
4031 return_val_if_nok (error, NULL);
4033 while ((method = mono_class_get_methods (klass, &iter))) {
4034 if (!strcmp (method->name, name))
4041 // FIXME: Check parameters/return value etc. match
4044 *handle_class = mono_defaults.methodhandle_class;
4045 } else if (is_sre_method_builder (oklass) ||
4046 mono_is_sre_ctor_builder (oklass) ||
4047 is_sre_field_builder (oklass) ||
4048 is_sre_gparam_builder (oklass) ||
4049 is_sre_generic_instance (oklass) ||
4050 is_sre_array (oklass) ||
4051 is_sre_byref (oklass) ||
4052 is_sre_pointer (oklass) ||
4053 !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4054 !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4055 !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4056 static MonoMethod *resolve_method;
4057 if (!resolve_method) {
4058 MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4060 mono_memory_barrier ();
4065 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4066 mono_error_assert_ok (error);
4068 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
4070 g_print ("%s\n", obj->vtable->klass->name);
4071 g_assert_not_reached ();
4076 #else /* DISABLE_REFLECTION_EMIT */
4079 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4081 g_assert_not_reached ();
4086 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4088 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4092 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4094 g_assert_not_reached ();
4099 mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4101 g_assert_not_reached ();
4106 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
4108 g_assert_not_reached ();
4113 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
4114 gboolean create_open_instance, gboolean register_token, MonoError *error)
4116 g_assert_not_reached ();
4121 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4123 mono_error_init (error);
4128 MonoReflectionTypeHandle
4129 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
4131 g_assert_not_reached ();
4136 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4138 mono_error_init (error);
4142 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4144 mono_error_init (error);
4151 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
4153 mono_error_init (error);
4154 if (MONO_HANDLE_IS_NULL (ref))
4156 return MONO_HANDLE_GETVAL (ref, type);
4160 #endif /* DISABLE_REFLECTION_EMIT */
4163 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4165 mono_gc_deregister_root ((char*) &entry->gparam);
4170 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
4172 mono_error_init (error);
4173 if (MONO_HANDLE_IS_NULL (obj)) {
4174 mono_error_set_argument_null (error, "obj", "");
4177 return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
4181 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
4182 MonoReflectionMethodHandle method,
4183 MonoArrayHandle opt_param_types,
4186 mono_error_init (error);
4187 if (MONO_HANDLE_IS_NULL (method)) {
4188 mono_error_set_argument_null (error, "method", "");
4192 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
4196 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4199 mono_image_create_pefile (mb, file, &error);
4200 mono_error_set_pending_exception (&error);
4204 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4207 mono_image_build_metadata (mb, &error);
4208 mono_error_set_pending_exception (&error);
4212 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
4214 mono_error_init (error);
4215 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj);
4219 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
4223 mono_loader_lock ();
4224 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
4225 mono_loader_unlock ();
4230 #ifndef DISABLE_REFLECTION_EMIT
4232 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4235 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4236 mono_error_set_pending_exception (&error);
4242 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4244 mono_reflection_dynimage_basic_init (assemblyb);
4248 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
4249 MonoReflectionType *t)
4251 enumtype->type = t->type;
4255 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4257 mono_error_init (error);
4258 mono_image_module_basic_init (moduleb, error);
4262 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4264 return mono_image_insert_string (module, str, error);
4268 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
4270 MonoDynamicImage *image = moduleb->dynamic_image;
4272 g_assert (type->type);
4273 image->wrappers_type = mono_class_from_mono_type (type->type);