[mono] Introduce MonoMemoryManager to hold memory previously owned by the domain...
[mono-project.git] / mono / metadata / sre.c
blobad482f98330bb6b02c4400159c72884b85da1eff
1 /**
2 * \file
3 * Routines for creating an image at runtime
4 * and related System.Reflection.Emit icalls
5 *
6 *
7 * Author:
8 * Paolo Molaro (lupus@ximian.com)
10 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
12 * Copyright 2011 Rodrigo Kumpera
13 * Copyright 2016 Microsoft
15 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
17 #include <config.h>
18 #include <glib.h>
19 #include "mono/metadata/assembly.h"
20 #include "mono/metadata/assembly-internals.h"
21 #include "mono/metadata/class-init.h"
22 #include "mono/metadata/debug-helpers.h"
23 #include "mono/metadata/dynamic-image-internals.h"
24 #include "mono/metadata/dynamic-stream-internals.h"
25 #include "mono/metadata/exception.h"
26 #include "mono/metadata/gc-internals.h"
27 #include "mono/metadata/mono-ptr-array.h"
28 #include "mono/metadata/object-internals.h"
29 #include "mono/metadata/profiler-private.h"
30 #include "mono/metadata/reflection-internals.h"
31 #include "mono/metadata/reflection-cache.h"
32 #include "mono/metadata/sre-internals.h"
33 #include "mono/metadata/custom-attrs-internals.h"
34 #include "mono/metadata/security-manager.h"
35 #include "mono/metadata/security-core-clr.h"
36 #include "mono/metadata/tabledefs.h"
37 #include "mono/metadata/tokentype.h"
38 #include "mono/metadata/abi-details.h"
39 #include "mono/utils/checked-build.h"
40 #include "mono/utils/mono-digest.h"
41 #include "mono/utils/w32api.h"
42 #ifdef MONO_CLASS_DEF_PRIVATE
43 /* Rationale: Some of the code here does MonoClass construction.
44 * FIXME: Move SRE class construction to class-init.c and unify with ordinary class construction.
46 #define REALLY_INCLUDE_CLASS_DEF 1
47 #include <mono/metadata/class-private-definition.h>
48 #undef REALLY_INCLUDE_CLASS_DEF
49 #endif
50 #include "icall-decl.h"
52 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, "System.Runtime.InteropServices", "MarshalAsAttribute");
53 #ifndef DISABLE_REFLECTION_EMIT
54 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", "ModuleBuilder");
55 #endif
57 static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
59 #ifndef DISABLE_REFLECTION_EMIT
60 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
61 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
62 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
63 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
64 static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
65 static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
68 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
69 #endif
71 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
72 static MonoReflectionTypeHandle mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error);
73 static gboolean is_sre_array (MonoClass *klass);
74 static gboolean is_sre_byref (MonoClass *klass);
75 static gboolean is_sre_pointer (MonoClass *klass);
76 static gboolean is_sre_generic_instance (MonoClass *klass);
77 static gboolean is_sre_type_builder (MonoClass *klass);
78 static gboolean is_sre_method_builder (MonoClass *klass);
79 static gboolean is_sre_field_builder (MonoClass *klass);
80 static gboolean is_sre_gparam_builder (MonoClass *klass);
81 static gboolean is_sre_enum_builder (MonoClass *klass);
82 static gboolean is_sr_mono_method (MonoClass *klass);
84 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
85 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
86 static guint32 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error);
89 #ifndef DISABLE_REFLECTION_EMIT
90 static MonoType* mono_type_array_get_and_resolve_raw (MonoArray* array, int idx, MonoError* error);
91 #endif
93 static gboolean mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module, MonoError *error);
95 void
96 mono_reflection_emit_init (void)
98 mono_dynamic_images_init ();
101 char*
102 string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
104 /* FIXME all callers to string_to_utf8_image_raw should use handles */
105 HANDLE_FUNCTION_ENTER ();
106 error_init (error);
107 MONO_HANDLE_DCL (MonoString, s);
108 char* const result = mono_string_to_utf8_image (image, s, error);
109 HANDLE_FUNCTION_RETURN_VAL (result);
112 static char*
113 type_get_fully_qualified_name (MonoType *type)
115 MONO_REQ_GC_NEUTRAL_MODE;
117 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
120 static char*
121 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
123 MONO_REQ_GC_UNSAFE_MODE;
125 MonoClass *klass;
126 MonoAssembly *ta;
128 klass = mono_class_from_mono_type_internal (type);
129 if (!klass)
130 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
131 ta = klass->image->assembly;
132 if (assembly_is_dynamic (ta) || (ta == ass)) {
133 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
134 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
135 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
136 else
137 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
140 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
143 #ifndef DISABLE_REFLECTION_EMIT
145 * mp_g_alloc:
147 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
148 * from the C heap.
150 static gpointer
151 image_g_malloc (MonoImage *image, guint size)
153 MONO_REQ_GC_NEUTRAL_MODE;
155 if (image)
156 return mono_image_alloc (image, size);
157 else
158 return g_malloc (size);
160 #endif /* !DISABLE_REFLECTION_EMIT */
163 * image_g_alloc0:
165 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
166 * from the C heap.
168 gpointer
169 (mono_image_g_malloc0) (MonoImage *image, guint size)
171 MONO_REQ_GC_NEUTRAL_MODE;
173 if (image)
174 return mono_image_alloc0 (image, size);
175 else
176 return g_malloc0 (size);
180 * image_g_free:
181 * @image: a MonoImage
182 * @ptr: pointer
184 * If @image is NULL, free @ptr, otherwise do nothing.
186 static void
187 image_g_free (MonoImage *image, gpointer ptr)
189 if (image == NULL)
190 g_free (ptr);
193 #ifndef DISABLE_REFLECTION_EMIT
194 static char*
195 image_strdup (MonoImage *image, const char *s)
197 MONO_REQ_GC_NEUTRAL_MODE;
199 if (image)
200 return mono_image_strdup (image, s);
201 else
202 return g_strdup (s);
204 #endif
206 #define image_g_new(image,struct_type, n_structs) \
207 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
209 #define image_g_new0(image,struct_type, n_structs) \
210 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
213 static void
214 alloc_table (MonoDynamicTable *table, guint nrows)
216 mono_dynimage_alloc_table (table, nrows);
219 static guint32
220 string_heap_insert (MonoDynamicStream *sh, const char *str)
222 return mono_dynstream_insert_string (sh, str);
225 static guint32
226 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
228 return mono_dynstream_add_data (stream, data, len);
232 * Despite the name, we handle also TypeSpec (with the above helper).
234 static guint32
235 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
237 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
241 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
242 * dest may be misaligned.
244 static void
245 swap_with_size (gpointer void_dest, gconstpointer void_val, int len, int nelem)
247 char *dest = (char*)void_dest;
248 const char* val = (const char*)void_val;
249 MONO_REQ_GC_NEUTRAL_MODE;
250 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
251 int elem;
253 for (elem = 0; elem < nelem; ++elem) {
254 switch (len) {
255 case 1:
256 *dest = *val;
257 break;
258 case 2:
259 dest [0] = val [1];
260 dest [1] = val [0];
261 break;
262 case 4:
263 dest [0] = val [3];
264 dest [1] = val [2];
265 dest [2] = val [1];
266 dest [3] = val [0];
267 break;
268 case 8:
269 dest [0] = val [7];
270 dest [1] = val [6];
271 dest [2] = val [5];
272 dest [3] = val [4];
273 dest [4] = val [3];
274 dest [5] = val [2];
275 dest [6] = val [1];
276 dest [7] = val [0];
277 break;
278 default:
279 g_assert_not_reached ();
281 dest += len;
282 val += len;
284 #else
285 memcpy (dest, val, len * nelem);
286 #endif
289 guint32
290 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
292 MONO_REQ_GC_UNSAFE_MODE;
294 guint32 num_clauses = 0;
295 int i;
297 MonoILExceptionInfo *ex_info;
298 for (i = 0; i < mono_array_length_internal (ilgen->ex_handlers); ++i) {
299 ex_info = (MonoILExceptionInfo*)mono_array_addr_internal (ilgen->ex_handlers, MonoILExceptionInfo, i);
300 if (ex_info->handlers)
301 num_clauses += mono_array_length_internal (ex_info->handlers);
302 else
303 num_clauses++;
306 return num_clauses;
309 #ifndef DISABLE_REFLECTION_EMIT
310 static MonoExceptionClause*
311 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
313 MONO_REQ_GC_UNSAFE_MODE;
315 error_init (error);
317 MonoExceptionClause *clauses;
318 MonoExceptionClause *clause;
319 MonoILExceptionInfo *ex_info;
320 MonoILExceptionBlock *ex_block;
321 guint32 finally_start;
322 int i, j, clause_index;
324 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
326 clause_index = 0;
327 for (i = mono_array_length_internal (ilgen->ex_handlers) - 1; i >= 0; --i) {
328 ex_info = (MonoILExceptionInfo*)mono_array_addr_internal (ilgen->ex_handlers, MonoILExceptionInfo, i);
329 finally_start = ex_info->start + ex_info->len;
330 if (!ex_info->handlers)
331 continue;
332 for (j = 0; j < mono_array_length_internal (ex_info->handlers); ++j) {
333 ex_block = (MonoILExceptionBlock*)mono_array_addr_internal (ex_info->handlers, MonoILExceptionBlock, j);
334 clause = &(clauses [clause_index]);
336 clause->flags = ex_block->type;
337 clause->try_offset = ex_info->start;
339 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
340 clause->try_len = finally_start - ex_info->start;
341 else
342 clause->try_len = ex_info->len;
343 clause->handler_offset = ex_block->start;
344 clause->handler_len = ex_block->len;
345 if (ex_block->extype) {
346 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
348 if (!is_ok (error)) {
349 image_g_free (image, clauses);
350 return NULL;
352 clause->data.catch_class = mono_class_from_mono_type_internal (extype);
353 } else {
354 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
355 clause->data.filter_offset = ex_block->filter_offset;
356 else
357 clause->data.filter_offset = 0;
359 finally_start = ex_block->start + ex_block->len;
361 clause_index ++;
365 return clauses;
367 #endif /* !DISABLE_REFLECTION_EMIT */
369 #ifndef DISABLE_REFLECTION_EMIT
371 * LOCKING: Acquires the loader lock.
373 static void
374 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
376 MONO_REQ_GC_UNSAFE_MODE;
378 MonoCustomAttrInfo *ainfo, *tmp;
380 if (!cattrs || !mono_array_length_internal (cattrs))
381 return;
383 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
385 mono_loader_lock ();
386 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
387 if (tmp)
388 mono_custom_attrs_free (tmp);
389 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
390 mono_loader_unlock ();
393 #else
394 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
395 static void
396 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
399 #endif
401 guint32
402 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
404 MONO_REQ_GC_UNSAFE_MODE;
406 MonoDynamicTable *table;
407 guint32 token;
408 guint32 *values;
409 guint32 cols [MONO_ASSEMBLY_SIZE];
410 const char *pubkey;
411 guint32 publen;
413 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
414 return token;
416 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
417 table = &assembly->tables [MONO_TABLE_MODULEREF];
418 token = table->next_idx ++;
419 table->rows ++;
420 alloc_table (table, table->rows);
421 values = table->values + token * MONO_MODULEREF_SIZE;
422 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
424 token <<= MONO_RESOLUTION_SCOPE_BITS;
425 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
426 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
428 return token;
431 if (assembly_is_dynamic (image->assembly))
432 /* FIXME: */
433 memset (cols, 0, sizeof (cols));
434 else {
435 /* image->assembly->image is the manifest module */
436 image = image->assembly->image;
437 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
440 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
441 token = table->next_idx ++;
442 table->rows ++;
443 alloc_table (table, table->rows);
444 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
445 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
446 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
447 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
448 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
449 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
450 values [MONO_ASSEMBLYREF_FLAGS] = 0;
451 values [MONO_ASSEMBLYREF_CULTURE] = 0;
452 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
454 if (strcmp ("", image->assembly->aname.culture)) {
455 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
456 image->assembly->aname.culture);
459 if ((pubkey = mono_image_get_public_key (image, &publen))) {
460 guchar pubtoken [9];
461 pubtoken [0] = 8;
462 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
463 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
464 } else {
465 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
467 token <<= MONO_RESOLUTION_SCOPE_BITS;
468 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
469 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
470 return token;
473 #ifndef DISABLE_REFLECTION_EMIT
474 gboolean
475 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
477 MONO_REQ_GC_UNSAFE_MODE;
479 error_init (error);
480 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
482 rmb->ilgen = mb->ilgen;
483 MONO_HANDLE_PIN (rmb->ilgen);
484 rmb->rtype = (MonoReflectionType*)mb->rtype;
485 MONO_HANDLE_PIN (rmb->rtype);
486 rmb->parameters = mb->parameters;
487 MONO_HANDLE_PIN (rmb->parameters);
488 rmb->generic_params = mb->generic_params;
489 MONO_HANDLE_PIN (rmb->generic_params);
490 rmb->generic_container = mb->generic_container;
491 rmb->opt_types = NULL;
492 rmb->pinfo = mb->pinfo;
493 MONO_HANDLE_PIN (rmb->pinfo);
494 rmb->attrs = mb->attrs;
495 rmb->iattrs = mb->iattrs;
496 rmb->call_conv = mb->call_conv;
497 rmb->code = mb->code;
498 MONO_HANDLE_PIN (rmb->code);
499 rmb->type = mb->type;
500 MONO_HANDLE_PIN (rmb->type);
501 rmb->name = mb->name;
502 MONO_HANDLE_PIN (rmb->name);
503 rmb->table_idx = &mb->table_idx;
504 rmb->init_locals = mb->init_locals;
505 rmb->skip_visibility = FALSE;
506 rmb->return_modreq = mb->return_modreq;
507 MONO_HANDLE_PIN (rmb->return_modreq);
508 rmb->return_modopt = mb->return_modopt;
509 MONO_HANDLE_PIN (rmb->return_modopt);
510 rmb->param_modreq = mb->param_modreq;
511 MONO_HANDLE_PIN (rmb->param_modreq);
512 rmb->param_modopt = mb->param_modopt;
513 MONO_HANDLE_PIN (rmb->param_modopt);
514 rmb->permissions = mb->permissions;
515 MONO_HANDLE_PIN (rmb->permissions);
516 rmb->mhandle = mb->mhandle;
517 rmb->nrefs = 0;
518 rmb->refs = NULL;
520 if (mb->dll) {
521 rmb->charset = mb->charset;
522 rmb->extra_flags = mb->extra_flags;
523 rmb->native_cc = mb->native_cc;
524 rmb->dllentry = mb->dllentry;
525 MONO_HANDLE_PIN (rmb->dllentry);
526 rmb->dll = mb->dll;
527 MONO_HANDLE_PIN (rmb->dll);
530 return TRUE;
533 gboolean
534 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
536 MONO_REQ_GC_UNSAFE_MODE;
538 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
540 error_init (error);
542 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
544 rmb->ilgen = mb->ilgen;
545 MONO_HANDLE_PIN (rmb->ilgen);
546 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), mono_get_void_type (), error);
547 return_val_if_nok (error, FALSE);
548 MONO_HANDLE_PIN (rmb->rtype);
549 rmb->parameters = mb->parameters;
550 MONO_HANDLE_PIN (rmb->parameters);
551 rmb->generic_params = NULL;
552 rmb->generic_container = NULL;
553 rmb->opt_types = NULL;
554 rmb->pinfo = mb->pinfo;
555 MONO_HANDLE_PIN (rmb->pinfo);
556 rmb->attrs = mb->attrs;
557 rmb->iattrs = mb->iattrs;
558 rmb->call_conv = mb->call_conv;
559 rmb->code = NULL;
560 rmb->type = mb->type;
561 MONO_HANDLE_PIN (rmb->type);
562 rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
563 return_val_if_nok (error, FALSE);
564 MONO_HANDLE_PIN (rmb->name);
565 rmb->table_idx = &mb->table_idx;
566 rmb->init_locals = mb->init_locals;
567 rmb->skip_visibility = FALSE;
568 rmb->return_modreq = NULL;
569 rmb->return_modopt = NULL;
570 rmb->param_modreq = mb->param_modreq;
571 MONO_HANDLE_PIN (rmb->param_modreq);
572 rmb->param_modopt = mb->param_modopt;
573 MONO_HANDLE_PIN (rmb->param_modopt);
574 rmb->permissions = mb->permissions;
575 MONO_HANDLE_PIN (rmb->permissions);
576 rmb->mhandle = mb->mhandle;
577 rmb->nrefs = 0;
578 rmb->refs = NULL;
580 return TRUE;
583 static void
584 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
586 MONO_REQ_GC_UNSAFE_MODE;
588 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
590 rmb->ilgen = mb->ilgen;
591 MONO_HANDLE_PIN (rmb->ilgen);
592 rmb->rtype = mb->rtype;
593 MONO_HANDLE_PIN (rmb->type);
594 rmb->parameters = mb->parameters;
595 MONO_HANDLE_PIN (rmb->parameters);
596 rmb->generic_params = NULL;
597 rmb->generic_container = NULL;
598 rmb->opt_types = NULL;
599 rmb->pinfo = NULL;
600 rmb->attrs = mb->attrs;
601 rmb->iattrs = 0;
602 rmb->call_conv = mb->call_conv;
603 rmb->code = NULL;
604 rmb->type = (MonoObject *) mb->owner;
605 MONO_HANDLE_PIN (rmb->type);
606 rmb->name = mb->name;
607 MONO_HANDLE_PIN (rmb->name);
608 rmb->table_idx = NULL;
609 rmb->init_locals = mb->init_locals;
610 rmb->skip_visibility = mb->skip_visibility;
611 rmb->return_modreq = NULL;
612 rmb->return_modopt = NULL;
613 rmb->param_modreq = NULL;
614 rmb->param_modopt = NULL;
615 rmb->permissions = NULL;
616 rmb->mhandle = mb->mhandle;
617 rmb->nrefs = 0;
618 rmb->refs = NULL;
620 #else /* DISABLE_REFLECTION_EMIT */
621 gboolean
622 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
623 g_assert_not_reached ();
624 return FALSE;
626 gboolean
627 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
629 g_assert_not_reached ();
630 return FALSE;
632 #endif /* DISABLE_REFLECTION_EMIT */
634 #ifndef DISABLE_REFLECTION_EMIT
635 static guint32
636 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
638 MONO_REQ_GC_NEUTRAL_MODE;
640 MonoDynamicTable *table;
641 guint32 *values;
642 guint32 token, pclass;
644 switch (parent & MONO_TYPEDEFORREF_MASK) {
645 case MONO_TYPEDEFORREF_TYPEREF:
646 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
647 break;
648 case MONO_TYPEDEFORREF_TYPESPEC:
649 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
650 break;
651 case MONO_TYPEDEFORREF_TYPEDEF:
652 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
653 break;
654 default:
655 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
656 return 0;
658 /* extract the index */
659 parent >>= MONO_TYPEDEFORREF_BITS;
661 table = &assembly->tables [MONO_TABLE_MEMBERREF];
663 if (assembly->save) {
664 alloc_table (table, table->rows + 1);
665 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
666 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
667 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
668 values [MONO_MEMBERREF_SIGNATURE] = sig;
671 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
672 table->next_idx ++;
674 return token;
678 * Insert a memberef row into the metadata: the token that point to the memberref
679 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
680 * mono_image_get_fieldref_token()).
681 * The sig param is an index to an already built signature.
683 static guint32
684 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
686 MONO_REQ_GC_NEUTRAL_MODE;
688 guint32 parent = mono_image_typedef_or_ref (assembly, type);
689 return mono_image_add_memberef_row (assembly, parent, name, sig);
693 guint32
694 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
696 MONO_REQ_GC_NEUTRAL_MODE;
698 guint32 token;
699 MonoMethodSignature *sig;
701 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
703 if (create_typespec) {
704 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
705 if (token)
706 return token;
709 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
710 if (token && !create_typespec)
711 return token;
713 g_assert (!method->is_inflated);
714 if (!token) {
716 * A methodref signature can't contain an unmanaged calling convention.
718 sig = mono_metadata_signature_dup (mono_method_signature_internal (method));
719 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
720 sig->call_convention = MONO_CALL_DEFAULT;
721 token = mono_image_get_memberref_token (assembly, m_class_get_byval_arg (method->klass),
722 method->name, mono_dynimage_encode_method_signature (assembly, sig));
723 g_free (sig);
724 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
727 if (create_typespec) {
728 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
729 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
730 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
732 if (assembly->save) {
733 guint32 *values;
735 alloc_table (table, table->rows + 1);
736 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
737 values [MONO_METHODSPEC_METHOD] = token;
738 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
741 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
742 table->next_idx ++;
743 /*methodspec and memberef tokens are diferent, */
744 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
745 return token;
747 return token;
750 static guint32
751 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
752 const gchar *name, guint32 sig)
754 MonoDynamicTable *table;
755 guint32 token;
756 guint32 *values;
758 table = &assembly->tables [MONO_TABLE_MEMBERREF];
760 if (assembly->save) {
761 alloc_table (table, table->rows + 1);
762 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
763 values [MONO_MEMBERREF_CLASS] = original;
764 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
765 values [MONO_MEMBERREF_SIGNATURE] = sig;
768 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
769 table->next_idx ++;
771 return token;
774 #else /* DISABLE_REFLECTION_EMIT */
776 guint32
777 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
779 g_assert_not_reached ();
780 return -1;
782 #endif
784 static gboolean
785 is_field_on_inst (MonoClassField *field)
787 return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
790 static gboolean
791 is_field_on_gtd (MonoClassField *field)
793 return mono_class_is_gtd (field->parent);
796 #ifndef DISABLE_REFLECTION_EMIT
797 static guint32
798 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
800 MonoType *type;
801 guint32 token;
803 g_assert (field);
804 g_assert (field->parent);
806 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
807 if (token)
808 return token;
810 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) {
811 int index = field - field->parent->fields;
812 type = mono_field_get_type_internal (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
813 } else {
814 type = mono_field_get_type_internal (field);
816 token = mono_image_get_memberref_token (assembly, m_class_get_byval_arg (field->parent),
817 mono_field_get_name (field),
818 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
819 g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
820 return token;
823 static guint32
824 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
826 MonoDynamicTable *table;
827 guint32 *values;
828 guint32 token, mtoken = 0, sig;
829 MonoMethodInflated *imethod;
830 MonoMethod *declaring;
832 table = &assembly->tables [MONO_TABLE_METHODSPEC];
834 g_assert (method->is_inflated);
835 imethod = (MonoMethodInflated *) method;
836 declaring = imethod->declaring;
838 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature_internal (declaring));
839 mtoken = mono_image_get_memberref_token (assembly, m_class_get_byval_arg (method->klass), declaring->name, sig);
841 if (!mono_method_signature_internal (declaring)->generic_param_count)
842 return mtoken;
844 switch (mono_metadata_token_table (mtoken)) {
845 case MONO_TABLE_MEMBERREF:
846 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
847 break;
848 case MONO_TABLE_METHOD:
849 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
850 break;
851 default:
852 g_assert_not_reached ();
855 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
857 if (assembly->save) {
858 alloc_table (table, table->rows + 1);
859 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
860 values [MONO_METHODSPEC_METHOD] = mtoken;
861 values [MONO_METHODSPEC_SIGNATURE] = sig;
864 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
865 table->next_idx ++;
867 return token;
870 static guint32
871 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
873 MonoMethodInflated *imethod;
874 guint32 token;
876 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
877 if (token)
878 return token;
880 g_assert (method->is_inflated);
881 imethod = (MonoMethodInflated *) method;
883 if (mono_method_signature_internal (imethod->declaring)->generic_param_count) {
884 token = method_encode_methodspec (assembly, method);
885 } else {
886 guint32 sig = mono_dynimage_encode_method_signature (
887 assembly, mono_method_signature_internal (imethod->declaring));
888 token = mono_image_get_memberref_token (
889 assembly, m_class_get_byval_arg (method->klass), method->name, sig);
892 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
893 return token;
896 static guint32
897 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
899 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
900 guint32 sig, token;
902 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature_internal (imethod->declaring));
903 token = mono_image_get_memberref_token (
904 assembly, m_class_get_byval_arg (m->klass), m->name, sig);
906 return token;
909 static guint32
910 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
912 guint32 idx;
913 MonoDynamicTable *table;
914 guint32 *values;
916 error_init (error);
918 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
919 idx = table->next_idx ++;
920 table->rows ++;
921 alloc_table (table, table->rows);
922 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
924 values [MONO_STAND_ALONE_SIGNATURE] =
925 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
926 return_val_if_nok (error, 0);
928 return idx;
931 static int
932 reflection_cc_to_file (int call_conv) {
933 switch (call_conv & 0x3) {
934 case 0:
935 case 1: return MONO_CALL_DEFAULT;
936 case 2: return MONO_CALL_VARARG;
937 default:
938 g_assert_not_reached ();
940 return 0;
942 #endif /* !DISABLE_REFLECTION_EMIT */
944 struct _ArrayMethod {
945 MonoType *parent;
946 MonoMethodSignature *sig;
947 char *name;
948 guint32 token;
951 void
952 mono_sre_array_method_free (ArrayMethod *am)
954 g_free (am->sig);
955 g_free (am->name);
956 g_free (am);
959 #ifndef DISABLE_REFLECTION_EMIT
960 static guint32
961 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethodHandle m, MonoError *error)
963 MonoMethodSignature *sig = NULL;
964 char *name = NULL;
966 error_init (error);
968 MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
969 guint32 nparams = mono_array_handle_length (parameters);
970 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
971 sig->hasthis = 1;
972 sig->sentinelpos = -1;
973 sig->call_convention = reflection_cc_to_file (MONO_HANDLE_GETVAL (m, call_conv));
974 sig->param_count = nparams;
975 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW_GET (MonoReflectionType, m, ret);
976 if (!MONO_HANDLE_IS_NULL (ret)) {
977 sig->ret = mono_reflection_type_handle_mono_type (ret, error);
978 goto_if_nok (error, fail);
979 } else
980 sig->ret = mono_get_void_type ();
982 MonoReflectionTypeHandle parent;
983 parent = MONO_HANDLE_NEW_GET (MonoReflectionType, m, parent);
984 MonoType *mtype;
985 mtype = mono_reflection_type_handle_mono_type (parent, error);
986 goto_if_nok (error, fail);
988 for (int i = 0; i < nparams; ++i) {
989 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
990 goto_if_nok (error, fail);
993 MonoStringHandle mname;
994 mname = MONO_HANDLE_NEW_GET (MonoString, m, name);
995 name = mono_string_handle_to_utf8 (mname, error);
996 goto_if_nok (error, fail);
998 ArrayMethod *am;
999 am = NULL;
1000 for (GList *tmp = assembly->array_methods; tmp; tmp = tmp->next) {
1001 am = (ArrayMethod *)tmp->data;
1002 if (strcmp (name, am->name) == 0 &&
1003 mono_metadata_type_equal (am->parent, mtype) &&
1004 mono_metadata_signature_equal (am->sig, sig)) {
1005 g_free (name);
1006 g_free (sig);
1007 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
1008 return am->token;
1011 am = g_new0 (ArrayMethod, 1);
1012 am->name = name;
1013 am->sig = sig;
1014 am->parent = mtype;
1015 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
1016 mono_dynimage_encode_method_signature (assembly, sig));
1017 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
1018 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
1019 return am->token;
1020 fail:
1021 g_free (name);
1022 g_free (sig);
1023 return 0;
1026 #endif
1028 #ifndef DISABLE_REFLECTION_EMIT
1031 * mono_image_insert_string:
1032 * @module: module builder object
1033 * @str: a string
1035 * Insert @str into the user string stream of @module.
1037 guint32
1038 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStringHandle str, MonoError *error)
1040 HANDLE_FUNCTION_ENTER ();
1041 guint32 idx;
1042 char buf [16];
1043 char *b = buf;
1044 guint32 token = 0;
1046 MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1047 if (!assembly) {
1048 if (!mono_image_module_basic_init (ref_module, error))
1049 goto leave;
1051 assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1053 g_assert (assembly != NULL);
1055 if (assembly->save) {
1056 int32_t length = mono_string_length_internal (MONO_HANDLE_RAW (str));
1057 mono_metadata_encode_value (1 | (length * 2), b, &b);
1058 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1059 /* pinned */
1060 MonoGCHandle gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, str), TRUE);
1061 const char *p = (const char*)mono_string_chars_internal (MONO_HANDLE_RAW (str));
1062 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1064 char *swapped = g_malloc (2 * length);
1066 swap_with_size (swapped, p, 2, length);
1067 mono_image_add_stream_data (&assembly->us, swapped, length * 2);
1068 g_free (swapped);
1070 #else
1071 mono_image_add_stream_data (&assembly->us, p, length * 2);
1072 #endif
1073 mono_gchandle_free_internal (gchandle);
1074 mono_image_add_stream_data (&assembly->us, "", 1);
1075 } else {
1076 idx = assembly->us.index ++;
1079 token = MONO_TOKEN_STRING | idx;
1080 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
1082 leave:
1083 HANDLE_FUNCTION_RETURN_VAL (token);
1086 static guint32
1087 create_method_token (MonoDynamicImage *assembly, MonoMethod *method, MonoArrayHandle opt_param_types, MonoError *error)
1089 guint32 sig_token, parent;
1092 int nargs = mono_array_handle_length (opt_param_types);
1093 MonoMethodSignature *old = mono_method_signature_internal (method);
1094 MonoMethodSignature *sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1096 sig->hasthis = old->hasthis;
1097 sig->explicit_this = old->explicit_this;
1098 sig->call_convention = old->call_convention;
1099 sig->generic_param_count = old->generic_param_count;
1100 sig->param_count = old->param_count + nargs;
1101 sig->sentinelpos = old->param_count;
1102 sig->ret = old->ret;
1104 for (int i = 0; i < old->param_count; i++)
1105 sig->params [i] = old->params [i];
1107 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1108 for (int i = 0; i < nargs; i++) {
1109 MONO_HANDLE_ARRAY_GETREF (rt, opt_param_types, i);
1110 sig->params [old->param_count + i] = mono_reflection_type_handle_mono_type (rt, error);
1111 goto_if_nok (error, fail);
1114 parent = mono_image_typedef_or_ref (assembly, m_class_get_byval_arg (method->klass));
1115 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1116 parent >>= MONO_TYPEDEFORREF_BITS;
1118 parent <<= MONO_MEMBERREF_PARENT_BITS;
1119 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1121 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1122 guint32 token;
1123 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1124 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1125 return token;
1126 fail:
1127 return 0;
1130 guint32
1131 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
1133 guint32 token = 0;
1135 error_init (error);
1137 MonoClass *klass = mono_handle_class (obj);
1138 if (strcmp (klass->name, "RuntimeMethodInfo") == 0 || strcmp (klass->name, "RuntimeConstructorInfo") == 0) {
1139 MonoReflectionMethodHandle ref_method = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1140 MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
1141 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types) && (mono_method_signature_internal (method)->sentinelpos >= 0));
1142 token = create_method_token (assembly, method, opt_param_types, error);
1143 goto_if_nok (error, fail);
1144 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1145 g_assert_not_reached ();
1146 } else {
1147 g_error ("requested method token for %s\n", klass->name);
1150 mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
1151 return token;
1152 fail:
1153 g_assert (!is_ok (error));
1154 return 0;
1158 * mono_image_create_token:
1159 * @assembly: a dynamic assembly
1160 * @obj:
1161 * @register_token: Whenever to register the token in the assembly->tokens hash.
1163 * Get a token to insert in the IL code stream for the given MemberInfo.
1164 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1165 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1166 * entry.
1168 guint32
1169 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
1170 gboolean create_open_instance, gboolean register_token,
1171 MonoError *error)
1173 HANDLE_FUNCTION_ENTER ();
1174 guint32 token = 0;
1176 error_init (error);
1178 MonoClass *klass = mono_handle_class (obj);
1179 MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
1180 MONO_HANDLE_ASSIGN (register_obj, obj);
1182 /* Check for user defined reflection objects */
1183 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1184 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1185 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1186 goto leave;
1189 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1190 int how_collide;
1191 how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
1193 if (strcmp (klass->name, "RuntimeType") == 0) {
1194 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
1195 goto_if_nok (error, leave);
1196 MonoClass *mc = mono_class_from_mono_type_internal (type);
1197 token = mono_metadata_token_from_dor (
1198 mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1199 /* If it's a RuntimeType now, we could have registered a
1200 * TypeBuilder for it before, so replacing is okay. */
1201 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1202 } else if (strcmp (klass->name, "RuntimeMethodInfo") == 0 ||
1203 strcmp (klass->name, "RuntimeConstructorInfo") == 0) {
1204 MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1205 MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
1206 if (method->is_inflated) {
1207 if (create_open_instance) {
1208 guint32 methodspec_token = mono_image_get_methodspec_token (assembly, method);
1209 MonoReflectionMethodHandle canonical_obj =
1210 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
1211 goto_if_nok (error, leave);
1212 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1213 token = methodspec_token;
1214 } else
1215 token = mono_image_get_inflated_method_token (assembly, method);
1216 } else if ((method->klass->image == &assembly->image) &&
1217 !mono_class_is_ginst (method->klass) &&
1218 !mono_class_is_gtd (method->klass)) {
1219 static guint32 method_table_idx = 0xffffff;
1220 if (method->klass->wastypebuilder) {
1221 /* we use the same token as the one that was assigned
1222 * to the Methodbuilder.
1223 * FIXME: do the equivalent for Fields.
1225 token = method->token;
1226 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1227 } else {
1229 * Each token should have a unique index, but the indexes are
1230 * assigned by managed code, so we don't know about them. An
1231 * easy solution is to count backwards...
1233 method_table_idx --;
1234 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1235 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1237 } else {
1238 guint32 methodref_token = mono_image_get_methodref_token (assembly, method, create_open_instance);
1239 /* We need to register a 'canonical' object. The same
1240 * MonoMethod could have been reflected via different
1241 * classes so the MonoReflectionMethod:reftype could be
1242 * different, and the object lookup in
1243 * dynamic_image_register_token would assert assert. So
1244 * we pick the MonoReflectionMethod object that has the
1245 * reflected type as NULL (ie, take the declaring type
1246 * of the method) */
1247 MonoReflectionMethodHandle canonical_obj =
1248 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
1249 goto_if_nok (error, leave);
1250 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1251 token = methodref_token;
1253 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1254 } else if (strcmp (klass->name, "RuntimeFieldInfo") == 0) {
1255 MonoReflectionFieldHandle f = MONO_HANDLE_CAST (MonoReflectionField, obj);
1256 MonoClassField *field = MONO_HANDLE_GETVAL (f, field);
1257 if ((field->parent->image == &assembly->image) &&
1258 !is_field_on_gtd (field) &&
1259 !is_field_on_inst (field)) {
1260 static guint32 field_table_idx = 0xffffff;
1261 field_table_idx --;
1262 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1263 g_assert (!mono_class_is_gtd (field->parent));
1264 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1265 } else {
1266 guint32 fieldref_token = mono_image_get_fieldref_token (assembly, field);
1267 /* Same as methodref: get a canonical object to
1268 * register with the token. */
1269 MonoReflectionFieldHandle canonical_obj =
1270 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj), field->parent, field, error);
1271 goto_if_nok (error, leave);
1272 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1273 token = fieldref_token;
1275 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1276 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1277 MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
1278 /* mono_image_get_array_token caches tokens by signature */
1279 guint32 array_token = mono_image_get_array_token (assembly, m, error);
1280 goto_if_nok (error, leave);
1281 token = array_token;
1282 /* ModuleBuilder:GetArrayMethod() always returns a fresh
1283 * MonoArrayMethod instance even given the same method name and
1284 * signature. But they're all interchangeable, so it's okay to
1285 * replace.
1287 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1288 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1289 MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
1290 /* always returns a fresh token */
1291 guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1292 goto_if_nok (error, leave);
1293 token = sig_token;
1294 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1295 } else {
1296 g_error ("requested token for %s\n", klass->name);
1299 if (register_token)
1300 mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
1302 leave:
1303 HANDLE_FUNCTION_RETURN_VAL (token);
1307 #endif
1309 #ifndef DISABLE_REFLECTION_EMIT
1311 static gboolean
1312 assemblybuilderaccess_can_refonlyload (guint32 access)
1314 return (access & 0x4) != 0;
1317 static gboolean
1318 assemblybuilderaccess_can_run (guint32 access)
1320 return (access & MonoAssemblyBuilderAccess_Run) != 0;
1323 static gboolean
1324 assemblybuilderaccess_can_save (guint32 access)
1326 return (access & MonoAssemblyBuilderAccess_Save) != 0;
1331 * mono_reflection_dynimage_basic_init:
1332 * @assembly: an assembly builder object
1334 * Create the MonoImage that represents the assembly builder and setup some
1335 * of the helper hash table and the basic metadata streams.
1337 void
1338 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb, MonoError *error)
1340 MonoDynamicAssembly *assembly;
1341 MonoDynamicImage *image;
1342 MonoDomain *domain = mono_object_domain (assemblyb);
1343 MonoAssemblyLoadContext *alc = mono_domain_default_alc (domain);
1345 if (assemblyb->dynamic_assembly)
1346 return;
1348 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1350 MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
1352 assembly->assembly.ref_count = 1;
1353 assembly->assembly.dynamic = TRUE;
1354 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1355 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1356 assembly->assembly.basedir = mono_string_to_utf8_checked_internal (assemblyb->dir, error);
1357 return_if_nok (error);
1358 if (assemblyb->culture) {
1359 assembly->assembly.aname.culture = mono_string_to_utf8_checked_internal (assemblyb->culture, error);
1360 return_if_nok (error);
1361 } else
1362 assembly->assembly.aname.culture = g_strdup ("");
1364 if (assemblyb->version) {
1365 char *vstr = mono_string_to_utf8_checked_internal (assemblyb->version, error);
1366 if (mono_error_set_pending_exception (error))
1367 return;
1368 char **version = g_strsplit (vstr, ".", 4);
1369 char **parts = version;
1370 assembly->assembly.aname.major = atoi (*parts++);
1371 assembly->assembly.aname.minor = atoi (*parts++);
1372 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1373 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1375 g_strfreev (version);
1376 g_free (vstr);
1377 } else {
1378 assembly->assembly.aname.major = 0;
1379 assembly->assembly.aname.minor = 0;
1380 assembly->assembly.aname.build = 0;
1381 assembly->assembly.aname.revision = 0;
1384 /* SRE assemblies are loaded into the individual loading context, ie,
1385 * they only fire AssemblyResolve events, they don't cause probing for
1386 * referenced assemblies to happen. */
1387 assembly->assembly.context.kind = assemblybuilderaccess_can_refonlyload (assemblyb->access) ? MONO_ASMCTX_REFONLY : MONO_ASMCTX_INDIVIDUAL;
1388 assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
1389 assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
1390 assembly->domain = domain;
1392 char *assembly_name = mono_string_to_utf8_checked_internal (assemblyb->name, error);
1393 return_if_nok (error);
1394 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1395 image->initial_image = TRUE;
1396 assembly->assembly.aname.name = image->image.name;
1397 assembly->assembly.image = &image->image;
1398 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1399 /* -1 to correct for the trailing NULL byte */
1400 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1401 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1403 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr_internal (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1406 mono_domain_assemblies_lock (domain);
1407 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1408 #ifdef ENABLE_NETCORE
1409 // TODO: potentially relax the locking here?
1410 mono_alc_assemblies_lock (alc);
1411 alc->loaded_assemblies = g_slist_append (alc->loaded_assemblies, assembly);
1412 mono_alc_assemblies_unlock (alc);
1413 #endif
1414 mono_domain_assemblies_unlock (domain);
1416 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1418 MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
1420 mono_assembly_invoke_load_hook_internal (alc, (MonoAssembly*)assembly);
1423 #endif /* !DISABLE_REFLECTION_EMIT */
1425 #ifndef DISABLE_REFLECTION_EMIT
1426 static gpointer
1427 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1429 return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1432 static MonoReflectionModuleBuilderHandle
1433 register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, MonoDynamicImage *module)
1435 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilder, module, MONO_HANDLE_CAST (MonoObject, res), NULL);
1438 static gboolean
1439 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1441 error_init (error);
1442 MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
1443 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
1444 MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
1445 MONO_HANDLE_GET (ab, moduleb, assemblyb);
1446 if (!image) {
1448 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1449 * we don't know which module it belongs to, since that is only
1450 * determined at assembly save time.
1452 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1453 MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name);
1454 char *name = mono_string_handle_to_utf8 (abname, error);
1455 return_val_if_nok (error, FALSE);
1456 MonoStringHandle modfqname = MONO_HANDLE_NEW_GET (MonoString, MONO_HANDLE_CAST (MonoReflectionModule, moduleb), fqname);
1457 char *fqname = mono_string_handle_to_utf8 (modfqname, error);
1458 if (!is_ok (error)) {
1459 g_free (name);
1460 return FALSE;
1462 MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly);
1463 image = mono_dynamic_image_create (dynamic_assembly, name, fqname);
1465 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image);
1466 MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image);
1467 register_module (domain, moduleb, image);
1469 /* register the module with the assembly */
1470 MonoImage *ass = dynamic_assembly->assembly.image;
1471 int module_count = ass->module_count;
1472 MonoImage **new_modules = g_new0 (MonoImage *, module_count + 1);
1474 if (ass->modules)
1475 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1476 new_modules [module_count] = &image->image;
1477 mono_image_addref (&image->image);
1479 g_free (ass->modules);
1480 ass->modules = new_modules;
1481 ass->module_count ++;
1483 return TRUE;
1486 static gboolean
1487 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1489 error_init (error);
1490 return image_module_basic_init (moduleb, error);
1493 #endif
1495 static gboolean
1496 is_corlib_type (MonoClass *klass)
1498 return klass->image == mono_defaults.corlib;
1501 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1502 static MonoClass *cached_class; \
1503 if (cached_class) \
1504 return cached_class == _class; \
1505 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1506 cached_class = _class; \
1507 return TRUE; \
1509 return FALSE; \
1510 } while (0) \
1513 MonoType*
1514 mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
1516 HANDLE_FUNCTION_ENTER();
1517 error_init (error);
1518 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1519 MONO_HANDLE_ARRAY_GETREF (t, array, idx);
1520 MonoType *result = mono_reflection_type_handle_mono_type (t, error);
1521 HANDLE_FUNCTION_RETURN_VAL (result);
1524 static MonoType *
1525 add_custom_modifiers_to_type (MonoType *without_mods, MonoArrayHandle req_array, MonoArrayHandle opt_array, MonoImage *image, MonoError *error)
1527 HANDLE_FUNCTION_ENTER();
1528 error_init (error);
1530 int num_req_mods = 0;
1531 if (!MONO_HANDLE_IS_NULL (req_array))
1532 num_req_mods = mono_array_handle_length (req_array);
1534 int num_opt_mods = 0;
1535 if (!MONO_HANDLE_IS_NULL (opt_array))
1536 num_opt_mods = mono_array_handle_length (opt_array);
1538 const int total_mods = num_req_mods + num_opt_mods;
1539 if (total_mods == 0)
1540 return without_mods;
1542 MonoTypeWithModifiers *result;
1543 result = mono_image_g_malloc0 (image, mono_sizeof_type_with_mods (total_mods, FALSE));
1544 memcpy (result, without_mods, MONO_SIZEOF_TYPE);
1545 result->unmodified.has_cmods = 1;
1546 MonoCustomModContainer *cmods = mono_type_get_cmods ((MonoType *)result);
1547 g_assert (cmods);
1548 cmods->count = total_mods;
1549 cmods->image = image;
1551 g_assert (image_is_dynamic (image));
1552 MonoDynamicImage *allocator = (MonoDynamicImage *) image;
1554 g_assert (total_mods > 0);
1555 /* store cmods in reverse order from how the API supplies them.
1556 (Assemblies store modifiers in reverse order of IL syntax - and SRE
1557 follows the same order as IL syntax). */
1558 int modifier_index = total_mods - 1;
1560 MonoObjectHandle mod_handle = MONO_HANDLE_NEW (MonoObject, NULL);
1561 for (int i=0; i < num_req_mods; i++) {
1562 cmods->modifiers [modifier_index].required = TRUE;
1563 MONO_HANDLE_ARRAY_GETREF (mod_handle, req_array, i);
1564 cmods->modifiers [modifier_index].token = mono_image_create_token (allocator, mod_handle, FALSE, TRUE, error);
1565 modifier_index--;
1568 for (int i=0; i < num_opt_mods; i++) {
1569 cmods->modifiers [modifier_index].required = FALSE;
1570 MONO_HANDLE_ARRAY_GETREF (mod_handle, opt_array, i);
1571 cmods->modifiers [modifier_index].token = mono_image_create_token (allocator, mod_handle, FALSE, TRUE, error);
1572 modifier_index--;
1575 g_assert (modifier_index == -1);
1577 HANDLE_FUNCTION_RETURN_VAL ((MonoType *) result);
1580 static
1581 MonoType *
1582 mono_type_array_get_and_resolve_with_modifiers (MonoArrayHandle types, MonoArrayHandle required_modifiers, MonoArrayHandle optional_modifiers, int idx, MonoImage *image, MonoError *error)
1584 HANDLE_FUNCTION_ENTER();
1585 error_init (error);
1586 MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1587 MonoArrayHandle req_mods_handle = MONO_HANDLE_NEW (MonoArray, NULL);
1588 MonoArrayHandle opt_mods_handle = MONO_HANDLE_NEW (MonoArray, NULL);
1590 if (!MONO_HANDLE_IS_NULL (required_modifiers))
1591 MONO_HANDLE_ARRAY_GETREF (req_mods_handle, required_modifiers, idx);
1593 if (!MONO_HANDLE_IS_NULL (optional_modifiers))
1594 MONO_HANDLE_ARRAY_GETREF (opt_mods_handle, optional_modifiers, idx);
1596 MONO_HANDLE_ARRAY_GETREF (type, types, idx);
1598 MonoType *result = mono_reflection_type_handle_mono_type (type, error);
1599 result = (MonoType *) add_custom_modifiers_to_type (result, req_mods_handle, opt_mods_handle, image, error);
1601 HANDLE_FUNCTION_RETURN_VAL (result);
1605 #ifndef DISABLE_REFLECTION_EMIT
1606 static gboolean
1607 is_sre_array (MonoClass *klass)
1609 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1612 static gboolean
1613 is_sre_byref (MonoClass *klass)
1615 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1618 static gboolean
1619 is_sre_pointer (MonoClass *klass)
1621 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1624 static gboolean
1625 is_sre_generic_instance (MonoClass *klass)
1627 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1630 static gboolean
1631 is_sre_type_builder (MonoClass *klass)
1633 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1636 static gboolean
1637 is_sre_method_builder (MonoClass *klass)
1639 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1642 gboolean
1643 mono_is_sre_ctor_builder (MonoClass *klass)
1645 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1648 static gboolean
1649 is_sre_field_builder (MonoClass *klass)
1651 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1654 static gboolean
1655 is_sre_gparam_builder (MonoClass *klass)
1657 check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1660 static gboolean
1661 is_sre_enum_builder (MonoClass *klass)
1663 check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1666 gboolean
1667 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1669 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1672 gboolean
1673 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1675 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1678 static MonoReflectionTypeHandle
1679 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error)
1681 HANDLE_FUNCTION_ENTER ();
1683 error_init (error);
1685 MONO_STATIC_POINTER_INIT (MonoMethod, method_get_underlying_system_type)
1687 method_get_underlying_system_type = mono_class_get_method_from_name_checked (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0, 0, error);
1688 mono_error_assert_ok (error);
1690 MONO_STATIC_POINTER_INIT_END (MonoMethod, method_get_underlying_system_type)
1692 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1694 MonoMethod *usertype_method = mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject, t), method_get_underlying_system_type, error);
1695 goto_if_nok (error, leave);
1697 MONO_HANDLE_ASSIGN (rt, MONO_HANDLE_CAST (MonoReflectionType, MONO_HANDLE_NEW (MonoObject, mono_runtime_invoke_checked (usertype_method, MONO_HANDLE_RAW (t), NULL, error))));
1699 leave:
1700 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType, rt);
1703 MonoType*
1704 mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
1706 HANDLE_FUNCTION_ENTER ();
1707 error_init (error);
1708 MONO_HANDLE_DCL (MonoReflectionType, ref);
1709 MonoType * const result = mono_reflection_type_handle_mono_type (ref, error);
1710 HANDLE_FUNCTION_RETURN_VAL (result);
1713 static MonoType*
1714 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass, MonoError *error)
1716 HANDLE_FUNCTION_ENTER ();
1717 MonoType *result = NULL;
1718 MonoType **types = NULL;
1720 MonoArrayHandle typeargs = MONO_HANDLE_NEW_GET (MonoArray, ref_gclass, type_arguments);
1721 int count = mono_array_handle_length (typeargs);
1722 types = g_new0 (MonoType*, count);
1723 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1724 for (int i = 0; i < count; ++i) {
1725 MONO_HANDLE_ARRAY_GETREF (t, typeargs, i);
1726 types [i] = mono_reflection_type_handle_mono_type (t, error);
1727 if (!types[i] || !is_ok (error)) {
1728 goto leave;
1731 /* Need to resolve the generic_type in order for it to create its generic context. */
1732 MonoReflectionTypeHandle ref_gtd;
1733 ref_gtd = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_gclass, generic_type);
1734 MonoType *gtd;
1735 gtd = mono_reflection_type_handle_mono_type (ref_gtd, error);
1736 goto_if_nok (error, leave);
1737 MonoClass *gtd_klass;
1738 gtd_klass = mono_class_from_mono_type_internal (gtd);
1739 if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
1740 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
1741 goto_if_nok (error, leave);
1743 g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1744 result = mono_reflection_bind_generic_parameters (ref_gtd, count, types, error);
1745 goto_if_nok (error, leave);
1746 g_assert (result);
1747 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gclass), type, MonoType*, result);
1748 leave:
1749 g_free (types);
1750 HANDLE_FUNCTION_RETURN_VAL (result);
1753 static MonoType*
1754 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
1756 HANDLE_FUNCTION_ENTER ();
1757 error_init (error);
1758 MonoType *result = NULL;
1761 MonoReflectionTypeBuilderHandle ref_tbuilder = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_gparam, tbuilder);
1762 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tbuilder, module);
1763 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1764 MonoImage *image = &dynamic_image->image;
1766 MonoGenericParamFull *param = mono_image_new0 (image, MonoGenericParamFull, 1);
1768 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_gparam, name);
1769 param->info.name = mono_string_to_utf8_image (image, ref_name, error);
1770 mono_error_assert_ok (error);
1771 param->num = MONO_HANDLE_GETVAL (ref_gparam, index);
1773 MonoReflectionMethodBuilderHandle ref_mbuilder = MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder, ref_gparam, mbuilder);
1774 if (!MONO_HANDLE_IS_NULL (ref_mbuilder)) {
1775 MonoGenericContainer *generic_container = MONO_HANDLE_GETVAL (ref_mbuilder, generic_container);
1776 if (!generic_container) {
1777 generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1778 generic_container->is_method = TRUE;
1780 * Cannot set owner.method, since the MonoMethod is not created yet.
1781 * Set the image field instead, so type_in_image () works.
1783 generic_container->is_anonymous = TRUE;
1784 generic_container->owner.image = image;
1785 MONO_HANDLE_SETVAL (ref_mbuilder, generic_container, MonoGenericContainer*, generic_container);
1787 param->owner = generic_container;
1788 } else {
1789 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_tbuilder), error);
1790 goto_if_nok (error, leave);
1791 MonoClass *owner;
1792 owner = mono_class_from_mono_type_internal (type);
1793 g_assert (mono_class_is_gtd (owner));
1794 param->owner = mono_class_get_generic_container (owner);
1797 MonoClass *pklass;
1798 pklass = mono_class_create_generic_parameter ((MonoGenericParam *) param);
1800 result = m_class_get_byval_arg (pklass);
1802 mono_class_set_ref_info (pklass, MONO_HANDLE_CAST (MonoObject, ref_gparam));
1803 mono_image_append_class_to_reflection_info_set (pklass);
1805 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), type, MonoType*, result);
1807 leave:
1808 HANDLE_FUNCTION_RETURN_VAL (result);
1811 static MonoType*
1812 mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
1814 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1815 error_init (error);
1816 MONO_HANDLE_DCL (MonoArray, array);
1817 MonoType * const result = mono_type_array_get_and_resolve (array, idx, error);
1818 HANDLE_FUNCTION_RETURN_VAL (result);
1821 MonoType*
1822 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
1824 HANDLE_FUNCTION_ENTER ();
1825 error_init (error);
1827 MonoType* result = NULL;
1829 g_assert (!MONO_HANDLE_IS_NULL (ref));
1830 if (MONO_HANDLE_IS_NULL (ref))
1831 goto leave;
1832 MonoType *t;
1833 t = MONO_HANDLE_GETVAL (ref, type);
1834 if (t) {
1835 result = t;
1836 goto leave;
1839 if (mono_reflection_is_usertype (ref)) {
1840 MONO_HANDLE_ASSIGN (ref, mono_reflection_type_get_underlying_system_type (ref, error));
1841 if (!is_ok (error) || MONO_HANDLE_IS_NULL (ref) || mono_reflection_is_usertype (ref))
1842 goto leave;
1843 t = MONO_HANDLE_GETVAL (ref, type);
1844 if (t) {
1845 result = t;
1846 goto leave;
1850 MonoClass *klass;
1851 klass = mono_handle_class (ref);
1853 if (is_sre_array (klass)) {
1854 MonoReflectionArrayTypeHandle sre_array = MONO_HANDLE_CAST (MonoReflectionArrayType, ref);
1855 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_array, element_type);
1856 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1857 goto_if_nok (error, leave);
1858 g_assert (base);
1859 gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
1860 MonoClass *eclass = mono_class_from_mono_type_internal (base);
1861 result = mono_image_new0 (eclass->image, MonoType, 1);
1862 if (rank == 0) {
1863 result->type = MONO_TYPE_SZARRAY;
1864 result->data.klass = eclass;
1865 } else {
1866 MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
1867 result->type = MONO_TYPE_ARRAY;
1868 result->data.array = at;
1869 at->eklass = eclass;
1870 at->rank = rank;
1872 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1873 } else if (is_sre_byref (klass)) {
1874 MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1875 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_byref, element_type);
1876 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1877 goto_if_nok (error, leave);
1878 g_assert (base);
1879 result = &mono_class_from_mono_type_internal (base)->this_arg;
1880 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1881 } else if (is_sre_pointer (klass)) {
1882 MonoReflectionDerivedTypeHandle sre_pointer = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1883 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_pointer, element_type);
1884 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1885 goto_if_nok (error, leave);
1886 g_assert (base);
1887 result = m_class_get_byval_arg (mono_class_create_ptr (base));
1888 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1889 } else if (is_sre_generic_instance (klass)) {
1890 result = reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass, ref), error);
1891 } else if (is_sre_gparam_builder (klass)) {
1892 result = reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam, ref), error);
1893 } else if (is_sre_enum_builder (klass)) {
1894 MonoReflectionEnumBuilderHandle ref_ebuilder = MONO_HANDLE_CAST (MonoReflectionEnumBuilder, ref);
1896 MonoReflectionTypeHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionType, MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_ebuilder, tb));
1897 result = mono_reflection_type_handle_mono_type (ref_tb, error);
1898 } else if (is_sre_type_builder (klass)) {
1899 MonoReflectionTypeBuilderHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref);
1901 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1902 reflection_setup_internal_class (ref_tb, error);
1903 mono_error_assert_ok (error);
1904 result = MONO_HANDLE_GETVAL (ref, type);
1905 } else {
1906 g_error ("Cannot handle corlib user type %s", mono_type_full_name (m_class_get_byval_arg (mono_handle_class (ref))));
1908 leave:
1909 HANDLE_FUNCTION_RETURN_VAL (result);
1913 * LOCKING: Assumes the loader lock is held.
1915 static MonoMethodSignature*
1916 parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoArrayHandle required_modifiers, MonoArrayHandle optional_modifiers, MonoError *error) {
1917 MonoMethodSignature *sig;
1918 int count, i;
1920 error_init (error);
1922 count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
1924 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1925 sig->param_count = count;
1926 sig->sentinelpos = -1; /* FIXME */
1927 for (i = 0; i < count; ++i) {
1928 sig->params [i] = mono_type_array_get_and_resolve_with_modifiers (parameters, required_modifiers, optional_modifiers, i, image, error);
1929 if (!is_ok (error)) {
1930 image_g_free (image, sig);
1931 return NULL;
1934 return sig;
1938 * LOCKING: Assumes the loader lock is held.
1940 static MonoMethodSignature*
1941 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
1942 MonoMethodSignature *sig;
1944 error_init (error);
1945 MonoArrayHandle params = MONO_HANDLE_NEW_GET(MonoArray, ctor, parameters);
1946 MonoArrayHandle required_modifiers = MONO_HANDLE_NEW_GET(MonoArray, ctor, param_modreq);
1947 MonoArrayHandle optional_modifiers = MONO_HANDLE_NEW_GET(MonoArray, ctor, param_modopt);
1949 sig = parameters_to_signature (image, params, required_modifiers, optional_modifiers, error);
1950 return_val_if_nok (error, NULL);
1951 sig->hasthis = MONO_HANDLE_GETVAL (ctor, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1952 sig->ret = mono_get_void_type ();
1953 return sig;
1956 static MonoMethodSignature*
1957 ctor_builder_to_signature_raw (MonoImage *image, MonoReflectionCtorBuilder* ctor_raw, MonoError *error) {
1958 HANDLE_FUNCTION_ENTER();
1959 MONO_HANDLE_DCL (MonoReflectionCtorBuilder, ctor);
1960 MonoMethodSignature * const sig = ctor_builder_to_signature (image, ctor, error);
1961 HANDLE_FUNCTION_RETURN_VAL (sig);
1964 * LOCKING: Assumes the loader lock is held.
1966 static MonoMethodSignature*
1967 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error)
1969 MonoMethodSignature *sig;
1971 error_init (error);
1972 MonoArrayHandle params = MONO_HANDLE_NEW_GET(MonoArray, method, parameters);
1973 MonoArrayHandle required_modifiers = MONO_HANDLE_NEW_GET(MonoArray, method, param_modreq);
1974 MonoArrayHandle optional_modifiers = MONO_HANDLE_NEW_GET(MonoArray, method, param_modopt);
1975 MonoArrayHandle ret_req_modifiers = MONO_HANDLE_NEW_GET (MonoArray, method, return_modreq);
1976 MonoArrayHandle ret_opt_modifiers = MONO_HANDLE_NEW_GET (MonoArray, method, return_modopt);
1978 sig = parameters_to_signature (image, params, required_modifiers, optional_modifiers, error);
1979 return_val_if_nok (error, NULL);
1980 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1981 MonoReflectionTypeHandle rtype;
1982 rtype = MONO_HANDLE_CAST (MonoReflectionType, MONO_HANDLE_NEW_GET (MonoObject, method, rtype));
1983 if (!MONO_HANDLE_IS_NULL (rtype)) {
1984 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1985 sig->ret = add_custom_modifiers_to_type (sig->ret, ret_req_modifiers, ret_opt_modifiers, image, error);
1986 if (!is_ok (error)) {
1987 image_g_free (image, sig);
1988 return NULL;
1990 } else {
1991 sig->ret = mono_get_void_type ();
1993 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, method, generic_params);
1994 sig->generic_param_count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
1995 return sig;
1998 static MonoMethodSignature*
1999 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError *error)
2001 HANDLE_FUNCTION_ENTER ();
2002 MonoMethodSignature *sig = NULL;
2004 error_init (error);
2006 sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters),
2007 MONO_HANDLE_CAST (MonoArray, NULL_HANDLE), MONO_HANDLE_CAST (MonoArray, NULL_HANDLE), error);
2008 goto_if_nok (error, leave);
2009 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
2010 MonoReflectionTypeHandle rtype;
2011 rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
2012 if (!MONO_HANDLE_IS_NULL (rtype)) {
2013 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
2014 if (!is_ok (error)) {
2015 g_free (sig);
2016 sig = NULL;
2017 goto leave;
2019 } else {
2020 sig->ret = mono_get_void_type ();
2022 sig->generic_param_count = 0;
2023 leave:
2024 HANDLE_FUNCTION_RETURN_VAL (sig);
2027 static void
2028 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
2030 error_init (error);
2031 MonoClass *klass = mono_object_class (prop);
2032 if (strcmp (klass->name, "PropertyBuilder") == 0) {
2033 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
2034 *name = mono_string_to_utf8_checked_internal (pb->name, error);
2035 return_if_nok (error);
2036 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
2037 } else {
2038 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
2039 *name = g_strdup (p->property->name);
2040 if (p->property->get)
2041 *type = mono_method_signature_internal (p->property->get)->ret;
2042 else
2043 *type = mono_method_signature_internal (p->property->set)->params [mono_method_signature_internal (p->property->set)->param_count - 1];
2047 static void
2048 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
2050 error_init (error);
2051 MonoClass *klass = mono_object_class (field);
2052 if (strcmp (klass->name, "FieldBuilder") == 0) {
2053 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
2054 *name = mono_string_to_utf8_checked_internal (fb->name, error);
2055 return_if_nok (error);
2056 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
2057 } else {
2058 MonoReflectionField *f = (MonoReflectionField *)field;
2059 *name = g_strdup (mono_field_get_name (f->field));
2060 *type = f->field->type;
2064 #else /* DISABLE_REFLECTION_EMIT */
2066 static gboolean
2067 is_sre_type_builder (MonoClass *klass)
2069 return FALSE;
2072 static gboolean
2073 is_sre_generic_instance (MonoClass *klass)
2075 return FALSE;
2078 gboolean
2079 mono_is_sre_ctor_builder (MonoClass *klass)
2081 return FALSE;
2084 gboolean
2085 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2087 return FALSE;
2090 gboolean
2091 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2093 return FALSE;
2096 #endif /* !DISABLE_REFLECTION_EMIT */
2098 gboolean
2099 mono_is_sr_mono_property (MonoClass *klass)
2101 check_corlib_type_cached (klass, "System.Reflection", "RuntimePropertyInfo");
2104 static gboolean
2105 is_sr_mono_method (MonoClass *klass)
2107 check_corlib_type_cached (klass, "System.Reflection", "RuntimeMethodInfo");
2110 gboolean
2111 mono_is_sr_mono_cmethod (MonoClass *klass)
2113 check_corlib_type_cached (klass, "System.Reflection", "RuntimeConstructorInfo");
2116 gboolean
2117 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
2119 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
2122 gboolean
2123 mono_is_sre_type_builder (MonoClass *klass)
2125 return is_sre_type_builder (klass);
2128 gboolean
2129 mono_is_sre_generic_instance (MonoClass *klass)
2131 return is_sre_generic_instance (klass);
2137 * encode_cattr_value:
2138 * Encode a value in a custom attribute stream of bytes.
2139 * The value to encode is either supplied as an object in argument val
2140 * (valuetypes are boxed), or as a pointer to the data in the
2141 * argument argval.
2142 * @type represents the type of the value
2143 * @buffer is the start of the buffer
2144 * @p the current position in the buffer
2145 * @buflen contains the size of the buffer and is used to return the new buffer size
2146 * if this needs to be realloced.
2147 * @retbuffer and @retp return the start and the position of the buffer
2148 * @error set on error.
2150 static void
2151 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, gconstpointer void_argval, MonoError *error)
2153 const char *argval = (const char*)void_argval;
2154 MonoTypeEnum simple_type;
2156 error_init (error);
2157 if ((p-buffer) + 10 >= *buflen) {
2158 char *newbuf;
2159 *buflen *= 2;
2160 newbuf = (char *)g_realloc (buffer, *buflen);
2161 p = newbuf + (p-buffer);
2162 buffer = newbuf;
2164 if (!argval)
2165 argval = (const char*)mono_object_get_data (arg);
2166 simple_type = type->type;
2167 handle_enum:
2168 switch (simple_type) {
2169 case MONO_TYPE_BOOLEAN:
2170 case MONO_TYPE_U1:
2171 case MONO_TYPE_I1:
2172 *p++ = *argval;
2173 break;
2174 case MONO_TYPE_CHAR:
2175 case MONO_TYPE_U2:
2176 case MONO_TYPE_I2:
2177 swap_with_size (p, argval, 2, 1);
2178 p += 2;
2179 break;
2180 case MONO_TYPE_U4:
2181 case MONO_TYPE_I4:
2182 case MONO_TYPE_R4:
2183 swap_with_size (p, argval, 4, 1);
2184 p += 4;
2185 break;
2186 case MONO_TYPE_R8:
2187 swap_with_size (p, argval, 8, 1);
2188 p += 8;
2189 break;
2190 case MONO_TYPE_U8:
2191 case MONO_TYPE_I8:
2192 swap_with_size (p, argval, 8, 1);
2193 p += 8;
2194 break;
2195 case MONO_TYPE_VALUETYPE:
2196 if (type->data.klass->enumtype) {
2197 simple_type = mono_class_enum_basetype_internal (type->data.klass)->type;
2198 goto handle_enum;
2199 } else {
2200 g_warning ("generic valuetype %s not handled in custom attr value decoding", type->data.klass->name);
2202 break;
2203 case MONO_TYPE_STRING: {
2204 char *str;
2205 guint32 slen;
2206 if (!arg) {
2207 MONO_DISABLE_WARNING(4309) // truncation of constant
2208 *p++ = 0xFF;
2209 MONO_RESTORE_WARNING
2210 break;
2212 str = mono_string_to_utf8_checked_internal ((MonoString*)arg, error);
2213 return_if_nok (error);
2214 slen = strlen (str);
2215 if ((p-buffer) + 10 + slen >= *buflen) {
2216 char *newbuf;
2217 *buflen *= 2;
2218 *buflen += slen;
2219 newbuf = (char *)g_realloc (buffer, *buflen);
2220 p = newbuf + (p-buffer);
2221 buffer = newbuf;
2223 mono_metadata_encode_value (slen, p, &p);
2224 memcpy (p, str, slen);
2225 p += slen;
2226 g_free (str);
2227 break;
2229 case MONO_TYPE_CLASS: {
2230 char *str;
2231 guint32 slen;
2232 MonoType *arg_type;
2233 if (!arg) {
2234 MONO_DISABLE_WARNING(4309) // truncation of constant
2235 *p++ = 0xFF;
2236 MONO_RESTORE_WARNING
2237 break;
2239 handle_type:
2240 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2241 return_if_nok (error);
2243 str = type_get_qualified_name (arg_type, NULL);
2244 slen = strlen (str);
2245 if ((p-buffer) + 10 + slen >= *buflen) {
2246 char *newbuf;
2247 *buflen *= 2;
2248 *buflen += slen;
2249 newbuf = (char *)g_realloc (buffer, *buflen);
2250 p = newbuf + (p-buffer);
2251 buffer = newbuf;
2253 mono_metadata_encode_value (slen, p, &p);
2254 memcpy (p, str, slen);
2255 p += slen;
2256 g_free (str);
2257 break;
2259 case MONO_TYPE_SZARRAY: {
2260 int len, i;
2261 MonoClass *eclass, *arg_eclass;
2263 if (!arg) {
2264 MONO_DISABLE_WARNING(4309) // truncation of constant
2265 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2266 MONO_RESTORE_WARNING
2267 break;
2269 len = mono_array_length_internal ((MonoArray*)arg);
2270 *p++ = len & 0xff;
2271 *p++ = (len >> 8) & 0xff;
2272 *p++ = (len >> 16) & 0xff;
2273 *p++ = (len >> 24) & 0xff;
2274 *retp = p;
2275 *retbuffer = buffer;
2276 eclass = type->data.klass;
2277 arg_eclass = mono_object_class (arg)->element_class;
2279 if (!eclass) {
2280 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2281 eclass = mono_defaults.object_class;
2283 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2284 char *elptr = mono_array_addr_internal ((MonoArray*)arg, char, 0);
2285 int elsize = mono_class_array_element_size (arg_eclass);
2286 for (i = 0; i < len; ++i) {
2287 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, m_class_get_byval_arg (arg_eclass), NULL, elptr, error);
2288 return_if_nok (error);
2289 elptr += elsize;
2291 } else if (eclass->valuetype && arg_eclass->valuetype) {
2292 char *elptr = mono_array_addr_internal ((MonoArray*)arg, char, 0);
2293 int elsize = mono_class_array_element_size (eclass);
2294 for (i = 0; i < len; ++i) {
2295 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, m_class_get_byval_arg (eclass), NULL, elptr, error);
2296 return_if_nok (error);
2297 elptr += elsize;
2299 } else {
2300 for (i = 0; i < len; ++i) {
2301 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, m_class_get_byval_arg (eclass), mono_array_get_internal ((MonoArray*)arg, MonoObject*, i), NULL, error);
2302 return_if_nok (error);
2305 break;
2307 case MONO_TYPE_OBJECT: {
2308 MonoClass *klass;
2309 char *str;
2310 guint32 slen;
2313 * The parameter type is 'object' but the type of the actual
2314 * argument is not. So we have to add type information to the blob
2315 * too. This is completely undocumented in the spec.
2318 if (arg == NULL) {
2319 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2320 MONO_DISABLE_WARNING(4309) // truncation of constant
2321 *p++ = 0xFF;
2322 MONO_RESTORE_WARNING
2323 break;
2326 klass = mono_object_class (arg);
2328 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2329 *p++ = 0x50;
2330 goto handle_type;
2331 } else {
2332 return_if_nok (error);
2335 MonoType *klass_byval_arg = m_class_get_byval_arg (klass);
2336 if (klass->enumtype) {
2337 *p++ = 0x55;
2338 } else if (klass == mono_defaults.string_class) {
2339 simple_type = MONO_TYPE_STRING;
2340 *p++ = 0x0E;
2341 goto handle_enum;
2342 } else if (klass->rank == 1) {
2343 *p++ = 0x1D;
2344 if (m_class_get_byval_arg (m_class_get_element_class (klass))->type == MONO_TYPE_OBJECT)
2345 /* See Partition II, Appendix B3 */
2346 *p++ = 0x51;
2347 else
2348 *p++ = m_class_get_byval_arg (m_class_get_element_class (klass))->type;
2349 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, klass_byval_arg, arg, NULL, error);
2350 return_if_nok (error);
2351 break;
2352 } else if (klass_byval_arg->type >= MONO_TYPE_BOOLEAN && klass_byval_arg->type <= MONO_TYPE_R8) {
2353 *p++ = simple_type = klass_byval_arg->type;
2354 goto handle_enum;
2355 } else {
2356 mono_error_set_not_supported (error, "unhandled type in custom attr");
2357 break;
2359 str = type_get_qualified_name (m_class_get_byval_arg (klass), NULL);
2360 slen = strlen (str);
2361 if ((p-buffer) + 10 + slen >= *buflen) {
2362 char *newbuf;
2363 *buflen *= 2;
2364 *buflen += slen;
2365 newbuf = (char *)g_realloc (buffer, *buflen);
2366 p = newbuf + (p-buffer);
2367 buffer = newbuf;
2369 mono_metadata_encode_value (slen, p, &p);
2370 memcpy (p, str, slen);
2371 p += slen;
2372 g_free (str);
2373 simple_type = mono_class_enum_basetype_internal (klass)->type;
2374 goto handle_enum;
2376 default:
2377 mono_error_set_not_supported (error, "type 0x%02x not yet supported in custom attr encoder", simple_type);
2379 *retp = p;
2380 *retbuffer = buffer;
2383 static void
2384 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2386 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2387 char *str = type_get_qualified_name (type, NULL);
2388 int slen = strlen (str);
2390 *p++ = 0x55;
2392 * This seems to be optional...
2393 * *p++ = 0x80;
2395 mono_metadata_encode_value (slen, p, &p);
2396 memcpy (p, str, slen);
2397 p += slen;
2398 g_free (str);
2399 } else if (type->type == MONO_TYPE_OBJECT) {
2400 *p++ = 0x51;
2401 } else if (type->type == MONO_TYPE_CLASS) {
2402 /* it should be a type: encode_cattr_value () has the check */
2403 *p++ = 0x50;
2404 } else {
2405 mono_metadata_encode_value (type->type, p, &p);
2406 if (type->type == MONO_TYPE_SZARRAY)
2407 /* See the examples in Partition VI, Annex B */
2408 encode_field_or_prop_type (m_class_get_byval_arg (type->data.klass), p, &p);
2411 *retp = p;
2414 #ifndef DISABLE_REFLECTION_EMIT
2415 static void
2416 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2418 int len;
2420 error_init (error);
2422 /* Preallocate a large enough buffer */
2423 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2424 char *str = type_get_qualified_name (type, NULL);
2425 len = strlen (str);
2426 g_free (str);
2427 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2428 char *str = type_get_qualified_name (m_class_get_byval_arg (type->data.klass), NULL);
2429 len = strlen (str);
2430 g_free (str);
2431 } else {
2432 len = 0;
2434 len += strlen (name);
2436 if ((p-buffer) + 20 + len >= *buflen) {
2437 char *newbuf;
2438 *buflen *= 2;
2439 *buflen += len;
2440 newbuf = (char *)g_realloc (buffer, *buflen);
2441 p = newbuf + (p-buffer);
2442 buffer = newbuf;
2445 encode_field_or_prop_type (type, p, &p);
2447 len = strlen (name);
2448 mono_metadata_encode_value (len, p, &p);
2449 memcpy (p, name, len);
2450 p += len;
2451 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2452 return_if_nok (error);
2453 *retp = p;
2454 *retbuffer = buffer;
2458 * mono_reflection_get_custom_attrs_blob:
2459 * \param ctor custom attribute constructor
2460 * \param ctorArgs arguments o the constructor
2461 * \param properties
2462 * \param propValues
2463 * \param fields
2464 * \param fieldValues
2465 * Creates the blob of data that needs to be saved in the metadata and that represents
2466 * the custom attributed described by \p ctor, \p ctorArgs etc.
2467 * \returns a \c Byte array representing the blob of data.
2469 MonoArray*
2470 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2472 HANDLE_FUNCTION_ENTER ();
2474 MonoArrayHandle result;
2476 MONO_ENTER_GC_UNSAFE;
2478 ERROR_DECL (error);
2480 MONO_HANDLE_NEW (MonoReflectionAssembly, assembly);
2481 MONO_HANDLE_NEW (MonoObject, ctor);
2482 MONO_HANDLE_NEW (MonoArray, ctorArgs);
2483 MONO_HANDLE_NEW (MonoArray, properties);
2484 MONO_HANDLE_NEW (MonoArray, propValues);
2485 MONO_HANDLE_NEW (MonoArray, fields);
2486 MONO_HANDLE_NEW (MonoArray, fieldValues);
2488 result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, error);
2490 mono_error_cleanup (error);
2492 MONO_EXIT_GC_UNSAFE;
2494 HANDLE_FUNCTION_RETURN_OBJ (result);
2498 * mono_reflection_get_custom_attrs_blob_checked:
2499 * \param ctor custom attribute constructor
2500 * \param ctorArgs arguments o the constructor
2501 * \param properties
2502 * \param propValues
2503 * \param fields
2504 * \param fieldValues
2505 * \param error set on error
2506 * Creates the blob of data that needs to be saved in the metadata and that represents
2507 * the custom attributed described by \p ctor, \p ctorArgs etc.
2508 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2510 MonoArrayHandle
2511 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2513 MonoArrayHandle result = NULL_HANDLE_INIT;
2514 MonoMethodSignature *sig;
2515 MonoMethodSignature *sig_free = NULL;
2516 MonoObject *arg;
2517 char *buffer = NULL;
2518 char *p;
2519 guint32 buflen, i;
2520 MonoObjectHandle h1 = NULL_HANDLE_INIT;
2521 MonoObjectHandle h2 = NULL_HANDLE_INIT;
2522 MonoObjectHandle argh = NULL_HANDLE_INIT;
2524 HANDLE_FUNCTION_ENTER ();
2526 if (strcmp (ctor->vtable->klass->name, "RuntimeConstructorInfo")) {
2527 /* sig is freed later so allocate it in the heap */
2528 sig = ctor_builder_to_signature_raw (NULL, (MonoReflectionCtorBuilder*)ctor, error); /* FIXME use handles */
2529 sig_free = sig;
2530 goto_if_nok (error, leave);
2531 } else {
2532 sig = mono_method_signature_internal (((MonoReflectionMethod*)ctor)->method);
2535 g_assert (mono_array_length_internal (ctorArgs) == sig->param_count);
2536 buflen = 256;
2537 p = buffer = (char *)g_malloc (buflen);
2538 /* write the prolog */
2539 *p++ = 1;
2540 *p++ = 0;
2542 argh = MONO_HANDLE_NEW (MonoObject, NULL);
2544 for (i = 0; i < sig->param_count; ++i) {
2545 arg = mono_array_get_internal (ctorArgs, MonoObject*, i);
2546 MONO_HANDLE_ASSIGN_RAW (argh, arg);
2547 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2548 goto_if_nok (error, leave);
2550 i = 0;
2551 if (properties)
2552 i += mono_array_length_internal (properties);
2553 if (fields)
2554 i += mono_array_length_internal (fields);
2555 *p++ = i & 0xff;
2556 *p++ = (i >> 8) & 0xff;
2558 if (properties || fields) {
2559 h1 = MONO_HANDLE_NEW (MonoObject, NULL);
2560 h2 = MONO_HANDLE_NEW (MonoObject, NULL);
2563 if (properties) {
2565 MonoObject *prop;
2567 for (i = 0; i < mono_array_length_internal (properties); ++i) {
2568 MonoType *ptype;
2569 char *pname;
2571 prop = (MonoObject *)mono_array_get_internal (properties, gpointer, i);
2572 MONO_HANDLE_ASSIGN_RAW (h1, prop);
2574 get_prop_name_and_type (prop, &pname, &ptype, error);
2575 goto_if_nok (error, leave);
2576 *p++ = 0x54; /* PROPERTY signature */
2578 prop = (MonoObject*)mono_array_get_internal (propValues, gpointer, i);
2579 MONO_HANDLE_ASSIGN_RAW (h2, prop);
2581 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, prop, error);
2582 g_free (pname);
2583 goto_if_nok (error, leave);
2587 if (fields) {
2589 MonoObject *field;
2591 for (i = 0; i < mono_array_length_internal (fields); ++i) {
2592 MonoType *ftype;
2593 char *fname;
2595 field = (MonoObject *)mono_array_get_internal (fields, gpointer, i);
2596 MONO_HANDLE_ASSIGN_RAW (h1, field);
2598 get_field_name_and_type (field, &fname, &ftype, error);
2599 goto_if_nok (error, leave);
2600 *p++ = 0x53; /* FIELD signature */
2602 field = (MonoObject*)mono_array_get_internal (fieldValues, gpointer, i);
2603 MONO_HANDLE_ASSIGN_RAW (h2, field);
2605 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, field, error);
2606 g_free (fname);
2607 goto_if_nok (error, leave);
2611 g_assert (p - buffer <= buflen);
2612 buflen = p - buffer;
2613 result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2614 goto_if_nok (error, leave);
2615 p = mono_array_addr_internal (MONO_HANDLE_RAW (result), char, 0);
2616 memcpy (p, buffer, buflen);
2617 leave:
2618 g_free (buffer);
2619 g_free (sig_free);
2621 HANDLE_FUNCTION_RETURN_REF (MonoArray, result);
2624 static gboolean
2625 reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
2627 error_init (error);
2629 mono_loader_lock ();
2631 MonoType *parent_type;
2632 MonoType *child_type;
2633 GHashTableIter iter;
2635 g_hash_table_iter_init (&iter, unparented);
2637 while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
2638 MonoClass *child_class = mono_class_from_mono_type_internal (child_type);
2639 if (parent_type != NULL) {
2640 MonoClass *parent_class = mono_class_from_mono_type_internal (parent_type);
2641 child_class->parent = NULL;
2642 /* fool mono_class_setup_parent */
2643 child_class->supertypes = NULL;
2644 mono_class_setup_parent (child_class, parent_class);
2645 } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
2646 const char *old_n = child_class->name;
2647 /* trick to get relative numbering right when compiling corlib */
2648 child_class->name = "BuildingObject";
2649 mono_class_setup_parent (child_class, mono_defaults.object_class);
2650 child_class->name = old_n;
2652 mono_class_setup_mono_type (child_class);
2653 mono_class_setup_supertypes (child_class);
2656 mono_loader_unlock ();
2657 return is_ok (error);
2660 static gboolean
2661 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2663 HANDLE_FUNCTION_ENTER ();
2664 error_init (error);
2666 mono_loader_lock ();
2668 gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
2669 if (entering_state != MonoTypeBuilderNew) {
2670 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
2671 goto leave;
2674 MONO_HANDLE_SETVAL (ref_tb, state, gint32/*MonoTypeBuilderState*/, MonoTypeBuilderEntered);
2675 MonoReflectionModuleBuilderHandle module_ref;
2676 module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2677 GHashTable *unparented_classes;
2678 unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
2680 // If this type is already setup, exit. We'll fix the parenting later
2681 MonoType *type;
2682 type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2683 if (type)
2684 goto leave;
2686 MonoReflectionModuleBuilderHandle ref_module;
2687 ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2688 MonoDynamicImage *dynamic_image;
2689 dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
2691 MonoStringHandle ref_name;
2692 ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_tb, name);
2693 MonoStringHandle ref_nspace;
2694 ref_nspace = MONO_HANDLE_NEW_GET (MonoString, ref_tb, nspace);
2696 guint32 table_idx;
2697 table_idx = MONO_HANDLE_GETVAL (ref_tb, table_idx);
2699 * The size calculation here warrants some explaining.
2700 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2701 * meaning we need to alloc enough space to morth a def into a gtd.
2703 MonoClass *klass;
2704 klass = (MonoClass *)mono_image_alloc0 (&dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2705 klass->class_kind = MONO_CLASS_DEF;
2707 klass->image = &dynamic_image->image;
2709 klass->inited = 1; /* we lie to the runtime */
2710 klass->name = mono_string_to_utf8_image (klass->image, ref_name, error);
2711 goto_if_nok (error, leave);
2712 klass->name_space = mono_string_to_utf8_image (klass->image, ref_nspace, error);
2713 goto_if_nok (error, leave);
2714 klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
2715 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
2717 MONO_PROFILER_RAISE (class_loading, (klass));
2719 klass->element_class = klass;
2721 g_assert (!mono_class_has_ref_info (klass));
2722 mono_class_set_ref_info (klass, MONO_HANDLE_CAST (MonoObject, ref_tb));
2724 MonoReflectionTypeHandle ref_nesting_type;
2725 ref_nesting_type = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, nesting_type);
2726 /* Put into cache so mono_class_get_checked () will find it.
2727 Skip nested types as those should not be available on the global scope. */
2728 if (MONO_HANDLE_IS_NULL (ref_nesting_type))
2729 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, table_idx);
2732 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2733 by performing a mono_class_get which does the full resolution.
2735 Working around this semantics would require us to write a lot of code for no clear advantage.
2737 mono_image_append_class_to_reflection_info_set (klass);
2739 mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
2741 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2742 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2743 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2744 klass->instance_size = MONO_ABI_SIZEOF (MonoObject);
2745 klass->size_inited = 1;
2746 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2749 mono_class_setup_mono_type (klass);
2752 * FIXME: handle interfaces.
2754 MonoReflectionTypeHandle ref_tb_type;
2755 ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
2756 MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, m_class_get_byval_arg (klass));
2757 MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
2759 reflection_init_generic_class (ref_tb, error);
2760 goto_if_nok (error, leave);
2762 // Do here so that the search inside of the parent can see the above type that's been set.
2763 MonoReflectionTypeHandle ref_parent;
2764 ref_parent = MONO_HANDLE_CAST (MonoReflectionType, MONO_HANDLE_NEW_GET (MonoObject, ref_tb, parent));
2765 MonoType *parent_type;
2766 parent_type = NULL;
2767 if (!MONO_HANDLE_IS_NULL (ref_parent)) {
2768 MonoClass *parent_klass = mono_handle_class (ref_parent);
2769 gboolean recursive_init = TRUE;
2771 if (is_sre_type_builder (parent_klass)) {
2772 MonoTypeBuilderState parent_state = (MonoTypeBuilderState)MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
2774 if (parent_state != MonoTypeBuilderNew) {
2775 // Initialize types reachable from parent recursively
2776 // We'll fix the type hierarchy later
2777 recursive_init = FALSE;
2781 if (recursive_init) {
2782 // If we haven't encountered a cycle, force the creation of ref_parent's type
2783 mono_reflection_type_handle_mono_type (ref_parent, error);
2784 goto_if_nok (error, leave);
2787 parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
2789 // If we failed to create the parent, fail the child
2790 if (!parent_type)
2791 goto leave;
2794 // Push the child type and parent type to process later
2795 // Note: parent_type may be null.
2796 g_assert (!g_hash_table_lookup (unparented_classes, m_class_get_byval_arg (klass)));
2797 g_hash_table_insert (unparented_classes, m_class_get_byval_arg (klass), parent_type);
2799 if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
2800 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
2801 goto leave;
2803 MonoType *nesting_type = mono_reflection_type_handle_mono_type (ref_nesting_type, error);
2804 goto_if_nok (error, leave);
2805 klass->nested_in = mono_class_from_mono_type_internal (nesting_type);
2808 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2810 MONO_PROFILER_RAISE (class_loaded, (klass));
2812 leave:
2813 mono_loader_unlock ();
2814 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2818 * reflection_init_generic_class:
2819 * @tb: a TypeBuilder object
2820 * @error: set on error
2822 * Creates the generic class after all generic parameters have been added.
2823 * On success returns TRUE, on failure returns FALSE and sets @error.
2825 * This assumes that reflection_setup_internal_class has already set up
2826 * ref_tb
2828 static gboolean
2829 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2831 HANDLE_FUNCTION_ENTER ();
2833 error_init (error);
2835 MonoTypeBuilderState ref_state = (MonoTypeBuilderState)MONO_HANDLE_GETVAL (ref_tb, state);
2836 g_assert (ref_state == MonoTypeBuilderFinished);
2838 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2839 MonoClass *klass = mono_class_from_mono_type_internal (type);
2841 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
2842 int count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
2844 if (count == 0)
2845 goto leave;
2847 if (mono_class_try_get_generic_container (klass) != NULL)
2848 goto leave; /* already setup */
2850 MonoGenericContainer *generic_container;
2851 generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2853 generic_container->owner.klass = klass;
2854 generic_container->type_argc = count;
2855 generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2857 klass->class_kind = MONO_CLASS_GTD;
2858 mono_class_set_generic_container (klass, generic_container);
2861 MonoReflectionGenericParamHandle ref_gparam;
2862 ref_gparam = MONO_HANDLE_NEW (MonoReflectionGenericParam, NULL);
2863 for (int i = 0; i < count; i++) {
2864 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
2865 MonoType *param_type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), error);
2866 goto_if_nok (error, leave);
2867 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2868 generic_container->type_params [i] = *param;
2869 /*Make sure we are a diferent type instance */
2870 generic_container->type_params [i].owner = generic_container;
2871 generic_container->type_params [i].info.pklass = NULL;
2872 generic_container->type_params [i].info.flags = MONO_HANDLE_GETVAL (ref_gparam, attrs);
2874 g_assert (generic_container->type_params [i].owner);
2877 generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2878 MonoGenericContext* context;
2879 context = &generic_container->context;
2880 MonoType *canonical_inst;
2881 canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
2882 canonical_inst->type = MONO_TYPE_GENERICINST;
2883 canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
2885 leave:
2886 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2889 static MonoMarshalSpec*
2890 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2891 MonoReflectionMarshal *minfo, MonoError *error)
2893 MonoMarshalSpec *res;
2895 error_init (error);
2897 res = image_g_new0 (image, MonoMarshalSpec, 1);
2898 res->native = (MonoMarshalNative)minfo->type;
2900 switch (minfo->type) {
2901 case MONO_NATIVE_LPARRAY:
2902 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2903 if (minfo->has_size) {
2904 res->data.array_data.param_num = minfo->param_num;
2905 res->data.array_data.num_elem = minfo->count;
2906 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2908 else {
2909 res->data.array_data.param_num = -1;
2910 res->data.array_data.num_elem = -1;
2911 res->data.array_data.elem_mult = -1;
2913 break;
2915 case MONO_NATIVE_BYVALTSTR:
2916 case MONO_NATIVE_BYVALARRAY:
2917 res->data.array_data.num_elem = minfo->count;
2918 break;
2920 case MONO_NATIVE_CUSTOM:
2921 if (minfo->marshaltyperef) {
2922 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2923 if (!is_ok (error)) {
2924 image_g_free (image, res);
2925 return NULL;
2927 res->data.custom_data.custom_name =
2928 type_get_fully_qualified_name (marshaltyperef);
2930 if (minfo->mcookie) {
2931 res->data.custom_data.cookie = mono_string_to_utf8_checked_internal (minfo->mcookie, error);
2932 if (!is_ok (error)) {
2933 image_g_free (image, res);
2934 return NULL;
2937 break;
2939 default:
2940 break;
2943 return res;
2945 #endif /* !DISABLE_REFLECTION_EMIT */
2947 MonoReflectionMarshalAsAttributeHandle
2948 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2949 MonoMarshalSpec *spec, MonoError *error)
2951 error_init (error);
2953 MonoAssemblyLoadContext *alc = mono_domain_ambient_alc (domain);
2954 MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, mono_object_new_handle (domain, mono_class_get_marshal_as_attribute_class (), error));
2955 goto_if_nok (error, fail);
2956 guint32 utype;
2957 utype = spec->native;
2958 MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2960 switch (utype) {
2961 case MONO_NATIVE_LPARRAY:
2962 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2963 if (spec->data.array_data.num_elem != -1)
2964 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2965 if (spec->data.array_data.param_num != -1)
2966 MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2967 break;
2969 case MONO_NATIVE_BYVALTSTR:
2970 case MONO_NATIVE_BYVALARRAY:
2971 if (spec->data.array_data.num_elem != -1)
2972 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2973 break;
2975 case MONO_NATIVE_CUSTOM:
2976 if (spec->data.custom_data.custom_name) {
2977 MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, alc, klass->image, error);
2978 goto_if_nok (error, fail);
2980 if (mtype) {
2981 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2982 goto_if_nok (error, fail);
2984 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2987 MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2988 goto_if_nok (error, fail);
2989 MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2991 if (spec->data.custom_data.cookie) {
2992 MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2993 goto_if_nok (error, fail);
2994 MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2996 break;
2998 default:
2999 break;
3002 return minfo;
3003 fail:
3004 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
3007 #ifndef DISABLE_REFLECTION_EMIT
3008 static MonoMethod*
3009 reflection_methodbuilder_to_mono_method (MonoClass *klass,
3010 ReflectionMethodBuilder *rmb,
3011 MonoMethodSignature *sig,
3012 MonoError *error)
3014 MonoMethod *m;
3015 MonoMethodWrapper *wrapperm;
3016 MonoMarshalSpec **specs = NULL;
3017 MonoReflectionMethodAux *method_aux;
3018 MonoImage *image;
3019 gboolean dynamic;
3020 int i;
3022 error_init (error);
3024 * Methods created using a MethodBuilder should have their memory allocated
3025 * inside the image mempool, while dynamic methods should have their memory
3026 * malloc'd.
3028 dynamic = rmb->refs != NULL;
3029 image = dynamic ? NULL : klass->image;
3031 if (!dynamic)
3032 g_assert (!mono_class_is_ginst (klass));
3034 mono_loader_lock ();
3036 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
3037 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
3038 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
3039 else
3040 m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
3042 wrapperm = (MonoMethodWrapper*)m;
3044 m->dynamic = dynamic;
3045 m->slot = -1;
3046 m->flags = rmb->attrs;
3047 m->iflags = rmb->iattrs;
3048 m->name = string_to_utf8_image_raw (image, rmb->name, error);
3049 goto_if_nok (error, fail);
3050 m->klass = klass;
3051 m->signature = sig;
3052 m->sre_method = TRUE;
3053 m->skip_visibility = rmb->skip_visibility;
3054 if (rmb->table_idx)
3055 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
3057 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
3058 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
3059 m->string_ctor = 1;
3061 m->signature->pinvoke = 1;
3062 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3063 m->signature->pinvoke = 1;
3065 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3067 method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
3068 mono_error_assert_ok (error);
3069 method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
3070 mono_error_assert_ok (error);
3072 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
3074 if (image_is_dynamic (klass->image))
3075 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3077 goto leave;
3079 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
3080 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
3081 MonoMethodHeader *header;
3082 guint32 code_size;
3083 gint32 max_stack, i;
3084 gint32 num_locals = 0;
3085 gint32 num_clauses = 0;
3086 guint8 *code;
3088 if (rmb->ilgen) {
3089 code = mono_array_addr_internal (rmb->ilgen->code, guint8, 0);
3090 code_size = rmb->ilgen->code_len;
3091 max_stack = rmb->ilgen->max_stack;
3092 num_locals = rmb->ilgen->locals ? mono_array_length_internal (rmb->ilgen->locals) : 0;
3093 if (rmb->ilgen->ex_handlers)
3094 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
3095 } else {
3096 if (rmb->code) {
3097 code = mono_array_addr_internal (rmb->code, guint8, 0);
3098 code_size = mono_array_length_internal (rmb->code);
3099 /* we probably need to run a verifier on the code... */
3100 max_stack = 8;
3102 else {
3103 code = NULL;
3104 code_size = 0;
3105 max_stack = 8;
3109 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
3110 header->code_size = code_size;
3111 header->code = (const unsigned char *)image_g_malloc (image, code_size);
3112 memcpy ((char*)header->code, code, code_size);
3113 header->max_stack = max_stack;
3114 header->init_locals = rmb->init_locals;
3115 header->num_locals = num_locals;
3117 for (i = 0; i < num_locals; ++i) {
3118 MonoReflectionLocalBuilder *lb =
3119 mono_array_get_internal (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
3121 header->locals [i] = image_g_new0 (image, MonoType, 1);
3122 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
3123 mono_error_assert_ok (error);
3124 memcpy (header->locals [i], type, mono_sizeof_type (type));
3127 header->num_clauses = num_clauses;
3128 if (num_clauses) {
3129 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
3130 rmb->ilgen, num_clauses, error);
3131 mono_error_assert_ok (error);
3134 wrapperm->header = header;
3135 MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
3136 dm->assembly = klass->image->assembly;
3139 if (rmb->generic_params) {
3140 int count = mono_array_length_internal (rmb->generic_params);
3141 MonoGenericContainer *container;
3143 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3144 container->is_method = TRUE;
3145 container->is_anonymous = FALSE;
3146 container->type_argc = count;
3147 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
3148 container->owner.method = m;
3150 m->is_generic = TRUE;
3151 mono_method_set_generic_container (m, container);
3153 for (i = 0; i < count; i++) {
3154 MonoReflectionGenericParam *gp =
3155 mono_array_get_internal (rmb->generic_params, MonoReflectionGenericParam*, i);
3156 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
3157 mono_error_assert_ok (error);
3158 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
3159 container->type_params [i] = *param;
3160 container->type_params [i].owner = container;
3162 gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
3164 MonoClass *gklass = mono_class_from_mono_type_internal (gp_type);
3165 gklass->wastypebuilder = TRUE;
3169 * The method signature might have pointers to generic parameters that belong to other methods.
3170 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3171 * generic parameters.
3173 for (i = 0; i < m->signature->param_count; ++i) {
3174 MonoType *t = m->signature->params [i];
3175 if (t->type == MONO_TYPE_MVAR) {
3176 MonoGenericParam *gparam = t->data.generic_param;
3177 if (gparam->num < count) {
3178 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
3179 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
3185 if (mono_class_is_gtd (klass)) {
3186 container->parent = mono_class_get_generic_container (klass);
3187 container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
3189 container->context.method_inst = mono_get_shared_generic_inst (container);
3192 if (rmb->refs) {
3193 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
3194 int i;
3195 void **data;
3197 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
3199 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
3200 data [0] = GUINT_TO_POINTER (rmb->nrefs);
3201 for (i = 0; i < rmb->nrefs; ++i)
3202 data [i + 1] = rmb->refs [i];
3205 method_aux = NULL;
3207 /* Parameter info */
3208 if (rmb->pinfo) {
3209 if (!method_aux)
3210 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3211 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature_internal (m)->param_count + 1);
3212 for (i = 0; i <= m->signature->param_count; ++i) {
3213 MonoReflectionParamBuilder *pb;
3214 if ((pb = mono_array_get_internal (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3215 if ((i > 0) && (pb->attrs)) {
3216 /* Make a copy since it might point to a shared type structure */
3217 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
3218 m->signature->params [i - 1]->attrs = pb->attrs;
3221 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3222 MonoDynamicImage *assembly;
3223 guint32 idx, len;
3224 MonoTypeEnum def_type;
3225 char *p;
3226 const char *p2;
3228 if (!method_aux->param_defaults) {
3229 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3230 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3232 assembly = (MonoDynamicImage*)klass->image;
3233 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3234 /* Copy the data from the blob since it might get realloc-ed */
3235 p = assembly->blob.data + idx;
3236 len = mono_metadata_decode_blob_size (p, &p2);
3237 len += p2 - p;
3238 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3239 method_aux->param_default_types [i] = def_type;
3240 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3243 if (pb->name) {
3244 method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
3245 mono_error_assert_ok (error);
3247 if (pb->cattrs) {
3248 if (!method_aux->param_cattr)
3249 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3250 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3256 /* Parameter marshalling */
3257 if (rmb->pinfo)
3258 for (i = 0; i < mono_array_length_internal (rmb->pinfo); ++i) {
3259 MonoReflectionParamBuilder *pb;
3260 if ((pb = mono_array_get_internal (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3261 if (pb->marshal_info) {
3262 if (specs == NULL)
3263 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3264 specs [pb->position] =
3265 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3266 goto_if_nok (error, fail);
3270 if (specs != NULL) {
3271 if (!method_aux)
3272 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3273 method_aux->param_marshall = specs;
3276 if (image_is_dynamic (klass->image) && method_aux)
3277 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3279 leave:
3280 mono_loader_unlock ();
3281 if (!m) // FIXME: This leaks if image is not NULL.
3282 image_g_free (image, specs);
3283 return m;
3285 fail:
3286 m = NULL;
3287 goto leave;
3290 static MonoMethod*
3291 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3293 /* We need to clear handles for rmb fields created in mono_reflection_methodbuilder_from_ctor_builder */
3294 HANDLE_FUNCTION_ENTER ();
3295 ReflectionMethodBuilder rmb;
3296 MonoMethodSignature *sig;
3297 MonoMethod *ret;
3299 mono_loader_lock ();
3301 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error)) {
3302 mono_loader_unlock ();
3303 goto exit_null;
3306 g_assert (klass->image != NULL);
3307 sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
3308 mono_loader_unlock ();
3309 goto_if_nok (error, exit_null);
3311 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3312 goto_if_nok (error, exit_null);
3313 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3315 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
3316 /* ilgen is no longer needed */
3317 mb->ilgen = NULL;
3320 ret = mb->mhandle;
3321 goto exit;
3322 exit_null:
3323 ret = NULL;
3324 exit:
3325 HANDLE_FUNCTION_RETURN_VAL (ret);
3328 static MonoMethod*
3329 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
3331 /* We need to clear handles for rmb fields created in mono_reflection_methodbuilder_from_method_builder */
3332 HANDLE_FUNCTION_ENTER ();
3333 ReflectionMethodBuilder rmb;
3334 MonoMethodSignature *sig;
3335 MonoMethod *ret, *method;
3337 error_init (error);
3339 mono_loader_lock ();
3341 MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
3342 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error)) {
3343 mono_loader_unlock ();
3344 goto exit_null;
3347 g_assert (klass->image != NULL);
3348 sig = method_builder_to_signature (klass->image, ref_mb, error);
3349 mono_loader_unlock ();
3350 goto_if_nok (error, exit_null);
3352 method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3353 goto_if_nok (error, exit_null);
3354 MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
3355 mono_save_custom_attrs (klass->image, method, mb->cattrs);
3357 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
3358 /* ilgen is no longer needed */
3359 mb->ilgen = NULL;
3360 ret = method;
3361 goto exit;
3362 exit_null:
3363 ret = NULL;
3364 exit:
3365 HANDLE_FUNCTION_RETURN_VAL (ret);
3368 static MonoMethod*
3369 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
3371 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3372 error_init (error);
3373 MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
3374 MonoMethod * const result = methodbuilder_to_mono_method (klass, mb, error);
3375 HANDLE_FUNCTION_RETURN_VAL (result);
3378 #endif
3380 #ifndef DISABLE_REFLECTION_EMIT
3383 * fix_partial_generic_class:
3384 * @klass: a generic instantiation MonoClass
3385 * @error: set on error
3387 * Assumes that the generic container of @klass has its vtable
3388 * initialized, and updates the parent class, interfaces, methods and
3389 * fields of @klass by inflating the types using the generic context.
3391 * On success returns TRUE, on failure returns FALSE and sets @error.
3394 static gboolean
3395 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3397 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3398 int i;
3400 error_init (error);
3402 if (klass->wastypebuilder)
3403 return TRUE;
3405 if (klass->parent != gklass->parent) {
3406 MonoType *parent_type = mono_class_inflate_generic_type_checked (m_class_get_byval_arg (m_class_get_parent (gklass)), &mono_class_get_generic_class (klass)->context, error);
3407 if (is_ok (error)) {
3408 MonoClass *parent = mono_class_from_mono_type_internal (parent_type);
3409 mono_metadata_free_type (parent_type);
3410 if (parent != klass->parent) {
3411 /*fool mono_class_setup_parent*/
3412 klass->supertypes = NULL;
3413 mono_class_setup_parent (klass, parent);
3415 } else {
3416 if (gklass->wastypebuilder)
3417 klass->wastypebuilder = TRUE;
3418 return FALSE;
3422 if (!mono_class_get_generic_class (klass)->need_sync)
3423 return TRUE;
3425 int mcount = mono_class_get_method_count (klass);
3426 int gmcount = mono_class_get_method_count (gklass);
3427 if (mcount != gmcount) {
3428 mono_class_set_method_count (klass, gmcount);
3429 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
3431 for (i = 0; i < gmcount; i++) {
3432 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3433 gklass->methods [i], klass, mono_class_get_context (klass), error);
3434 mono_error_assert_ok (error);
3438 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3439 klass->interface_count = gklass->interface_count;
3440 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3441 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3443 MonoClass **gklass_interfaces = m_class_get_interfaces (gklass);
3444 for (i = 0; i < gklass->interface_count; ++i) {
3445 MonoType *iface_type = mono_class_inflate_generic_type_checked (m_class_get_byval_arg (gklass_interfaces [i]), mono_class_get_context (klass), error);
3446 return_val_if_nok (error, FALSE);
3448 klass->interfaces [i] = mono_class_from_mono_type_internal (iface_type);
3449 mono_metadata_free_type (iface_type);
3451 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3452 return FALSE;
3454 klass->interfaces_inited = 1;
3457 int fcount = mono_class_get_field_count (klass);
3458 int gfcount = mono_class_get_field_count (gklass);
3459 if (fcount != gfcount) {
3460 mono_class_set_field_count (klass, gfcount);
3461 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3463 for (i = 0; i < gfcount; i++) {
3464 klass->fields [i] = gklass->fields [i];
3465 klass->fields [i].parent = klass;
3466 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3467 return_val_if_nok (error, FALSE);
3471 /*We can only finish with this klass once it's parent has as well*/
3472 if (gklass->wastypebuilder)
3473 klass->wastypebuilder = TRUE;
3474 return TRUE;
3478 * ensure_generic_class_runtime_vtable:
3479 * @klass a generic class
3480 * @error set on error
3482 * Ensures that the generic container of @klass has a vtable and
3483 * returns TRUE on success. On error returns FALSE and sets @error.
3485 static gboolean
3486 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3488 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3490 error_init (error);
3492 if (!ensure_runtime_vtable (gklass, error))
3493 return FALSE;
3495 return fix_partial_generic_class (klass, error);
3499 * ensure_runtime_vtable:
3500 * @klass the class
3501 * @error set on error
3503 * Ensures that @klass has a vtable and returns TRUE on success. On
3504 * error returns FALSE and sets @error.
3506 static gboolean
3507 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3509 MonoReflectionTypeBuilder *tb = mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3510 int i, num, j;
3512 error_init (error);
3514 if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3515 return TRUE;
3516 if (klass->parent)
3517 if (!ensure_runtime_vtable (klass->parent, error))
3518 return FALSE;
3520 if (tb) {
3521 num = tb->ctors? mono_array_length_internal (tb->ctors): 0;
3522 num += tb->num_methods;
3523 mono_class_set_method_count (klass, num);
3524 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3525 num = tb->ctors? mono_array_length_internal (tb->ctors): 0;
3526 for (i = 0; i < num; ++i) {
3527 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get_internal (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3528 if (!ctor)
3529 return FALSE;
3530 klass->methods [i] = ctor;
3532 num = tb->num_methods;
3533 j = i;
3534 for (i = 0; i < num; ++i) {
3535 MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get_internal (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
3536 if (!meth)
3537 return FALSE;
3538 klass->methods [j++] = meth;
3541 if (tb->interfaces) {
3542 klass->interface_count = mono_array_length_internal (tb->interfaces);
3543 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3544 for (i = 0; i < klass->interface_count; ++i) {
3545 MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
3546 return_val_if_nok (error, FALSE);
3547 klass->interfaces [i] = mono_class_from_mono_type_internal (iface);
3548 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3549 return FALSE;
3551 klass->interfaces_inited = 1;
3553 } else if (mono_class_is_ginst (klass)){
3554 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3555 mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3556 return FALSE;
3560 if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3561 int slot_num = 0;
3562 int mcount = mono_class_get_method_count (klass);
3563 for (i = 0; i < mcount; ++i) {
3564 MonoMethod *im = klass->methods [i];
3565 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3566 im->slot = slot_num++;
3569 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3570 mono_class_setup_interface_offsets (klass);
3571 mono_class_setup_interface_id (klass);
3575 * The generic vtable is needed even if image->run is not set since some
3576 * runtime code like ves_icall_Type_GetMethodsByName depends on
3577 * method->slot being defined.
3581 * tb->methods could not be freed since it is used for determining
3582 * overrides during dynamic vtable construction.
3585 return TRUE;
3588 static MonoMethod*
3589 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3591 error_init (error);
3592 MonoClass *klass = mono_object_class (method);
3593 if (is_sr_mono_method (klass)) {
3594 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3595 return sr_method->method;
3597 if (is_sre_method_builder (klass)) {
3598 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3599 return mb->mhandle;
3601 if (mono_is_sre_method_on_tb_inst (klass)) {
3602 MonoClass *handle_class;
3604 MonoMethod *result = (MonoMethod*)mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3605 return_val_if_nok (error, NULL);
3607 return result;
3610 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3611 return NULL;
3614 void
3615 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3617 MonoReflectionTypeBuilder *tb;
3618 int i, j, onum;
3619 MonoReflectionMethod *m;
3621 error_init (error);
3622 *overrides = NULL;
3623 *num_overrides = 0;
3625 g_assert (image_is_dynamic (klass->image));
3627 if (!mono_class_has_ref_info (klass))
3628 return;
3630 tb = mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3631 g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
3633 onum = 0;
3634 if (tb->methods) {
3635 for (i = 0; i < tb->num_methods; ++i) {
3636 MonoReflectionMethodBuilder *mb =
3637 mono_array_get_internal (tb->methods, MonoReflectionMethodBuilder*, i);
3638 if (mb->override_methods)
3639 onum += mono_array_length_internal (mb->override_methods);
3643 if (onum) {
3644 *overrides = g_new0 (MonoMethod*, onum * 2);
3646 onum = 0;
3647 for (i = 0; i < tb->num_methods; ++i) {
3648 MonoReflectionMethodBuilder *mb =
3649 mono_array_get_internal (tb->methods, MonoReflectionMethodBuilder*, i);
3650 if (mb->override_methods) {
3651 for (j = 0; j < mono_array_length_internal (mb->override_methods); ++j) {
3652 m = mono_array_get_internal (mb->override_methods, MonoReflectionMethod*, j);
3654 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3655 return_if_nok (error);
3656 (*overrides) [onum * 2 + 1] = mb->mhandle;
3658 g_assert (mb->mhandle);
3660 onum ++;
3666 *num_overrides = onum;
3669 static gint32
3670 modulebuilder_get_next_table_index (MonoReflectionModuleBuilder *mb, gint32 table, gint32 num_fields, MonoError *error)
3672 error_init (error);
3674 if (mb->table_indexes == NULL) {
3675 MonoArray *arr = mono_array_new_checked (mono_object_domain (&mb->module.obj), mono_defaults.int_class, 64, error);
3676 return_val_if_nok (error, 0);
3677 for (int i = 0; i < 64; i++) {
3678 mono_array_set_internal (arr, int, i, 1);
3680 MONO_OBJECT_SETREF_INTERNAL (mb, table_indexes, arr);
3682 gint32 index = mono_array_get_internal (mb->table_indexes, gint32, table);
3683 gint32 next_index = index + num_fields;
3684 mono_array_set_internal (mb->table_indexes, gint32, table, next_index);
3685 return index;
3688 static void
3689 typebuilder_setup_one_field (MonoDynamicImage *dynamic_image, MonoClass *klass, int32_t first_idx, MonoArray *tb_fields, int i, MonoFieldDefaultValue *def_value_out, MonoError *error)
3691 HANDLE_FUNCTION_ENTER ();
3693 MonoImage *image = klass->image;
3694 MonoReflectionFieldBuilder *fb;
3695 MonoClassField *field;
3696 MonoArray *rva_data;
3698 fb = (MonoReflectionFieldBuilder *)mono_array_get_internal (tb_fields, gpointer, i);
3699 field = &klass->fields [i];
3700 field->parent = klass;
3701 field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
3702 goto_if_nok (error, leave);
3703 if (fb->attrs) {
3704 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3705 goto_if_nok (error, leave);
3706 field->type = mono_metadata_type_dup (klass->image, type);
3707 field->type->attrs = fb->attrs;
3708 } else {
3709 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3710 goto_if_nok (error, leave);
3712 if (klass->enumtype && strcmp (field->name, "value__") == 0) // used by enum classes to store the instance value
3713 field->type->attrs |= FIELD_ATTRIBUTE_RT_SPECIAL_NAME;
3715 if (!mono_type_get_underlying_type (field->type)) {
3716 if (!(klass->enumtype && mono_metadata_type_equal (field->type, m_class_get_byval_arg (klass)))) {
3717 mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
3718 goto leave;
3722 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3723 char *base = mono_array_addr_internal (rva_data, char, 0);
3724 size_t size = mono_array_length_internal (rva_data);
3725 char *data = (char *)mono_image_alloc (klass->image, size);
3726 memcpy (data, base, size);
3727 def_value_out->data = data;
3729 if (fb->offset != -1)
3730 field->offset = fb->offset;
3731 fb->handle = field;
3732 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3734 if (fb->def_value) {
3735 guint32 len, idx;
3736 const char *p, *p2;
3737 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3738 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3739 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_value_out->def_type);
3740 /* Copy the data from the blob since it might get realloc-ed */
3741 p = assembly->blob.data + idx;
3742 len = mono_metadata_decode_blob_size (p, &p2);
3743 len += p2 - p;
3744 def_value_out->data = (const char *)mono_image_alloc (image, len);
3745 memcpy ((gpointer)def_value_out->data, p, len);
3748 MonoObjectHandle field_builder_handle = MONO_HANDLE_CAST (MonoObject, MONO_HANDLE_NEW (MonoReflectionFieldBuilder, fb));
3749 mono_dynamic_image_register_token (dynamic_image, mono_metadata_make_token (MONO_TABLE_FIELD, first_idx + i), field_builder_handle, MONO_DYN_IMAGE_TOK_NEW);
3751 leave:
3752 HANDLE_FUNCTION_RETURN ();
3755 /* This initializes the same data as mono_class_setup_fields () */
3756 static void
3757 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3759 MonoReflectionTypeBuilder *tb = mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3760 MonoFieldDefaultValue *def_values;
3761 MonoImage *image = klass->image;
3762 int i, instance_size, packing_size = 0;
3764 error_init (error);
3766 if (klass->parent) {
3767 if (!klass->parent->size_inited)
3768 mono_class_init_internal (klass->parent);
3769 instance_size = klass->parent->instance_size;
3770 } else {
3771 instance_size = MONO_ABI_SIZEOF (MonoObject);
3774 int fcount = tb->num_fields;
3775 mono_class_set_field_count (klass, fcount);
3777 gint32 first_idx = 0;
3778 if (tb->num_fields > 0) {
3779 first_idx = modulebuilder_get_next_table_index (tb->module, MONO_TABLE_FIELD, (gint32)tb->num_fields, error);
3780 return_if_nok (error);
3782 mono_class_set_first_field_idx (klass, first_idx - 1); /* Why do we subtract 1? because mono_class_create_from_typedef does it, too. */
3784 if (tb->class_size) {
3785 packing_size = tb->packing_size;
3786 instance_size += tb->class_size;
3789 klass->fields = image_g_new0 (image, MonoClassField, fcount);
3790 def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3791 mono_class_set_field_def_values (klass, def_values);
3793 This is, guess what, a hack.
3794 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3795 On the static path no field class is resolved, only types are built. This is the right thing to do
3796 but we suck.
3797 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3799 klass->size_inited = 1;
3801 for (i = 0; i < fcount; ++i) {
3802 typebuilder_setup_one_field (tb->module->dynamic_image, klass, first_idx, tb->fields, i, &def_values[i], error);
3803 if (!is_ok (error))
3804 return;
3807 if (!mono_class_has_failure (klass))
3808 mono_class_layout_fields (klass, instance_size, packing_size, tb->class_size, TRUE);
3811 static void
3812 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3814 MonoReflectionTypeBuilder *tb = mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3815 MonoReflectionPropertyBuilder *pb;
3816 MonoImage *image = klass->image;
3817 MonoProperty *properties;
3818 MonoClassPropertyInfo *info;
3819 int i;
3821 error_init (error);
3823 info = (MonoClassPropertyInfo*)mono_class_get_property_info (klass);
3824 if (!info) {
3825 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3826 mono_class_set_property_info (klass, info);
3829 info->count = tb->properties ? mono_array_length_internal (tb->properties) : 0;
3830 info->first = 0;
3832 properties = image_g_new0 (image, MonoProperty, info->count);
3833 info->properties = properties;
3834 for (i = 0; i < info->count; ++i) {
3835 pb = mono_array_get_internal (tb->properties, MonoReflectionPropertyBuilder*, i);
3836 properties [i].parent = klass;
3837 properties [i].attrs = pb->attrs;
3838 properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
3839 if (!is_ok (error))
3840 return;
3841 if (pb->get_method)
3842 properties [i].get = pb->get_method->mhandle;
3843 if (pb->set_method)
3844 properties [i].set = pb->set_method->mhandle;
3846 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3847 if (pb->def_value) {
3848 guint32 len, idx;
3849 const char *p, *p2;
3850 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3851 if (!info->def_values)
3852 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3853 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3854 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3855 /* Copy the data from the blob since it might get realloc-ed */
3856 p = assembly->blob.data + idx;
3857 len = mono_metadata_decode_blob_size (p, &p2);
3858 len += p2 - p;
3859 info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3860 memcpy ((gpointer)info->def_values [i].data, p, len);
3865 static void
3866 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3868 MonoReflectionTypeBuilder *tb = mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3869 MonoReflectionEventBuilder *eb;
3870 MonoImage *image = klass->image;
3871 MonoEvent *events;
3872 MonoClassEventInfo *info;
3873 int i;
3875 error_init (error);
3877 info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3878 mono_class_set_event_info (klass, info);
3880 info->count = tb->events ? mono_array_length_internal (tb->events) : 0;
3881 info->first = 0;
3883 events = image_g_new0 (image, MonoEvent, info->count);
3884 info->events = events;
3885 for (i = 0; i < info->count; ++i) {
3886 eb = mono_array_get_internal (tb->events, MonoReflectionEventBuilder*, i);
3887 events [i].parent = klass;
3888 events [i].attrs = eb->attrs;
3889 events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
3890 if (!is_ok (error))
3891 return;
3892 if (eb->add_method)
3893 events [i].add = eb->add_method->mhandle;
3894 if (eb->remove_method)
3895 events [i].remove = eb->remove_method->mhandle;
3896 if (eb->raise_method)
3897 events [i].raise = eb->raise_method->mhandle;
3899 #ifndef MONO_SMALL_CONFIG
3900 if (eb->other_methods) {
3901 int j;
3902 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length_internal (eb->other_methods) + 1);
3903 for (j = 0; j < mono_array_length_internal (eb->other_methods); ++j) {
3904 MonoReflectionMethodBuilder *mb =
3905 mono_array_get_internal (eb->other_methods,
3906 MonoReflectionMethodBuilder*, j);
3907 events [i].other [j] = mb->mhandle;
3910 #endif
3911 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3915 struct remove_instantiations_user_data
3917 MonoClass *klass;
3918 MonoError *error;
3921 static gboolean
3922 remove_instantiations_of_and_ensure_contents (gpointer key,
3923 gpointer value,
3924 gpointer user_data)
3926 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3927 MonoType *type = (MonoType*)key;
3928 MonoClass *klass = data->klass;
3929 gboolean already_failed = !is_ok (data->error);
3930 ERROR_DECL (lerror);
3931 MonoError *error = already_failed ? lerror : data->error;
3933 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3934 MonoClass *inst_klass = mono_class_from_mono_type_internal (type);
3935 //Ensure it's safe to use it.
3936 if (!fix_partial_generic_class (inst_klass, error)) {
3937 mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3938 // Marked the class with failure, but since some other instantiation already failed,
3939 // just report that one, and swallow the error from this one.
3940 if (already_failed)
3941 mono_error_cleanup (error);
3943 return TRUE;
3944 } else
3945 return FALSE;
3949 * reflection_setup_internal_class:
3950 * @tb: a TypeBuilder object
3951 * @error: set on error
3953 * Creates a MonoClass that represents the TypeBuilder.
3954 * This is a trick that lets us simplify a lot of reflection code
3955 * (and will allow us to support Build and Run assemblies easier).
3957 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3959 static gboolean
3960 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3962 HANDLE_FUNCTION_ENTER ();
3964 MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
3965 GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
3966 gboolean ret_val;
3968 if (unparented_classes) {
3969 ret_val = reflection_setup_internal_class_internal (ref_tb, error);
3970 } else {
3971 // If we're not being called recursively
3972 unparented_classes = g_hash_table_new (NULL, NULL);
3973 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
3975 ret_val = reflection_setup_internal_class_internal (ref_tb, error);
3976 mono_error_assert_ok (error);
3978 // Fix the relationship between the created classes and their parents
3979 reflection_setup_class_hierarchy (unparented_classes, error);
3980 mono_error_assert_ok (error);
3982 g_hash_table_destroy (unparented_classes);
3983 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
3986 HANDLE_FUNCTION_RETURN_VAL (ret_val);
3989 MonoReflectionTypeHandle
3990 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3992 error_init (error);
3994 reflection_setup_internal_class (ref_tb, error);
3995 mono_error_assert_ok (error);
3997 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
3998 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
3999 MonoClass *klass = mono_class_from_mono_type_internal (type);
4001 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
4002 mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
4005 * we need to lock the domain because the lock will be taken inside
4006 * So, we need to keep the locking order correct.
4008 mono_loader_lock ();
4009 mono_domain_lock (domain);
4010 if (klass->wastypebuilder) {
4011 mono_domain_unlock (domain);
4012 mono_loader_unlock ();
4014 return mono_type_get_object_handle (domain, m_class_get_byval_arg (klass), error);
4017 * Fields to set in klass:
4018 * the various flags: delegate/unicode/contextbound etc.
4020 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
4021 klass->has_cctor = 1;
4023 mono_class_setup_parent (klass, klass->parent);
4024 /* fool mono_class_setup_supertypes */
4025 klass->supertypes = NULL;
4026 mono_class_setup_supertypes (klass);
4027 mono_class_setup_mono_type (klass);
4029 /* enums are done right away */
4030 if (!klass->enumtype)
4031 if (!ensure_runtime_vtable (klass, error))
4032 goto failure;
4034 MonoArrayHandle nested_types;
4035 nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
4036 if (!MONO_HANDLE_IS_NULL (nested_types)) {
4037 GList *nested = NULL;
4038 int num_nested = mono_array_handle_length (nested_types);
4039 MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
4040 for (int i = 0; i < num_nested; ++i) {
4041 MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
4043 if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
4044 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
4045 mono_error_assert_ok (error);
4048 MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
4049 goto_if_nok (error, failure);
4050 nested = mono_g_list_prepend_image (klass->image, nested, mono_class_from_mono_type_internal (subtype));
4052 mono_class_set_nested_classes_property (klass, nested);
4055 klass->nested_classes_inited = TRUE;
4057 typebuilder_setup_fields (klass, error);
4058 goto_if_nok (error, failure);
4059 typebuilder_setup_properties (klass, error);
4060 goto_if_nok (error, failure);
4062 typebuilder_setup_events (klass, error);
4063 goto_if_nok (error, failure);
4065 klass->wastypebuilder = TRUE;
4067 MonoArrayHandle generic_params;
4068 generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
4069 if (!MONO_HANDLE_IS_NULL (generic_params)) {
4070 int num_params = mono_array_handle_length (generic_params);
4071 MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
4072 for (int i = 0; i < num_params; i++) {
4073 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
4074 MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
4075 goto_if_nok (error, failure);
4076 MonoClass *gklass = mono_class_from_mono_type_internal (param_type);
4078 gklass->wastypebuilder = TRUE;
4083 * If we are a generic TypeBuilder, there might be instantiations in the type cache
4084 * which have type System.Reflection.MonoGenericClass, but after the type is created,
4085 * we want to return normal System.MonoType objects, so clear these out from the cache.
4087 * Together with this we must ensure the contents of all instances to match the created type.
4089 if (mono_class_is_gtd (klass)) {
4090 MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
4091 struct remove_instantiations_user_data data;
4092 data.klass = klass;
4093 data.error = error;
4094 mono_error_assert_ok (error);
4095 mono_mem_manager_lock (memory_manager);
4096 mono_g_hash_table_foreach_remove (memory_manager->type_hash, remove_instantiations_of_and_ensure_contents, &data);
4097 mono_mem_manager_unlock (memory_manager);
4098 goto_if_nok (error, failure);
4101 mono_domain_unlock (domain);
4102 mono_loader_unlock ();
4104 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
4105 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
4106 mono_error_set_type_load_class (error, klass, "Not a valid enumeration");
4107 goto failure_unlocked;
4110 MonoReflectionTypeHandle res;
4111 res = mono_type_get_object_handle (domain, m_class_get_byval_arg (klass), error);
4112 goto_if_nok (error, failure_unlocked);
4114 return res;
4116 failure:
4117 mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
4118 klass->wastypebuilder = TRUE;
4119 mono_domain_unlock (domain);
4120 mono_loader_unlock ();
4121 failure_unlocked:
4122 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4125 typedef struct {
4126 MonoMethod *handle;
4127 MonoDomain *domain;
4128 } DynamicMethodReleaseData;
4131 * The runtime automatically clean up those after finalization.
4133 static MonoReferenceQueue *dynamic_method_queue;
4135 static void
4136 free_dynamic_method (void *dynamic_method)
4138 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
4139 MonoDomain *domain = data->domain;
4140 MonoMethod *method = data->handle;
4141 MonoGCHandle dis_link;
4143 mono_domain_lock (domain);
4144 dis_link = g_hash_table_lookup (domain->method_to_dyn_method, method);
4145 g_hash_table_remove (domain->method_to_dyn_method, method);
4146 mono_domain_unlock (domain);
4147 g_assert (dis_link);
4148 mono_gchandle_free_internal (dis_link);
4150 mono_runtime_free_method (domain, method);
4151 g_free (data);
4154 static gboolean
4155 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
4157 /* We need to clear handles for rmb fields created in reflection_methodbuilder_from_dynamic_method */
4158 HANDLE_FUNCTION_ENTER ();
4159 MonoReferenceQueue *queue;
4160 MonoMethod *handle;
4161 DynamicMethodReleaseData *release_data;
4162 ReflectionMethodBuilder rmb;
4163 MonoMethodSignature *sig;
4164 MonoClass *klass;
4165 MonoDomain *domain;
4166 GSList *l;
4167 int i;
4168 gboolean ret = TRUE;
4169 MonoReflectionDynamicMethod *mb;
4170 MonoAssembly *ass = NULL;
4172 error_init (error);
4174 if (!(queue = dynamic_method_queue)) {
4175 mono_loader_lock ();
4176 if (!(queue = dynamic_method_queue))
4177 queue = dynamic_method_queue = mono_gc_reference_queue_new_internal (free_dynamic_method);
4178 mono_loader_unlock ();
4181 sig = dynamic_method_to_signature (ref_mb, error);
4182 goto_if_nok (error, exit_false);
4184 mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
4185 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
4188 * Resolve references.
4191 * Every second entry in the refs array is reserved for storing handle_class,
4192 * which is needed by the ldtoken implementation in the JIT.
4194 rmb.nrefs = mb->nrefs;
4195 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
4196 for (i = 0; i < mb->nrefs; i += 2) {
4197 MonoClass *handle_class;
4198 gpointer ref;
4199 MonoObject *obj = mono_array_get_internal (mb->refs, MonoObject*, i);
4200 MONO_HANDLE_PIN (obj);
4202 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4203 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4205 * The referenced DynamicMethod should already be created by the managed
4206 * code, except in the case of circular references. In that case, we store
4207 * method in the refs array, and fix it up later when the referenced
4208 * DynamicMethod is created.
4210 if (method->mhandle) {
4211 ref = method->mhandle;
4212 } else {
4213 ref = method;
4215 method->referenced_by = g_slist_append (method->referenced_by, mb);
4217 handle_class = mono_defaults.methodhandle_class;
4218 } else {
4219 MonoException *ex = NULL;
4220 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
4221 /* ref should not be a reference. Otherwise we would need a handle for it */
4222 if (!is_ok (error)) {
4223 g_free (rmb.refs);
4224 goto exit_false;
4226 if (!ref)
4227 ex = mono_get_exception_type_load (NULL, NULL);
4228 else if (mono_security_core_clr_enabled ())
4229 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
4231 if (ex) {
4232 g_free (rmb.refs);
4233 mono_error_set_exception_instance (error, ex);
4234 goto exit_false;
4238 rmb.refs [i] = ref;
4239 rmb.refs [i + 1] = handle_class;
4242 if (mb->owner) {
4243 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
4244 if (!is_ok (error)) {
4245 g_free (rmb.refs);
4246 goto exit_false;
4248 klass = mono_class_from_mono_type_internal (owner_type);
4249 ass = klass->image->assembly;
4250 } else {
4251 klass = mono_defaults.object_class;
4252 ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
4255 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
4256 ((MonoDynamicMethod*)handle)->assembly = ass;
4257 g_free (rmb.refs);
4258 goto_if_nok (error, exit_false);
4260 release_data = g_new (DynamicMethodReleaseData, 1);
4261 release_data->handle = handle;
4262 release_data->domain = mono_object_get_domain_internal ((MonoObject*)mb);
4263 if (!mono_gc_reference_queue_add_internal (queue, (MonoObject*)mb, release_data))
4264 g_free (release_data);
4266 /* Fix up refs entries pointing at us */
4267 for (l = mb->referenced_by; l; l = l->next) {
4268 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
4269 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
4270 gpointer *data;
4272 g_assert (method->mhandle);
4274 data = (gpointer*)wrapper->method_data;
4275 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
4276 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
4277 data [i + 1] = mb->mhandle;
4280 g_slist_free (mb->referenced_by);
4282 domain = mono_domain_get ();
4283 mono_domain_lock (domain);
4284 if (!domain->method_to_dyn_method)
4285 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4286 g_hash_table_insert (domain->method_to_dyn_method, handle, mono_gchandle_new_weakref_internal ((MonoObject *)mb, TRUE));
4287 mono_domain_unlock (domain);
4289 goto exit;
4290 exit_false:
4291 ret = FALSE;
4292 exit:
4293 HANDLE_FUNCTION_RETURN_VAL (ret);
4296 void
4297 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4299 (void) reflection_create_dynamic_method (mb, error);
4302 #endif /* DISABLE_REFLECTION_EMIT */
4304 MonoMethodSignature *
4305 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4307 MonoMethodSignature *sig;
4308 g_assert (image_is_dynamic (image));
4310 error_init (error);
4312 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4313 if (sig)
4314 return sig;
4316 return mono_method_signature_checked (method, error);
4319 #ifndef DISABLE_REFLECTION_EMIT
4322 * ensure_complete_type:
4324 * Ensure that KLASS is completed if it is a dynamic type, or references
4325 * dynamic types.
4327 static void
4328 ensure_complete_type (MonoClass *klass, MonoError *error)
4330 HANDLE_FUNCTION_ENTER ();
4332 error_init (error);
4334 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
4335 #ifndef ENABLE_NETCORE
4336 MonoReflectionTypeBuilderHandle tb = mono_class_get_ref_info (klass);
4338 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb, error);
4339 goto_if_nok (error, exit);
4341 // Asserting here could break a lot of code
4342 //g_assert (klass->wastypebuilder);
4343 #else
4344 // TODO: make this work on netcore when working on SRE.TypeBuilder
4345 g_assert_not_reached ();
4346 #endif
4349 if (mono_class_is_ginst (klass)) {
4350 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
4351 int i;
4353 for (i = 0; i < inst->type_argc; ++i) {
4354 ensure_complete_type (mono_class_from_mono_type_internal (inst->type_argv [i]), error);
4355 goto_if_nok (error, exit);
4359 exit:
4360 HANDLE_FUNCTION_RETURN ();
4363 gpointer
4364 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4366 HANDLE_FUNCTION_ENTER ();
4368 MonoClass *oklass = obj->vtable->klass;
4369 gpointer result = NULL;
4371 error_init (error);
4373 if (strcmp (oklass->name, "String") == 0) {
4374 result = MONO_HANDLE_RAW (mono_string_intern_checked (MONO_HANDLE_NEW (MonoString, (MonoString*)obj), error));
4375 goto_if_nok (error, return_null);
4376 *handle_class = mono_defaults.string_class;
4377 g_assert (result);
4378 } else if (strcmp (oklass->name, "RuntimeType") == 0) {
4379 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4380 goto_if_nok (error, return_null);
4381 MonoClass *mc = mono_class_from_mono_type_internal (type);
4382 if (!mono_class_init_internal (mc)) {
4383 mono_error_set_for_class_failure (error, mc);
4384 goto return_null;
4387 if (context) {
4388 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4389 goto_if_nok (error, return_null);
4391 result = mono_class_from_mono_type_internal (inflated);
4392 mono_metadata_free_type (inflated);
4393 } else {
4394 result = mono_class_from_mono_type_internal (type);
4396 *handle_class = mono_defaults.typehandle_class;
4397 g_assert (result);
4398 } else if (strcmp (oklass->name, "RuntimeMethodInfo") == 0 ||
4399 strcmp (oklass->name, "RuntimeConstructorInfo") == 0) {
4400 result = ((MonoReflectionMethod*)obj)->method;
4401 if (context) {
4402 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4403 mono_error_assert_ok (error);
4405 *handle_class = mono_defaults.methodhandle_class;
4406 g_assert (result);
4407 } else if (strcmp (oklass->name, "RuntimeFieldInfo") == 0) {
4408 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4410 ensure_complete_type (field->parent, error);
4411 goto_if_nok (error, return_null);
4413 if (context) {
4414 MonoType *inflated = mono_class_inflate_generic_type_checked (m_class_get_byval_arg (field->parent), context, error);
4415 goto_if_nok (error, return_null);
4417 MonoClass *klass;
4418 klass = mono_class_from_mono_type_internal (inflated);
4419 MonoClassField *inflated_field;
4420 gpointer iter = NULL;
4421 mono_metadata_free_type (inflated);
4422 while ((inflated_field = mono_class_get_fields_internal (klass, &iter))) {
4423 if (!strcmp (field->name, inflated_field->name))
4424 break;
4426 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4427 result = inflated_field;
4428 } else {
4429 result = field;
4431 *handle_class = mono_defaults.fieldhandle_class;
4432 g_assert (result);
4433 } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
4434 MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_NEW (MonoReflectionTypeBuilder, (MonoReflectionTypeBuilder*)obj);
4435 MonoType *type = mono_reflection_type_get_handle (&MONO_HANDLE_RAW (tb)->type, error);
4436 goto_if_nok (error, return_null);
4437 MonoClass *klass;
4439 klass = type->data.klass;
4440 if (klass->wastypebuilder) {
4441 /* Already created */
4442 result = klass;
4443 } else {
4444 #ifndef ENABLE_NETCORE
4445 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb, error);
4446 goto_if_nok (error, return_null);
4447 result = type->data.klass;
4448 g_assert (result);
4449 #else
4450 // TODO: make this work on netcore when working on SRE.TypeBuilder
4451 g_assert_not_reached();
4452 #endif
4455 *handle_class = mono_defaults.typehandle_class;
4456 } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
4457 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4458 MonoMethodSignature *sig;
4459 int nargs, i;
4461 if (helper->arguments)
4462 nargs = mono_array_length_internal (helper->arguments);
4463 else
4464 nargs = 0;
4466 sig = mono_metadata_signature_alloc (image, nargs);
4467 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4468 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4470 if (helper->unmanaged_call_conv) { /* unmanaged */
4471 sig->call_convention = helper->unmanaged_call_conv - 1;
4472 sig->pinvoke = TRUE;
4473 } else if (helper->call_conv & 0x02) {
4474 sig->call_convention = MONO_CALL_VARARG;
4475 } else {
4476 sig->call_convention = MONO_CALL_DEFAULT;
4479 sig->param_count = nargs;
4480 /* TODO: Copy type ? */
4481 sig->ret = helper->return_type->type;
4482 for (i = 0; i < nargs; ++i) {
4483 sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
4484 if (!is_ok (error)) {
4485 image_g_free (image, sig);
4486 goto return_null;
4490 result = sig;
4491 *handle_class = NULL;
4492 } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4493 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4494 /* Already created by the managed code */
4495 g_assert (method->mhandle);
4496 result = method->mhandle;
4497 *handle_class = mono_defaults.methodhandle_class;
4498 } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4499 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4500 MonoType *mtype;
4501 MonoClass *klass;
4502 MonoMethod *method;
4503 gpointer iter;
4504 char *name;
4506 mtype = mono_reflection_type_get_handle (m->parent, error);
4507 goto_if_nok (error, return_null);
4508 klass = mono_class_from_mono_type_internal (mtype);
4510 /* Find the method */
4512 name = mono_string_to_utf8_checked_internal (m->name, error);
4513 goto_if_nok (error, return_null);
4514 iter = NULL;
4515 while ((method = mono_class_get_methods (klass, &iter))) {
4516 if (!strcmp (method->name, name))
4517 break;
4519 g_free (name);
4521 // FIXME:
4522 g_assert (method);
4523 // FIXME: Check parameters/return value etc. match
4525 result = method;
4526 *handle_class = mono_defaults.methodhandle_class;
4527 } else if (is_sre_method_builder (oklass) ||
4528 mono_is_sre_ctor_builder (oklass) ||
4529 is_sre_field_builder (oklass) ||
4530 is_sre_gparam_builder (oklass) ||
4531 is_sre_generic_instance (oklass) ||
4532 is_sre_array (oklass) ||
4533 is_sre_byref (oklass) ||
4534 is_sre_pointer (oklass) ||
4535 !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4536 !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4537 !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4538 static MonoMethod *resolve_method;
4539 if (!resolve_method) {
4540 MonoMethod *m = mono_class_get_method_from_name_checked (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0, error);
4541 mono_error_assert_ok (error);
4542 g_assert (m);
4543 mono_memory_barrier ();
4544 resolve_method = m;
4546 void *args [ ] = { obj };
4547 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4548 goto_if_nok (error, return_null);
4549 g_assert (obj);
4550 result = mono_reflection_resolve_object (image, obj, handle_class, context, error);
4551 goto exit;
4552 } else {
4553 g_print ("%s\n", obj->vtable->klass->name);
4554 g_assert_not_reached ();
4557 goto exit;
4558 return_null:
4559 result = NULL;
4560 goto exit;
4561 exit:
4562 HANDLE_FUNCTION_RETURN_VAL (result);
4565 gpointer
4566 mono_reflection_resolve_object_handle (MonoImage *image, MonoObjectHandle obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4568 return mono_reflection_resolve_object (image, MONO_HANDLE_RAW (obj), handle_class, context, error);
4571 #else /* DISABLE_REFLECTION_EMIT */
4573 MonoArray*
4574 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4576 g_assert_not_reached ();
4577 return NULL;
4580 void
4581 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb, MonoError *error)
4583 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4586 static gboolean
4587 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4589 g_assert_not_reached ();
4590 return FALSE;
4593 guint32
4594 mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4596 g_assert_not_reached ();
4597 return 0;
4600 guint32
4601 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
4603 g_assert_not_reached ();
4604 return 0;
4607 guint32
4608 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
4609 gboolean create_open_instance, gboolean register_token, MonoError *error)
4611 g_assert_not_reached ();
4612 return 0;
4615 void
4616 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4618 error_init (error);
4619 *overrides = NULL;
4620 *num_overrides = 0;
4623 MonoReflectionTypeHandle
4624 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
4626 g_assert_not_reached ();
4627 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4630 void
4631 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4633 error_init (error);
4636 MonoType*
4637 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4639 error_init (error);
4640 if (!ref)
4641 return NULL;
4642 return ref->type;
4645 MonoType*
4646 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
4648 error_init (error);
4649 if (MONO_HANDLE_IS_NULL (ref))
4650 return NULL;
4651 return MONO_HANDLE_GETVAL (ref, type);
4655 #endif /* DISABLE_REFLECTION_EMIT */
4657 void
4658 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4660 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
4661 g_free (entry);
4664 gint32
4665 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, MonoBoolean create_open_instance, MonoError *error)
4667 if (MONO_HANDLE_IS_NULL (obj)) {
4668 mono_error_set_argument_null (error, "obj", "");
4669 return 0;
4671 return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
4674 gint32
4675 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
4676 MonoReflectionMethodHandle method,
4677 MonoArrayHandle opt_param_types,
4678 MonoError *error)
4680 if (MONO_HANDLE_IS_NULL (method)) {
4681 mono_error_set_argument_null (error, "method", "");
4682 return 0;
4685 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
4688 #ifndef ENABLE_NETCORE
4689 void
4690 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilderHandle mb, HANDLE file, MonoError* error)
4692 mono_image_create_pefile (MONO_HANDLE_RAW (mb), file, error);
4695 void
4696 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilderHandle mb, MonoError* error)
4698 mono_image_build_metadata (MONO_HANDLE_RAW (mb), error);
4700 #endif
4702 void
4703 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
4705 /* This function may be called by ModuleBuilder.FixupTokens to update
4706 * an existing token, so replace is okay here. */
4707 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
4710 MonoObjectHandle
4711 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
4713 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4714 return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
4717 #ifndef DISABLE_REFLECTION_EMIT
4719 MonoArrayHandle
4720 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssemblyHandle assembly, MonoObjectHandle ctor,
4721 MonoArrayHandle ctorArgs, MonoArrayHandle properties,
4722 MonoArrayHandle propValues, MonoArrayHandle fields,
4723 MonoArrayHandle fieldValues, MonoError* error)
4725 return mono_reflection_get_custom_attrs_blob_checked (MONO_HANDLE_RAW (assembly), MONO_HANDLE_RAW (ctor),
4726 MONO_HANDLE_RAW (ctorArgs), MONO_HANDLE_RAW (properties),
4727 MONO_HANDLE_RAW (propValues), MONO_HANDLE_RAW (fields),
4728 MONO_HANDLE_RAW (fieldValues), error);
4731 #endif
4733 void
4734 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
4736 MonoGCHandle gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, assemblyb), TRUE);
4737 mono_reflection_dynimage_basic_init (MONO_HANDLE_RAW (assemblyb), error);
4738 mono_gchandle_free_internal (gchandle);
4741 void
4742 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
4744 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
4746 MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
4747 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
4748 g_assert (assembly);
4750 mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
4753 void
4754 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
4755 MonoReflectionTypeHandle t,
4756 MonoError *error)
4758 MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
4761 void
4762 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4764 mono_image_module_basic_init (moduleb, error);
4767 guint32
4768 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4770 return mono_image_insert_string (module, str, error);
4773 void
4774 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
4776 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
4777 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4779 g_assert (type);
4780 image->wrappers_type = mono_class_from_mono_type_internal (type);