[sre] register a canonical MonoReflectionMethod for a methodref token
[mono.git] / mono / metadata / sre.c
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)
9  *
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
14  *
15  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
16  */
17 #include <config.h>
18 #include <glib.h>
19 #include "mono/metadata/assembly.h"
20 #include "mono/metadata/debug-helpers.h"
21 #include "mono/metadata/dynamic-image-internals.h"
22 #include "mono/metadata/dynamic-stream-internals.h"
23 #include "mono/metadata/exception.h"
24 #include "mono/metadata/gc-internals.h"
25 #include "mono/metadata/mono-ptr-array.h"
26 #include "mono/metadata/object-internals.h"
27 #include "mono/metadata/profiler-private.h"
28 #include "mono/metadata/reflection-internals.h"
29 #include "mono/metadata/reflection-cache.h"
30 #include "mono/metadata/sre-internals.h"
31 #include "mono/metadata/custom-attrs-internals.h"
32 #include "mono/metadata/security-manager.h"
33 #include "mono/metadata/security-core-clr.h"
34 #include "mono/metadata/tabledefs.h"
35 #include "mono/metadata/tokentype.h"
36 #include "mono/utils/checked-build.h"
37 #include "mono/utils/mono-digest.h"
38 #include "mono/utils/w32api.h"
39
40 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, "System.Runtime.InteropServices", "MarshalAsAttribute");
41 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", "ModuleBuilder");
42
43 static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
44
45 #ifndef DISABLE_REFLECTION_EMIT
46 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
47 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
48 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
49 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
50 static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
51 static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
52
53
54 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
55 #endif
56
57 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
58 static MonoReflectionTypeHandle mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error);
59 static gboolean is_sre_array (MonoClass *klass);
60 static gboolean is_sre_byref (MonoClass *klass);
61 static gboolean is_sre_pointer (MonoClass *klass);
62 static gboolean is_sre_generic_instance (MonoClass *klass);
63 static gboolean is_sre_type_builder (MonoClass *klass);
64 static gboolean is_sre_method_builder (MonoClass *klass);
65 static gboolean is_sre_field_builder (MonoClass *klass);
66 static gboolean is_sre_gparam_builder (MonoClass *klass);
67 static gboolean is_sre_enum_builder (MonoClass *klass);
68 static gboolean is_sr_mono_method (MonoClass *klass);
69 static gboolean is_sr_mono_field (MonoClass *klass);
70
71 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
72 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
73 static guint32 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error);
74
75
76 #ifndef DISABLE_REFLECTION_EMIT
77 static MonoType* mono_type_array_get_and_resolve_raw (MonoArray* array, int idx, MonoError* error);
78 #endif
79
80 static gboolean mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module, MonoError *error);
81
82 void
83 mono_reflection_emit_init (void)
84 {
85         mono_dynamic_images_init ();
86 }
87
88 char*
89 string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
90 {
91         /* FIXME all callers to string_to_utf8_image_raw should use handles */
92         HANDLE_FUNCTION_ENTER ();
93         char* result = NULL;
94         error_init (error);
95         MONO_HANDLE_DCL (MonoString, s);
96         result = mono_string_to_utf8_image (image, s, error);
97         HANDLE_FUNCTION_RETURN_VAL (result);
98 }
99
100 static char*
101 type_get_fully_qualified_name (MonoType *type)
102 {
103         MONO_REQ_GC_NEUTRAL_MODE;
104
105         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
106 }
107
108 static char*
109 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
110 {
111         MONO_REQ_GC_UNSAFE_MODE;
112
113         MonoClass *klass;
114         MonoAssembly *ta;
115
116         klass = mono_class_from_mono_type (type);
117         if (!klass) 
118                 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
119         ta = klass->image->assembly;
120         if (assembly_is_dynamic (ta) || (ta == ass)) {
121                 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
122                         /* For generic type definitions, we want T, while REFLECTION returns T<K> */
123                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
124                 else
125                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
126         }
127
128         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
129 }
130
131 #ifndef DISABLE_REFLECTION_EMIT
132 /**
133  * mp_g_alloc:
134  *
135  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
136  * from the C heap.
137  */
138 static gpointer
139 image_g_malloc (MonoImage *image, guint size)
140 {
141         MONO_REQ_GC_NEUTRAL_MODE;
142
143         if (image)
144                 return mono_image_alloc (image, size);
145         else
146                 return g_malloc (size);
147 }
148 #endif /* !DISABLE_REFLECTION_EMIT */
149
150 /**
151  * image_g_alloc0:
152  *
153  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
154  * from the C heap.
155  */
156 gpointer
157 mono_image_g_malloc0 (MonoImage *image, guint size)
158 {
159         MONO_REQ_GC_NEUTRAL_MODE;
160
161         if (image)
162                 return mono_image_alloc0 (image, size);
163         else
164                 return g_malloc0 (size);
165 }
166
167 /**
168  * image_g_free:
169  * @image: a MonoImage
170  * @ptr: pointer
171  *
172  * If @image is NULL, free @ptr, otherwise do nothing.
173  */
174 static void
175 image_g_free (MonoImage *image, gpointer ptr)
176 {
177         if (image == NULL)
178                 g_free (ptr);
179 }
180
181 #ifndef DISABLE_REFLECTION_EMIT
182 static char*
183 image_strdup (MonoImage *image, const char *s)
184 {
185         MONO_REQ_GC_NEUTRAL_MODE;
186
187         if (image)
188                 return mono_image_strdup (image, s);
189         else
190                 return g_strdup (s);
191 }
192 #endif
193
194 #define image_g_new(image,struct_type, n_structs)               \
195     ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
196
197 #define image_g_new0(image,struct_type, n_structs)              \
198     ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
199
200
201 static void
202 alloc_table (MonoDynamicTable *table, guint nrows)
203 {
204         mono_dynimage_alloc_table (table, nrows);
205 }
206
207 static guint32
208 string_heap_insert (MonoDynamicStream *sh, const char *str)
209 {
210         return mono_dynstream_insert_string (sh, str);
211 }
212
213 static guint32
214 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
215 {
216         return mono_dynstream_add_data (stream, data, len);
217 }
218
219 /*
220  * Despite the name, we handle also TypeSpec (with the above helper).
221  */
222 static guint32
223 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
224 {
225         return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
226 }
227
228 /*
229  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
230  * dest may be misaligned.
231  */
232 static void
233 swap_with_size (char *dest, const char* val, int len, int nelem) {
234         MONO_REQ_GC_NEUTRAL_MODE;
235 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
236         int elem;
237
238         for (elem = 0; elem < nelem; ++elem) {
239                 switch (len) {
240                 case 1:
241                         *dest = *val;
242                         break;
243                 case 2:
244                         dest [0] = val [1];
245                         dest [1] = val [0];
246                         break;
247                 case 4:
248                         dest [0] = val [3];
249                         dest [1] = val [2];
250                         dest [2] = val [1];
251                         dest [3] = val [0];
252                         break;
253                 case 8:
254                         dest [0] = val [7];
255                         dest [1] = val [6];
256                         dest [2] = val [5];
257                         dest [3] = val [4];
258                         dest [4] = val [3];
259                         dest [5] = val [2];
260                         dest [6] = val [1];
261                         dest [7] = val [0];
262                         break;
263                 default:
264                         g_assert_not_reached ();
265                 }
266                 dest += len;
267                 val += len;
268         }
269 #else
270         memcpy (dest, val, len * nelem);
271 #endif
272 }
273
274 guint32
275 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
276 {
277         MONO_REQ_GC_UNSAFE_MODE;
278
279         guint32 num_clauses = 0;
280         int i;
281
282         MonoILExceptionInfo *ex_info;
283         for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
284                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
285                 if (ex_info->handlers)
286                         num_clauses += mono_array_length (ex_info->handlers);
287                 else
288                         num_clauses++;
289         }
290
291         return num_clauses;
292 }
293
294 #ifndef DISABLE_REFLECTION_EMIT
295 static MonoExceptionClause*
296 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
297 {
298         MONO_REQ_GC_UNSAFE_MODE;
299
300         error_init (error);
301
302         MonoExceptionClause *clauses;
303         MonoExceptionClause *clause;
304         MonoILExceptionInfo *ex_info;
305         MonoILExceptionBlock *ex_block;
306         guint32 finally_start;
307         int i, j, clause_index;;
308
309         clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
310
311         clause_index = 0;
312         for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
313                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
314                 finally_start = ex_info->start + ex_info->len;
315                 if (!ex_info->handlers)
316                         continue;
317                 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
318                         ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
319                         clause = &(clauses [clause_index]);
320
321                         clause->flags = ex_block->type;
322                         clause->try_offset = ex_info->start;
323
324                         if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
325                                 clause->try_len = finally_start - ex_info->start;
326                         else
327                                 clause->try_len = ex_info->len;
328                         clause->handler_offset = ex_block->start;
329                         clause->handler_len = ex_block->len;
330                         if (ex_block->extype) {
331                                 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
332
333                                 if (!is_ok (error)) {
334                                         image_g_free (image, clauses);
335                                         return NULL;
336                                 }
337                                 clause->data.catch_class = mono_class_from_mono_type (extype);
338                         } else {
339                                 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
340                                         clause->data.filter_offset = ex_block->filter_offset;
341                                 else
342                                         clause->data.filter_offset = 0;
343                         }
344                         finally_start = ex_block->start + ex_block->len;
345
346                         clause_index ++;
347                 }
348         }
349
350         return clauses;
351 }
352 #endif /* !DISABLE_REFLECTION_EMIT */
353
354 #ifndef DISABLE_REFLECTION_EMIT
355 /*
356  * LOCKING: Acquires the loader lock. 
357  */
358 static void
359 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
360 {
361         MONO_REQ_GC_UNSAFE_MODE;
362
363         MonoCustomAttrInfo *ainfo, *tmp;
364
365         if (!cattrs || !mono_array_length (cattrs))
366                 return;
367
368         ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
369
370         mono_loader_lock ();
371         tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
372         if (tmp)
373                 mono_custom_attrs_free (tmp);
374         mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
375         mono_loader_unlock ();
376
377 }
378 #else
379 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
380 static void
381 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
382 {
383 }
384 #endif
385
386 guint32
387 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
388 {
389         MONO_REQ_GC_UNSAFE_MODE;
390
391         MonoDynamicTable *table;
392         guint32 token;
393         guint32 *values;
394         guint32 cols [MONO_ASSEMBLY_SIZE];
395         const char *pubkey;
396         guint32 publen;
397
398         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
399                 return token;
400
401         if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
402                 table = &assembly->tables [MONO_TABLE_MODULEREF];
403                 token = table->next_idx ++;
404                 table->rows ++;
405                 alloc_table (table, table->rows);
406                 values = table->values + token * MONO_MODULEREF_SIZE;
407                 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
408
409                 token <<= MONO_RESOLUTION_SCOPE_BITS;
410                 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
411                 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
412
413                 return token;
414         }
415         
416         if (assembly_is_dynamic (image->assembly))
417                 /* FIXME: */
418                 memset (cols, 0, sizeof (cols));
419         else {
420                 /* image->assembly->image is the manifest module */
421                 image = image->assembly->image;
422                 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
423         }
424
425         table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
426         token = table->next_idx ++;
427         table->rows ++;
428         alloc_table (table, table->rows);
429         values = table->values + token * MONO_ASSEMBLYREF_SIZE;
430         values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
431         values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
432         values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
433         values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
434         values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
435         values [MONO_ASSEMBLYREF_FLAGS] = 0;
436         values [MONO_ASSEMBLYREF_CULTURE] = 0;
437         values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
438
439         if (strcmp ("", image->assembly->aname.culture)) {
440                 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
441                                 image->assembly->aname.culture);
442         }
443
444         if ((pubkey = mono_image_get_public_key (image, &publen))) {
445                 guchar pubtoken [9];
446                 pubtoken [0] = 8;
447                 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
448                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
449         } else {
450                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
451         }
452         token <<= MONO_RESOLUTION_SCOPE_BITS;
453         token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
454         g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
455         return token;
456 }
457
458 #ifndef DISABLE_REFLECTION_EMIT
459 gboolean
460 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
461 {
462         MONO_REQ_GC_UNSAFE_MODE;
463
464         error_init (error);
465         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
466
467         rmb->ilgen = mb->ilgen;
468         rmb->rtype = (MonoReflectionType*)mb->rtype;
469         return_val_if_nok (error, FALSE);
470         rmb->parameters = mb->parameters;
471         rmb->generic_params = mb->generic_params;
472         rmb->generic_container = mb->generic_container;
473         rmb->opt_types = NULL;
474         rmb->pinfo = mb->pinfo;
475         rmb->attrs = mb->attrs;
476         rmb->iattrs = mb->iattrs;
477         rmb->call_conv = mb->call_conv;
478         rmb->code = mb->code;
479         rmb->type = mb->type;
480         rmb->name = mb->name;
481         rmb->table_idx = &mb->table_idx;
482         rmb->init_locals = mb->init_locals;
483         rmb->skip_visibility = FALSE;
484         rmb->return_modreq = mb->return_modreq;
485         rmb->return_modopt = mb->return_modopt;
486         rmb->param_modreq = mb->param_modreq;
487         rmb->param_modopt = mb->param_modopt;
488         rmb->permissions = mb->permissions;
489         rmb->mhandle = mb->mhandle;
490         rmb->nrefs = 0;
491         rmb->refs = NULL;
492
493         if (mb->dll) {
494                 rmb->charset = mb->charset;
495                 rmb->extra_flags = mb->extra_flags;
496                 rmb->native_cc = mb->native_cc;
497                 rmb->dllentry = mb->dllentry;
498                 rmb->dll = mb->dll;
499         }
500
501         return TRUE;
502 }
503
504 gboolean
505 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
506 {
507         MONO_REQ_GC_UNSAFE_MODE;
508
509         const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
510
511         error_init (error);
512
513         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
514
515         rmb->ilgen = mb->ilgen;
516         rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
517         return_val_if_nok (error, FALSE);
518         rmb->parameters = mb->parameters;
519         rmb->generic_params = NULL;
520         rmb->generic_container = NULL;
521         rmb->opt_types = NULL;
522         rmb->pinfo = mb->pinfo;
523         rmb->attrs = mb->attrs;
524         rmb->iattrs = mb->iattrs;
525         rmb->call_conv = mb->call_conv;
526         rmb->code = NULL;
527         rmb->type = mb->type;
528         rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
529         return_val_if_nok (error, FALSE);
530         rmb->table_idx = &mb->table_idx;
531         rmb->init_locals = mb->init_locals;
532         rmb->skip_visibility = FALSE;
533         rmb->return_modreq = NULL;
534         rmb->return_modopt = NULL;
535         rmb->param_modreq = mb->param_modreq;
536         rmb->param_modopt = mb->param_modopt;
537         rmb->permissions = mb->permissions;
538         rmb->mhandle = mb->mhandle;
539         rmb->nrefs = 0;
540         rmb->refs = NULL;
541
542         return TRUE;
543 }
544
545 static void
546 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
547 {
548         MONO_REQ_GC_UNSAFE_MODE;
549
550         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
551
552         rmb->ilgen = mb->ilgen;
553         rmb->rtype = mb->rtype;
554         rmb->parameters = mb->parameters;
555         rmb->generic_params = NULL;
556         rmb->generic_container = NULL;
557         rmb->opt_types = NULL;
558         rmb->pinfo = NULL;
559         rmb->attrs = mb->attrs;
560         rmb->iattrs = 0;
561         rmb->call_conv = mb->call_conv;
562         rmb->code = NULL;
563         rmb->type = (MonoObject *) mb->owner;
564         rmb->name = mb->name;
565         rmb->table_idx = NULL;
566         rmb->init_locals = mb->init_locals;
567         rmb->skip_visibility = mb->skip_visibility;
568         rmb->return_modreq = NULL;
569         rmb->return_modopt = NULL;
570         rmb->param_modreq = NULL;
571         rmb->param_modopt = NULL;
572         rmb->permissions = NULL;
573         rmb->mhandle = mb->mhandle;
574         rmb->nrefs = 0;
575         rmb->refs = NULL;
576 }       
577 #else /* DISABLE_REFLECTION_EMIT */
578 gboolean
579 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
580         g_assert_not_reached ();
581         return FALSE;
582 }
583 gboolean
584 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
585 {
586         g_assert_not_reached ();
587         return FALSE;
588 }
589 #endif /* DISABLE_REFLECTION_EMIT */
590
591 #ifndef DISABLE_REFLECTION_EMIT
592 static guint32
593 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
594 {
595         MONO_REQ_GC_NEUTRAL_MODE;
596
597         MonoDynamicTable *table;
598         guint32 *values;
599         guint32 token, pclass;
600
601         switch (parent & MONO_TYPEDEFORREF_MASK) {
602         case MONO_TYPEDEFORREF_TYPEREF:
603                 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
604                 break;
605         case MONO_TYPEDEFORREF_TYPESPEC:
606                 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
607                 break;
608         case MONO_TYPEDEFORREF_TYPEDEF:
609                 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
610                 break;
611         default:
612                 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
613                 return 0;
614         }
615         /* extract the index */
616         parent >>= MONO_TYPEDEFORREF_BITS;
617
618         table = &assembly->tables [MONO_TABLE_MEMBERREF];
619
620         if (assembly->save) {
621                 alloc_table (table, table->rows + 1);
622                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
623                 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
624                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
625                 values [MONO_MEMBERREF_SIGNATURE] = sig;
626         }
627
628         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
629         table->next_idx ++;
630
631         return token;
632 }
633
634 /*
635  * Insert a memberef row into the metadata: the token that point to the memberref
636  * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
637  * mono_image_get_fieldref_token()).
638  * The sig param is an index to an already built signature.
639  */
640 static guint32
641 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
642 {
643         MONO_REQ_GC_NEUTRAL_MODE;
644
645         guint32 parent = mono_image_typedef_or_ref (assembly, type);
646         return mono_image_add_memberef_row (assembly, parent, name, sig);
647 }
648
649
650 guint32
651 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
652 {
653         MONO_REQ_GC_NEUTRAL_MODE;
654
655         guint32 token;
656         MonoMethodSignature *sig;
657         
658         create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
659
660         if (create_typespec) {
661                 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
662                 if (token)
663                         return token;
664         } 
665
666         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
667         if (token && !create_typespec)
668                 return token;
669
670         g_assert (!method->is_inflated);
671         if (!token) {
672                 /*
673                  * A methodref signature can't contain an unmanaged calling convention.
674                  */
675                 sig = mono_metadata_signature_dup (mono_method_signature (method));
676                 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
677                         sig->call_convention = MONO_CALL_DEFAULT;
678                 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
679                         method->name,  mono_dynimage_encode_method_signature (assembly, sig));
680                 g_free (sig);
681                 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
682         }
683
684         if (create_typespec) {
685                 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
686                 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
687                 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
688
689                 if (assembly->save) {
690                         guint32 *values;
691
692                         alloc_table (table, table->rows + 1);
693                         values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
694                         values [MONO_METHODSPEC_METHOD] = token;
695                         values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
696                 }
697
698                 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
699                 table->next_idx ++;
700                 /*methodspec and memberef tokens are diferent, */
701                 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
702                 return token;
703         }
704         return token;
705 }
706
707 static guint32
708 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
709                                      const gchar *name, guint32 sig)
710 {
711         MonoDynamicTable *table;
712         guint32 token;
713         guint32 *values;
714         
715         table = &assembly->tables [MONO_TABLE_MEMBERREF];
716
717         if (assembly->save) {
718                 alloc_table (table, table->rows + 1);
719                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
720                 values [MONO_MEMBERREF_CLASS] = original;
721                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
722                 values [MONO_MEMBERREF_SIGNATURE] = sig;
723         }
724
725         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
726         table->next_idx ++;
727
728         return token;
729 }
730
731 #else /* DISABLE_REFLECTION_EMIT */
732
733 guint32
734 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
735 {
736         g_assert_not_reached ();
737         return -1;
738 }
739 #endif
740
741 static gboolean
742 is_field_on_inst (MonoClassField *field)
743 {
744         return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
745 }
746
747 #ifndef DISABLE_REFLECTION_EMIT
748 static guint32
749 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
750 {
751         MonoType *type;
752         guint32 token;
753
754         g_assert (field);
755         g_assert (field->parent);
756
757         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
758         if (token)
759                 return token;
760
761         if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
762                 int index = field - field->parent->fields;
763                 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
764         } else {
765                 type = mono_field_get_type (field);
766         }
767         token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
768                                                                                         mono_field_get_name (field),
769                                                                                         mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
770         g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
771         return token;
772 }
773
774 static guint32
775 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
776 {
777         MonoDynamicTable *table;
778         guint32 *values;
779         guint32 token, mtoken = 0, sig;
780         MonoMethodInflated *imethod;
781         MonoMethod *declaring;
782
783         table = &assembly->tables [MONO_TABLE_METHODSPEC];
784
785         g_assert (method->is_inflated);
786         imethod = (MonoMethodInflated *) method;
787         declaring = imethod->declaring;
788
789         sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
790         mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
791
792         if (!mono_method_signature (declaring)->generic_param_count)
793                 return mtoken;
794
795         switch (mono_metadata_token_table (mtoken)) {
796         case MONO_TABLE_MEMBERREF:
797                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
798                 break;
799         case MONO_TABLE_METHOD:
800                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
801                 break;
802         default:
803                 g_assert_not_reached ();
804         }
805
806         sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
807
808         if (assembly->save) {
809                 alloc_table (table, table->rows + 1);
810                 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
811                 values [MONO_METHODSPEC_METHOD] = mtoken;
812                 values [MONO_METHODSPEC_SIGNATURE] = sig;
813         }
814
815         token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
816         table->next_idx ++;
817
818         return token;
819 }
820
821 static guint32
822 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
823 {
824         MonoMethodInflated *imethod;
825         guint32 token;
826         
827         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
828         if (token)
829                 return token;
830
831         g_assert (method->is_inflated);
832         imethod = (MonoMethodInflated *) method;
833
834         if (mono_method_signature (imethod->declaring)->generic_param_count) {
835                 token = method_encode_methodspec (assembly, method);
836         } else {
837                 guint32 sig = mono_dynimage_encode_method_signature (
838                         assembly, mono_method_signature (imethod->declaring));
839                 token = mono_image_get_memberref_token (
840                         assembly, &method->klass->byval_arg, method->name, sig);
841         }
842
843         g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
844         return token;
845 }
846
847 static guint32
848 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
849 {
850         MonoMethodInflated *imethod = (MonoMethodInflated *) m;
851         guint32 sig, token;
852
853         sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
854         token = mono_image_get_memberref_token (
855                 assembly, &m->klass->byval_arg, m->name, sig);
856
857         return token;
858 }
859
860 static guint32 
861 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
862 {
863         guint32 idx;
864         MonoDynamicTable *table;
865         guint32 *values;
866
867         error_init (error);
868
869         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
870         idx = table->next_idx ++;
871         table->rows ++;
872         alloc_table (table, table->rows);
873         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
874
875         values [MONO_STAND_ALONE_SIGNATURE] =
876                 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
877         return_val_if_nok (error, 0);
878         
879         return idx;
880 }
881
882 static int
883 reflection_cc_to_file (int call_conv) {
884         switch (call_conv & 0x3) {
885         case 0:
886         case 1: return MONO_CALL_DEFAULT;
887         case 2: return MONO_CALL_VARARG;
888         default:
889                 g_assert_not_reached ();
890         }
891         return 0;
892 }
893 #endif /* !DISABLE_REFLECTION_EMIT */
894
895 struct _ArrayMethod {
896         MonoType *parent;
897         MonoMethodSignature *sig;
898         char *name;
899         guint32 token;
900 };
901
902 void
903 mono_sre_array_method_free (ArrayMethod *am)
904 {
905         g_free (am->sig);
906         g_free (am->name);
907         g_free (am);
908 }
909
910 #ifndef DISABLE_REFLECTION_EMIT
911 static guint32
912 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethodHandle m, MonoError *error)
913 {
914         MonoMethodSignature *sig = NULL;
915         char *name = NULL;
916
917         error_init (error);
918
919         MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
920         guint32 nparams = mono_array_handle_length (parameters);
921         sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
922         sig->hasthis = 1;
923         sig->sentinelpos = -1;
924         sig->call_convention = reflection_cc_to_file (MONO_HANDLE_GETVAL (m, call_conv));
925         sig->param_count = nparams;
926         MonoReflectionTypeHandle ret = MONO_HANDLE_NEW_GET (MonoReflectionType, m, ret);
927         if (!MONO_HANDLE_IS_NULL (ret)) {
928                 sig->ret = mono_reflection_type_handle_mono_type (ret, error);
929                 if (!is_ok (error))
930                         goto fail;
931         } else
932                 sig->ret = &mono_defaults.void_class->byval_arg;
933
934         MonoReflectionTypeHandle parent = MONO_HANDLE_NEW_GET (MonoReflectionType, m, parent);
935         MonoType *mtype = mono_reflection_type_handle_mono_type (parent, error);
936         if (!is_ok (error))
937                 goto fail;
938
939         for (int i = 0; i < nparams; ++i) {
940                 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
941                 if (!is_ok (error))
942                         goto fail;
943         }
944
945         MonoStringHandle mname = MONO_HANDLE_NEW_GET (MonoString, m, name);
946         name = mono_string_handle_to_utf8 (mname, error);
947         if (!is_ok (error))
948                 goto fail;
949
950         ArrayMethod *am = NULL;
951         for (GList *tmp = assembly->array_methods; tmp; tmp = tmp->next) {
952                 am = (ArrayMethod *)tmp->data;
953                 if (strcmp (name, am->name) == 0 && 
954                                 mono_metadata_type_equal (am->parent, mtype) &&
955                                 mono_metadata_signature_equal (am->sig, sig)) {
956                         g_free (name);
957                         g_free (sig);
958                         MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
959                         return am->token;
960                 }
961         }
962         am = g_new0 (ArrayMethod, 1);
963         am->name = name;
964         am->sig = sig;
965         am->parent = mtype;
966         am->token = mono_image_get_memberref_token (assembly, am->parent, name,
967                 mono_dynimage_encode_method_signature (assembly, sig));
968         assembly->array_methods = g_list_prepend (assembly->array_methods, am);
969         MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
970         return am->token;
971 fail:
972         g_free (name);
973         g_free (sig);
974         return 0;
975
976 }
977 #endif
978
979 #ifndef DISABLE_REFLECTION_EMIT
980
981 /*
982  * mono_image_insert_string:
983  * @module: module builder object
984  * @str: a string
985  *
986  * Insert @str into the user string stream of @module.
987  */
988 guint32
989 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStringHandle str, MonoError *error)
990 {
991         HANDLE_FUNCTION_ENTER ();
992         guint32 idx;
993         char buf [16];
994         char *b = buf;
995         guint32 token = 0;
996
997         MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
998         if (!assembly) {
999                 if (!mono_image_module_basic_init (ref_module, error))
1000                         goto leave;
1001
1002                 assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1003         }
1004         g_assert (assembly != NULL);
1005
1006         if (assembly->save) {
1007                 int32_t length = mono_string_length (MONO_HANDLE_RAW (str));
1008                 mono_metadata_encode_value (1 | (length * 2), b, &b);
1009                 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1010                 /* pinned */
1011                 uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, str), TRUE);
1012                 const char *p = (const char*)mono_string_chars (MONO_HANDLE_RAW (str));
1013 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1014         {
1015                 char *swapped = g_malloc (2 * length);
1016
1017                 swap_with_size (swapped, p, 2, length);
1018                 mono_image_add_stream_data (&assembly->us, swapped, length * 2);
1019                 g_free (swapped);
1020         }
1021 #else
1022                 mono_image_add_stream_data (&assembly->us, p, length * 2);
1023 #endif
1024                 mono_gchandle_free (gchandle);
1025                 mono_image_add_stream_data (&assembly->us, "", 1);
1026         } else {
1027                 idx = assembly->us.index ++;
1028         }
1029
1030         token = MONO_TOKEN_STRING | idx;
1031         mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
1032
1033 leave:
1034         HANDLE_FUNCTION_RETURN_VAL (token);
1035 }
1036
1037 static guint32
1038 create_method_token (MonoDynamicImage *assembly, MonoMethod *method, MonoArrayHandle opt_param_types, MonoError *error)
1039 {
1040         guint32 sig_token, parent;
1041
1042
1043         int nargs = mono_array_handle_length (opt_param_types);
1044         MonoMethodSignature *old = mono_method_signature (method);
1045         MonoMethodSignature *sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1046
1047         sig->hasthis = old->hasthis;
1048         sig->explicit_this = old->explicit_this;
1049         sig->call_convention = old->call_convention;
1050         sig->generic_param_count = old->generic_param_count;
1051         sig->param_count = old->param_count + nargs;
1052         sig->sentinelpos = old->param_count;
1053         sig->ret = old->ret;
1054
1055         for (int i = 0; i < old->param_count; i++)
1056                 sig->params [i] = old->params [i];
1057
1058         MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1059         for (int i = 0; i < nargs; i++) {
1060                 MONO_HANDLE_ARRAY_GETREF (rt, opt_param_types, i);
1061                 sig->params [old->param_count + i] = mono_reflection_type_handle_mono_type (rt, error);
1062                 if (!is_ok (error)) goto fail;
1063         }
1064
1065         parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1066         g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1067         parent >>= MONO_TYPEDEFORREF_BITS;
1068
1069         parent <<= MONO_MEMBERREF_PARENT_BITS;
1070         parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1071
1072         sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1073         guint32 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1074         g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1075         return token;
1076 fail:
1077         return 0;
1078 }
1079
1080 guint32
1081 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
1082 {
1083         guint32 token = 0;
1084
1085         error_init (error);
1086
1087         MonoClass *klass = mono_handle_class (obj);
1088         if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1089                 MonoReflectionMethodHandle ref_method = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1090                 MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
1091                 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types) && (mono_method_signature (method)->sentinelpos >= 0));
1092                 token = create_method_token (assembly, method, opt_param_types, error);
1093                 if (!is_ok (error))
1094                         goto fail;
1095         } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1096                 g_assert_not_reached ();
1097         } else {
1098                 g_error ("requested method token for %s\n", klass->name);
1099         }
1100
1101         mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
1102         return token;
1103 fail:
1104         g_assert (!mono_error_ok (error));
1105         return 0;
1106 }
1107
1108 /*
1109  * mono_image_create_token:
1110  * @assembly: a dynamic assembly
1111  * @obj:
1112  * @register_token: Whenever to register the token in the assembly->tokens hash. 
1113  *
1114  * Get a token to insert in the IL code stream for the given MemberInfo.
1115  * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, 
1116  * the table_idx-es were recomputed, so registering the token would overwrite an existing 
1117  * entry.
1118  */
1119 guint32
1120 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, 
1121                          gboolean create_open_instance, gboolean register_token,
1122                          MonoError *error)
1123 {
1124         HANDLE_FUNCTION_ENTER ();
1125         guint32 token = 0;
1126
1127         error_init (error);
1128
1129         MonoClass *klass = mono_handle_class (obj);
1130         MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
1131         MONO_HANDLE_ASSIGN (register_obj, obj);
1132
1133         /* Check for user defined reflection objects */
1134         /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1135         if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1136                 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1137                 goto leave;
1138         }
1139
1140         /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1141         int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
1142
1143         if (strcmp (klass->name, "RuntimeType") == 0) {
1144                 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
1145                 if (!is_ok (error))
1146                         goto leave;
1147                 MonoClass *mc = mono_class_from_mono_type (type);
1148                 token = mono_metadata_token_from_dor (
1149                         mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1150                 /* If it's a RuntimeType now, we could have registered a
1151                  * TypeBuilder for it before, so replacing is okay. */
1152                 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1153         } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1154                            strcmp (klass->name, "MonoMethod") == 0) {
1155                 MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1156                 MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
1157                 if (method->is_inflated) {
1158                         if (create_open_instance)
1159                                 token = mono_image_get_methodspec_token (assembly, method);
1160                         else
1161                                 token = mono_image_get_inflated_method_token (assembly, method);
1162                 } else if ((method->klass->image == &assembly->image) &&
1163                          !mono_class_is_ginst (method->klass)) {
1164                         static guint32 method_table_idx = 0xffffff;
1165                         if (method->klass->wastypebuilder) {
1166                                 /* we use the same token as the one that was assigned
1167                                  * to the Methodbuilder.
1168                                  * FIXME: do the equivalent for Fields.
1169                                  */
1170                                 token = method->token;
1171                                 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1172                         } else {
1173                                 /*
1174                                  * Each token should have a unique index, but the indexes are
1175                                  * assigned by managed code, so we don't know about them. An
1176                                  * easy solution is to count backwards...
1177                                  */
1178                                 method_table_idx --;
1179                                 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1180                                 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1181                         }
1182                 } else {
1183                         guint32 methodref_token = mono_image_get_methodref_token (assembly, method, create_open_instance);
1184                         /* We need to register a 'canonical' object.  The same
1185                          * MonoMethod could have been reflected via different
1186                          * classes so the MonoReflectionMethod:reftype could be
1187                          * different, and the object lookup in
1188                          * dynamic_image_register_token would assert assert. So
1189                          * we pick the MonoReflectionMethod object that has the
1190                          * reflected type as NULL (ie, take the declaring type
1191                          * of the method) */
1192                         MonoReflectionMethodHandle canonical_obj =
1193                                 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
1194                         if (!is_ok (error))
1195                                 goto leave;
1196                         MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1197                         token = methodref_token;
1198                 }
1199                 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1200         } else if (strcmp (klass->name, "MonoField") == 0) {
1201                 MonoReflectionFieldHandle f = MONO_HANDLE_CAST (MonoReflectionField, obj);
1202                 MonoClassField *field = MONO_HANDLE_GETVAL (f, field);
1203                 if ((field->parent->image == &assembly->image) && !is_field_on_inst (field)) {
1204                         static guint32 field_table_idx = 0xffffff;
1205                         field_table_idx --;
1206                         token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1207                         how_collide = MONO_DYN_IMAGE_TOK_NEW;
1208                 } else {
1209                         guint32 fieldref_token = mono_image_get_fieldref_token (assembly, field);
1210                         /* Same as methodref: get a canonical object to
1211                          * register with the token. */
1212                         MonoReflectionFieldHandle canonical_obj =
1213                                 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj), field->parent, field, error);
1214                         if (!is_ok (error))
1215                                 goto leave;
1216                         MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1217                         token = fieldref_token;
1218                 }
1219                 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1220         } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1221                 MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
1222                 /* always returns a fresh token */
1223                 guint32 array_token = mono_image_get_array_token (assembly, m, error);
1224                 if (!is_ok (error))
1225                         goto leave;
1226                 token = array_token;
1227                 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1228         } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1229                 MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
1230                 /* always returns a fresh token */
1231                 guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1232                 if (!is_ok (error))
1233                         goto leave;
1234                 token = sig_token;
1235                 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1236         } else {
1237                 g_error ("requested token for %s\n", klass->name);
1238         }
1239
1240         if (register_token)
1241                 mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
1242
1243 leave:
1244         HANDLE_FUNCTION_RETURN_VAL (token);
1245 }
1246
1247
1248 #endif
1249
1250 #ifndef DISABLE_REFLECTION_EMIT
1251
1252 static gboolean
1253 assemblybuilderaccess_can_refonlyload (guint32 access)
1254 {
1255         return (access & 0x4) != 0;
1256 }
1257
1258 static gboolean
1259 assemblybuilderaccess_can_run (guint32 access)
1260 {
1261         return (access & MonoAssemblyBuilderAccess_Run) != 0;
1262 }
1263
1264 static gboolean
1265 assemblybuilderaccess_can_save (guint32 access)
1266 {
1267         return (access & MonoAssemblyBuilderAccess_Save) != 0;
1268 }
1269
1270
1271 /*
1272  * mono_reflection_dynimage_basic_init:
1273  * @assembly: an assembly builder object
1274  *
1275  * Create the MonoImage that represents the assembly builder and setup some
1276  * of the helper hash table and the basic metadata streams.
1277  */
1278 void
1279 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1280 {
1281         MonoError error;
1282         MonoDynamicAssembly *assembly;
1283         MonoDynamicImage *image;
1284         MonoDomain *domain = mono_object_domain (assemblyb);
1285         
1286         if (assemblyb->dynamic_assembly)
1287                 return;
1288
1289         assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1290
1291         MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
1292         
1293         assembly->assembly.ref_count = 1;
1294         assembly->assembly.dynamic = TRUE;
1295         assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1296         assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1297         assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1298         if (mono_error_set_pending_exception (&error))
1299                 return;
1300         if (assemblyb->culture) {
1301                 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1302                 if (mono_error_set_pending_exception (&error))
1303                         return;
1304         } else
1305                 assembly->assembly.aname.culture = g_strdup ("");
1306
1307         if (assemblyb->version) {
1308                         char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1309                         if (mono_error_set_pending_exception (&error))
1310                                 return;
1311                         char **version = g_strsplit (vstr, ".", 4);
1312                         char **parts = version;
1313                         assembly->assembly.aname.major = atoi (*parts++);
1314                         assembly->assembly.aname.minor = atoi (*parts++);
1315                         assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1316                         assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1317
1318                         g_strfreev (version);
1319                         g_free (vstr);
1320         } else {
1321                         assembly->assembly.aname.major = 0;
1322                         assembly->assembly.aname.minor = 0;
1323                         assembly->assembly.aname.build = 0;
1324                         assembly->assembly.aname.revision = 0;
1325         }
1326
1327         assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
1328         assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
1329         assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
1330         assembly->domain = domain;
1331
1332         char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1333         if (mono_error_set_pending_exception (&error))
1334                 return;
1335         image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1336         image->initial_image = TRUE;
1337         assembly->assembly.aname.name = image->image.name;
1338         assembly->assembly.image = &image->image;
1339         if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1340                 /* -1 to correct for the trailing NULL byte */
1341                 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1342                         g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1343                 }
1344                 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);           
1345         }
1346
1347         mono_domain_assemblies_lock (domain);
1348         domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1349         mono_domain_assemblies_unlock (domain);
1350
1351         register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1352         
1353         MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
1354         
1355         mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1356 }
1357
1358 #endif /* !DISABLE_REFLECTION_EMIT */
1359
1360 #ifndef DISABLE_REFLECTION_EMIT
1361 static gpointer
1362 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1363 {
1364         return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1365 }
1366
1367 static MonoReflectionModuleBuilderHandle
1368 register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, MonoDynamicImage *module)
1369 {
1370         return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilderHandle, module, MONO_HANDLE_CAST (MonoObject, res), NULL);
1371 }
1372
1373 static gboolean
1374 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1375 {
1376         error_init (error);
1377         MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
1378         MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
1379         MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
1380         MONO_HANDLE_GET (ab, moduleb, assemblyb);
1381         if (!image) {
1382                 /*
1383                  * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1384                  * we don't know which module it belongs to, since that is only 
1385                  * determined at assembly save time.
1386                  */
1387                 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1388                 MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name);
1389                 char *name = mono_string_handle_to_utf8 (abname, error);
1390                 return_val_if_nok (error, FALSE);
1391                 MonoStringHandle modfqname = MONO_HANDLE_NEW_GET (MonoString, MONO_HANDLE_CAST (MonoReflectionModule, moduleb), fqname);
1392                 char *fqname = mono_string_handle_to_utf8 (modfqname, error);
1393                 if (!is_ok (error)) {
1394                         g_free (name);
1395                         return FALSE;
1396                 }
1397                 MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly);
1398                 image = mono_dynamic_image_create (dynamic_assembly, name, fqname);
1399
1400                 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image);
1401                 MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image);
1402                 register_module (domain, moduleb, image);
1403
1404                 /* register the module with the assembly */
1405                 MonoImage *ass = dynamic_assembly->assembly.image;
1406                 int module_count = ass->module_count;
1407                 MonoImage **new_modules = g_new0 (MonoImage *, module_count + 1);
1408
1409                 if (ass->modules)
1410                         memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1411                 new_modules [module_count] = &image->image;
1412                 mono_image_addref (&image->image);
1413
1414                 g_free (ass->modules);
1415                 ass->modules = new_modules;
1416                 ass->module_count ++;
1417         }
1418         return TRUE;
1419 }
1420
1421 static gboolean
1422 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1423 {
1424         error_init (error);
1425         return image_module_basic_init (moduleb, error);
1426 }
1427
1428 #endif
1429
1430 static gboolean
1431 is_corlib_type (MonoClass *klass)
1432 {
1433         return klass->image == mono_defaults.corlib;
1434 }
1435
1436 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1437         static MonoClass *cached_class; \
1438         if (cached_class) \
1439                 return cached_class == _class; \
1440         if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1441                 cached_class = _class; \
1442                 return TRUE; \
1443         } \
1444         return FALSE; \
1445 } while (0) \
1446
1447
1448 MonoType*
1449 mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
1450 {
1451         HANDLE_FUNCTION_ENTER();
1452         error_init (error);
1453         MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1454         MONO_HANDLE_ARRAY_GETREF (t, array, idx);
1455         MonoType *result = mono_reflection_type_handle_mono_type (t, error);
1456         HANDLE_FUNCTION_RETURN_VAL (result);
1457 }
1458
1459
1460 #ifndef DISABLE_REFLECTION_EMIT
1461 static gboolean
1462 is_sre_array (MonoClass *klass)
1463 {
1464         check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1465 }
1466
1467 static gboolean
1468 is_sre_byref (MonoClass *klass)
1469 {
1470         check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1471 }
1472
1473 static gboolean
1474 is_sre_pointer (MonoClass *klass)
1475 {
1476         check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1477 }
1478
1479 static gboolean
1480 is_sre_generic_instance (MonoClass *klass)
1481 {
1482         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1483 }
1484
1485 static gboolean
1486 is_sre_type_builder (MonoClass *klass)
1487 {
1488         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1489 }
1490
1491 static gboolean
1492 is_sre_method_builder (MonoClass *klass)
1493 {
1494         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1495 }
1496
1497 gboolean
1498 mono_is_sre_ctor_builder (MonoClass *klass)
1499 {
1500         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1501 }
1502
1503 static gboolean
1504 is_sre_field_builder (MonoClass *klass)
1505 {
1506         check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1507 }
1508
1509 static gboolean
1510 is_sre_gparam_builder (MonoClass *klass)
1511 {
1512         check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1513 }
1514
1515 static gboolean
1516 is_sre_enum_builder (MonoClass *klass)
1517 {
1518         check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1519 }
1520
1521 gboolean
1522 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1523 {
1524         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1525 }
1526
1527 gboolean
1528 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1529 {
1530         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1531 }
1532
1533 static MonoReflectionTypeHandle
1534 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error)
1535 {
1536         static MonoMethod *method_get_underlying_system_type = NULL;
1537         HANDLE_FUNCTION_ENTER ();
1538
1539         error_init (error);
1540
1541         if (!method_get_underlying_system_type)
1542                 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1543
1544         MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1545
1546         MonoMethod *usertype_method = mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject, t), method_get_underlying_system_type, error);
1547         if (!is_ok (error))
1548                 goto leave;
1549
1550         MONO_HANDLE_ASSIGN (rt, MONO_HANDLE_NEW (MonoReflectionType, mono_runtime_invoke_checked (usertype_method, MONO_HANDLE_RAW (t), NULL, error)));
1551
1552 leave:
1553         HANDLE_FUNCTION_RETURN_REF (MonoReflectionType, rt);
1554 }
1555
1556 MonoType*
1557 mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
1558 {
1559         HANDLE_FUNCTION_ENTER ();
1560         error_init (error);
1561         MONO_HANDLE_DCL (MonoReflectionType, ref);
1562         MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
1563         HANDLE_FUNCTION_RETURN_VAL (result);
1564 }
1565
1566 static MonoType*
1567 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass, MonoError *error)
1568 {
1569         HANDLE_FUNCTION_ENTER ();
1570         MonoType *result = NULL;
1571         MonoType **types = NULL;
1572
1573         MonoArrayHandle typeargs = MONO_HANDLE_NEW_GET (MonoArray, ref_gclass, type_arguments);
1574         int count = mono_array_handle_length (typeargs);
1575         types = g_new0 (MonoType*, count);
1576         MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1577         for (int i = 0; i < count; ++i) {
1578                 MONO_HANDLE_ARRAY_GETREF (t, typeargs, i);
1579                 types [i] = mono_reflection_type_handle_mono_type (t, error);
1580                 if (!types[i] || !is_ok (error)) {
1581                         goto leave;
1582                 }
1583         }
1584         /* Need to resolve the generic_type in order for it to create its generic context. */
1585         MonoReflectionTypeHandle ref_gtd = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_gclass, generic_type);
1586         MonoType *gtd = mono_reflection_type_handle_mono_type (ref_gtd, error);
1587         if (!is_ok (error)) {
1588                 goto leave;
1589         }
1590         MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
1591         if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
1592                 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
1593                 if (!is_ok (error)) {
1594                         goto leave;
1595                 }
1596         }
1597         g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1598         result = mono_reflection_bind_generic_parameters (ref_gtd, count, types, error);
1599         if (!is_ok (error))
1600                 goto leave;
1601         g_assert (result);
1602         MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gclass), type, MonoType*, result);
1603 leave:
1604         g_free (types);
1605         HANDLE_FUNCTION_RETURN_VAL (result);
1606 }
1607
1608 static MonoType*
1609 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
1610 {
1611         HANDLE_FUNCTION_ENTER ();
1612         error_init (error);
1613         MonoType *result = NULL;
1614
1615
1616         MonoReflectionTypeBuilderHandle ref_tbuilder = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_gparam, tbuilder);
1617         MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tbuilder, module);
1618         MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1619         MonoImage *image = &dynamic_image->image;
1620
1621         MonoGenericParamFull *param = mono_image_new0 (image, MonoGenericParamFull, 1);
1622
1623         MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_gparam, name);
1624         param->info.name = mono_string_to_utf8_image (image, ref_name, error);
1625         mono_error_assert_ok (error);
1626         param->param.num = MONO_HANDLE_GETVAL (ref_gparam, index);
1627
1628         MonoReflectionMethodBuilderHandle ref_mbuilder = MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder, ref_gparam, mbuilder);
1629         if (!MONO_HANDLE_IS_NULL (ref_mbuilder)) {
1630                 MonoGenericContainer *generic_container = MONO_HANDLE_GETVAL (ref_mbuilder, generic_container);
1631                 if (!generic_container) {
1632                         generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1633                         generic_container->is_method = TRUE;
1634                         /*
1635                          * Cannot set owner.method, since the MonoMethod is not created yet.
1636                          * Set the image field instead, so type_in_image () works.
1637                          */
1638                         generic_container->is_anonymous = TRUE;
1639                         generic_container->owner.image = image;
1640                         MONO_HANDLE_SETVAL (ref_mbuilder, generic_container, MonoGenericContainer*, generic_container);
1641                 }
1642                 param->param.owner = generic_container;
1643         } else {
1644                 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_tbuilder), error);
1645                 if (!is_ok (error))
1646                         goto leave;
1647                 MonoClass *owner = mono_class_from_mono_type (type);
1648                 g_assert (mono_class_is_gtd (owner));
1649                 param->param.owner = mono_class_get_generic_container (owner);
1650         }
1651
1652         MonoClass *pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1653
1654         result = &pklass->byval_arg;
1655
1656         mono_class_set_ref_info (pklass, MONO_HANDLE_CAST (MonoObject, ref_gparam));
1657         mono_image_append_class_to_reflection_info_set (pklass);
1658
1659         MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), type, MonoType*, result);
1660
1661 leave:
1662         HANDLE_FUNCTION_RETURN_VAL (result);
1663 }
1664
1665 static MonoType*
1666 mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
1667 {
1668         HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1669         error_init (error);
1670         MONO_HANDLE_DCL (MonoArray, array);
1671         MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
1672         HANDLE_FUNCTION_RETURN_VAL (result);
1673 }
1674
1675 MonoType*
1676 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
1677 {
1678         HANDLE_FUNCTION_ENTER ();
1679         error_init (error);
1680
1681         MonoType* result = NULL;
1682
1683         g_assert (ref);
1684         if (MONO_HANDLE_IS_NULL (ref))
1685                 goto leave;
1686         MonoType *t = MONO_HANDLE_GETVAL (ref, type);
1687         if (t) {
1688                 result = t;
1689                 goto leave;
1690         }
1691
1692         if (mono_reflection_is_usertype (ref)) {
1693                 MONO_HANDLE_ASSIGN (ref, mono_reflection_type_get_underlying_system_type (ref, error));
1694                 if (!is_ok (error) || MONO_HANDLE_IS_NULL (ref) || mono_reflection_is_usertype (ref))
1695                         goto leave;
1696                 t = MONO_HANDLE_GETVAL (ref, type);
1697                 if (t) {
1698                         result = t;
1699                         goto leave;
1700                 }
1701         }
1702
1703         MonoClass *klass = mono_handle_class (ref);
1704
1705         if (is_sre_array (klass)) {
1706                 MonoReflectionArrayTypeHandle sre_array = MONO_HANDLE_CAST (MonoReflectionArrayType, ref);
1707                 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_array, element_type);
1708                 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1709                 if (!is_ok (error))
1710                         goto leave;
1711                 g_assert (base);
1712                 gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
1713                 MonoClass *eclass = mono_class_from_mono_type (base);
1714                 result = mono_image_new0 (eclass->image, MonoType, 1);
1715                 if (rank == 0)  {
1716                         result->type = MONO_TYPE_SZARRAY;
1717                         result->data.klass = eclass;
1718                 } else {
1719                         MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
1720                         result->type = MONO_TYPE_ARRAY;
1721                         result->data.array = at;
1722                         at->eklass = eclass;
1723                         at->rank = rank;
1724                 }
1725                 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1726         } else if (is_sre_byref (klass)) {
1727                 MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1728                 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_byref, element_type);
1729                 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1730                 if (!is_ok (error))
1731                         goto leave;
1732                 g_assert (base);
1733                 result = &mono_class_from_mono_type (base)->this_arg;
1734                 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1735         } else if (is_sre_pointer (klass)) {
1736                 MonoReflectionDerivedTypeHandle sre_pointer = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1737                 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_pointer, element_type);
1738                 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1739                 if (!is_ok (error))
1740                         goto leave;
1741                 g_assert (base);
1742                 result = &mono_ptr_class_get (base)->byval_arg;
1743                 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1744         } else if (is_sre_generic_instance (klass)) {
1745                 result = reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass, ref), error);
1746         } else if (is_sre_gparam_builder (klass)) {
1747                 result = reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam, ref), error);
1748         } else if (is_sre_enum_builder (klass)) {
1749                 MonoReflectionEnumBuilderHandle ref_ebuilder = MONO_HANDLE_CAST (MonoReflectionEnumBuilder, ref);
1750
1751                 MonoReflectionTypeHandle ref_tb = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_ebuilder, tb);
1752                 result = mono_reflection_type_handle_mono_type (ref_tb, error);
1753         } else if (is_sre_type_builder (klass)) {
1754                 MonoReflectionTypeBuilderHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref);
1755
1756                 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1757                 reflection_setup_internal_class (ref_tb, error);
1758                 mono_error_assert_ok (error);
1759                 result = MONO_HANDLE_GETVAL (ref, type);
1760         } else {
1761                 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1762         }
1763 leave:
1764         HANDLE_FUNCTION_RETURN_VAL (result);
1765 }
1766
1767 /**
1768  * LOCKING: Assumes the loader lock is held.
1769  */
1770 static MonoMethodSignature*
1771 parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError *error) {
1772         MonoMethodSignature *sig;
1773         int count, i;
1774
1775         error_init (error);
1776
1777         count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
1778
1779         sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1780         sig->param_count = count;
1781         sig->sentinelpos = -1; /* FIXME */
1782         for (i = 0; i < count; ++i) {
1783                 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1784                 if (!is_ok (error)) {
1785                         image_g_free (image, sig);
1786                         return NULL;
1787                 }
1788         }
1789         return sig;
1790 }
1791
1792 /**
1793  * LOCKING: Assumes the loader lock is held.
1794  */
1795 static MonoMethodSignature*
1796 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
1797         MonoMethodSignature *sig;
1798
1799         error_init (error);
1800
1801         sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
1802         return_val_if_nok (error, NULL);
1803         sig->hasthis = MONO_HANDLE_GETVAL (ctor, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1804         sig->ret = &mono_defaults.void_class->byval_arg;
1805         return sig;
1806 }
1807
1808 static MonoMethodSignature*
1809 ctor_builder_to_signature_raw (MonoImage *image, MonoReflectionCtorBuilder* ctor_raw, MonoError *error) {
1810         HANDLE_FUNCTION_ENTER();
1811         MONO_HANDLE_DCL (MonoReflectionCtorBuilder, ctor);
1812         MonoMethodSignature *sig = ctor_builder_to_signature (image, ctor, error);
1813         HANDLE_FUNCTION_RETURN_VAL (sig);
1814 }
1815 /**
1816  * LOCKING: Assumes the loader lock is held.
1817  */
1818 static MonoMethodSignature*
1819 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error) {
1820         MonoMethodSignature *sig;
1821
1822         error_init (error);
1823
1824         sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, method, parameters), error);
1825         return_val_if_nok (error, NULL);
1826         sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1827         MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1828         if (!MONO_HANDLE_IS_NULL (rtype)) {
1829                 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1830                 if (!is_ok (error)) {
1831                         image_g_free (image, sig);
1832                         return NULL;
1833                 }
1834         } else {
1835                 sig->ret = &mono_defaults.void_class->byval_arg;
1836         }
1837         MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, method, generic_params);
1838         sig->generic_param_count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
1839         return sig;
1840 }
1841
1842 static MonoMethodSignature*
1843 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError *error) {
1844         HANDLE_FUNCTION_ENTER ();
1845         MonoMethodSignature *sig = NULL;
1846
1847         error_init (error);
1848
1849         sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
1850         if (!is_ok (error))
1851                 goto leave;
1852         sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1853         MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1854         if (!MONO_HANDLE_IS_NULL (rtype)) {
1855                 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1856                 if (!is_ok (error)) {
1857                         g_free (sig);
1858                         sig = NULL;
1859                         goto leave;
1860                 }
1861         } else {
1862                 sig->ret = &mono_defaults.void_class->byval_arg;
1863         }
1864         sig->generic_param_count = 0;
1865 leave:
1866         HANDLE_FUNCTION_RETURN_VAL (sig);
1867 }
1868
1869 static void
1870 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1871 {
1872         error_init (error);
1873         MonoClass *klass = mono_object_class (prop);
1874         if (strcmp (klass->name, "PropertyBuilder") == 0) {
1875                 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1876                 *name = mono_string_to_utf8_checked (pb->name, error);
1877                 return_if_nok (error);
1878                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1879         } else {
1880                 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1881                 *name = g_strdup (p->property->name);
1882                 if (p->property->get)
1883                         *type = mono_method_signature (p->property->get)->ret;
1884                 else
1885                         *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1886         }
1887 }
1888
1889 static void
1890 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1891 {
1892         error_init (error);
1893         MonoClass *klass = mono_object_class (field);
1894         if (strcmp (klass->name, "FieldBuilder") == 0) {
1895                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1896                 *name = mono_string_to_utf8_checked (fb->name, error);
1897                 return_if_nok (error);
1898                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1899         } else {
1900                 MonoReflectionField *f = (MonoReflectionField *)field;
1901                 *name = g_strdup (mono_field_get_name (f->field));
1902                 *type = f->field->type;
1903         }
1904 }
1905
1906 #else /* DISABLE_REFLECTION_EMIT */
1907
1908 static gboolean
1909 is_sre_type_builder (MonoClass *klass)
1910 {
1911         return FALSE;
1912 }
1913
1914 static gboolean
1915 is_sre_generic_instance (MonoClass *klass)
1916 {
1917         return FALSE;
1918 }
1919
1920 gboolean
1921 mono_is_sre_ctor_builder (MonoClass *klass)
1922 {
1923         return FALSE;
1924 }
1925
1926 gboolean
1927 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1928 {
1929         return FALSE;
1930 }
1931
1932 gboolean
1933 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1934 {
1935         return FALSE;
1936 }
1937
1938 #endif /* !DISABLE_REFLECTION_EMIT */
1939
1940
1941 static gboolean
1942 is_sr_mono_field (MonoClass *klass)
1943 {
1944         check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1945 }
1946
1947 gboolean
1948 mono_is_sr_mono_property (MonoClass *klass)
1949 {
1950         check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1951 }
1952
1953 static gboolean
1954 is_sr_mono_method (MonoClass *klass)
1955 {
1956         check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1957 }
1958
1959 gboolean
1960 mono_is_sr_mono_cmethod (MonoClass *klass)
1961 {
1962         check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1963 }
1964
1965 gboolean
1966 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1967 {
1968         return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1969 }
1970
1971 gboolean
1972 mono_is_sre_type_builder (MonoClass *klass)
1973 {
1974         return is_sre_type_builder (klass);
1975 }
1976
1977 gboolean
1978 mono_is_sre_generic_instance (MonoClass *klass)
1979 {
1980         return is_sre_generic_instance (klass);
1981 }
1982
1983
1984
1985 /**
1986  * encode_cattr_value:
1987  * Encode a value in a custom attribute stream of bytes.
1988  * The value to encode is either supplied as an object in argument val
1989  * (valuetypes are boxed), or as a pointer to the data in the
1990  * argument argval.
1991  * @type represents the type of the value
1992  * @buffer is the start of the buffer
1993  * @p the current position in the buffer
1994  * @buflen contains the size of the buffer and is used to return the new buffer size
1995  * if this needs to be realloced.
1996  * @retbuffer and @retp return the start and the position of the buffer
1997  * @error set on error.
1998  */
1999 static void
2000 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2001 {
2002         MonoTypeEnum simple_type;
2003         
2004         error_init (error);
2005         if ((p-buffer) + 10 >= *buflen) {
2006                 char *newbuf;
2007                 *buflen *= 2;
2008                 newbuf = (char *)g_realloc (buffer, *buflen);
2009                 p = newbuf + (p-buffer);
2010                 buffer = newbuf;
2011         }
2012         if (!argval)
2013                 argval = ((char*)arg + sizeof (MonoObject));
2014         simple_type = type->type;
2015 handle_enum:
2016         switch (simple_type) {
2017         case MONO_TYPE_BOOLEAN:
2018         case MONO_TYPE_U1:
2019         case MONO_TYPE_I1:
2020                 *p++ = *argval;
2021                 break;
2022         case MONO_TYPE_CHAR:
2023         case MONO_TYPE_U2:
2024         case MONO_TYPE_I2:
2025                 swap_with_size (p, argval, 2, 1);
2026                 p += 2;
2027                 break;
2028         case MONO_TYPE_U4:
2029         case MONO_TYPE_I4:
2030         case MONO_TYPE_R4:
2031                 swap_with_size (p, argval, 4, 1);
2032                 p += 4;
2033                 break;
2034         case MONO_TYPE_R8:
2035                 swap_with_size (p, argval, 8, 1);
2036                 p += 8;
2037                 break;
2038         case MONO_TYPE_U8:
2039         case MONO_TYPE_I8:
2040                 swap_with_size (p, argval, 8, 1);
2041                 p += 8;
2042                 break;
2043         case MONO_TYPE_VALUETYPE:
2044                 if (type->data.klass->enumtype) {
2045                         simple_type = mono_class_enum_basetype (type->data.klass)->type;
2046                         goto handle_enum;
2047                 } else {
2048                         g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2049                 }
2050                 break;
2051         case MONO_TYPE_STRING: {
2052                 char *str;
2053                 guint32 slen;
2054                 if (!arg) {
2055                         *p++ = 0xFF;
2056                         break;
2057                 }
2058                 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2059                 return_if_nok (error);
2060                 slen = strlen (str);
2061                 if ((p-buffer) + 10 + slen >= *buflen) {
2062                         char *newbuf;
2063                         *buflen *= 2;
2064                         *buflen += slen;
2065                         newbuf = (char *)g_realloc (buffer, *buflen);
2066                         p = newbuf + (p-buffer);
2067                         buffer = newbuf;
2068                 }
2069                 mono_metadata_encode_value (slen, p, &p);
2070                 memcpy (p, str, slen);
2071                 p += slen;
2072                 g_free (str);
2073                 break;
2074         }
2075         case MONO_TYPE_CLASS: {
2076                 char *str;
2077                 guint32 slen;
2078                 MonoType *arg_type;
2079                 if (!arg) {
2080                         *p++ = 0xFF;
2081                         break;
2082                 }
2083 handle_type:
2084                 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2085                 return_if_nok (error);
2086
2087                 str = type_get_qualified_name (arg_type, NULL);
2088                 slen = strlen (str);
2089                 if ((p-buffer) + 10 + slen >= *buflen) {
2090                         char *newbuf;
2091                         *buflen *= 2;
2092                         *buflen += slen;
2093                         newbuf = (char *)g_realloc (buffer, *buflen);
2094                         p = newbuf + (p-buffer);
2095                         buffer = newbuf;
2096                 }
2097                 mono_metadata_encode_value (slen, p, &p);
2098                 memcpy (p, str, slen);
2099                 p += slen;
2100                 g_free (str);
2101                 break;
2102         }
2103         case MONO_TYPE_SZARRAY: {
2104                 int len, i;
2105                 MonoClass *eclass, *arg_eclass;
2106
2107                 if (!arg) {
2108                         *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2109                         break;
2110                 }
2111                 len = mono_array_length ((MonoArray*)arg);
2112                 *p++ = len & 0xff;
2113                 *p++ = (len >> 8) & 0xff;
2114                 *p++ = (len >> 16) & 0xff;
2115                 *p++ = (len >> 24) & 0xff;
2116                 *retp = p;
2117                 *retbuffer = buffer;
2118                 eclass = type->data.klass;
2119                 arg_eclass = mono_object_class (arg)->element_class;
2120
2121                 if (!eclass) {
2122                         /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2123                         eclass = mono_defaults.object_class;
2124                 }
2125                 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2126                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2127                         int elsize = mono_class_array_element_size (arg_eclass);
2128                         for (i = 0; i < len; ++i) {
2129                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2130                                 return_if_nok (error);
2131                                 elptr += elsize;
2132                         }
2133                 } else if (eclass->valuetype && arg_eclass->valuetype) {
2134                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2135                         int elsize = mono_class_array_element_size (eclass);
2136                         for (i = 0; i < len; ++i) {
2137                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2138                                 return_if_nok (error);
2139                                 elptr += elsize;
2140                         }
2141                 } else {
2142                         for (i = 0; i < len; ++i) {
2143                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2144                                 return_if_nok (error);
2145                         }
2146                 }
2147                 break;
2148         }
2149         case MONO_TYPE_OBJECT: {
2150                 MonoClass *klass;
2151                 char *str;
2152                 guint32 slen;
2153
2154                 /*
2155                  * The parameter type is 'object' but the type of the actual
2156                  * argument is not. So we have to add type information to the blob
2157                  * too. This is completely undocumented in the spec.
2158                  */
2159
2160                 if (arg == NULL) {
2161                         *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
2162                         *p++ = 0xFF;
2163                         break;
2164                 }
2165                 
2166                 klass = mono_object_class (arg);
2167
2168                 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2169                         *p++ = 0x50;
2170                         goto handle_type;
2171                 } else {
2172                         return_if_nok (error);
2173                 }
2174
2175                 if (klass->enumtype) {
2176                         *p++ = 0x55;
2177                 } else if (klass == mono_defaults.string_class) {
2178                         simple_type = MONO_TYPE_STRING;
2179                         *p++ = 0x0E;
2180                         goto handle_enum;
2181                 } else if (klass->rank == 1) {
2182                         *p++ = 0x1D;
2183                         if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2184                                 /* See Partition II, Appendix B3 */
2185                                 *p++ = 0x51;
2186                         else
2187                                 *p++ = klass->element_class->byval_arg.type;
2188                         encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2189                         return_if_nok (error);
2190                         break;
2191                 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2192                         *p++ = simple_type = klass->byval_arg.type;
2193                         goto handle_enum;
2194                 } else {
2195                         g_error ("unhandled type in custom attr");
2196                 }
2197                 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2198                 slen = strlen (str);
2199                 if ((p-buffer) + 10 + slen >= *buflen) {
2200                         char *newbuf;
2201                         *buflen *= 2;
2202                         *buflen += slen;
2203                         newbuf = (char *)g_realloc (buffer, *buflen);
2204                         p = newbuf + (p-buffer);
2205                         buffer = newbuf;
2206                 }
2207                 mono_metadata_encode_value (slen, p, &p);
2208                 memcpy (p, str, slen);
2209                 p += slen;
2210                 g_free (str);
2211                 simple_type = mono_class_enum_basetype (klass)->type;
2212                 goto handle_enum;
2213         }
2214         default:
2215                 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2216         }
2217         *retp = p;
2218         *retbuffer = buffer;
2219 }
2220
2221 static void
2222 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2223 {
2224         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2225                 char *str = type_get_qualified_name (type, NULL);
2226                 int slen = strlen (str);
2227
2228                 *p++ = 0x55;
2229                 /*
2230                  * This seems to be optional...
2231                  * *p++ = 0x80;
2232                  */
2233                 mono_metadata_encode_value (slen, p, &p);
2234                 memcpy (p, str, slen);
2235                 p += slen;
2236                 g_free (str);
2237         } else if (type->type == MONO_TYPE_OBJECT) {
2238                 *p++ = 0x51;
2239         } else if (type->type == MONO_TYPE_CLASS) {
2240                 /* it should be a type: encode_cattr_value () has the check */
2241                 *p++ = 0x50;
2242         } else {
2243                 mono_metadata_encode_value (type->type, p, &p);
2244                 if (type->type == MONO_TYPE_SZARRAY)
2245                         /* See the examples in Partition VI, Annex B */
2246                         encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2247         }
2248
2249         *retp = p;
2250 }
2251
2252 #ifndef DISABLE_REFLECTION_EMIT
2253 static void
2254 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2255 {
2256         int len;
2257
2258         error_init (error);
2259
2260         /* Preallocate a large enough buffer */
2261         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2262                 char *str = type_get_qualified_name (type, NULL);
2263                 len = strlen (str);
2264                 g_free (str);
2265         } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2266                 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2267                 len = strlen (str);
2268                 g_free (str);
2269         } else {
2270                 len = 0;
2271         }
2272         len += strlen (name);
2273
2274         if ((p-buffer) + 20 + len >= *buflen) {
2275                 char *newbuf;
2276                 *buflen *= 2;
2277                 *buflen += len;
2278                 newbuf = (char *)g_realloc (buffer, *buflen);
2279                 p = newbuf + (p-buffer);
2280                 buffer = newbuf;
2281         }
2282
2283         encode_field_or_prop_type (type, p, &p);
2284
2285         len = strlen (name);
2286         mono_metadata_encode_value (len, p, &p);
2287         memcpy (p, name, len);
2288         p += len;
2289         encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2290         return_if_nok (error);
2291         *retp = p;
2292         *retbuffer = buffer;
2293 }
2294
2295 /**
2296  * mono_reflection_get_custom_attrs_blob:
2297  * \param ctor custom attribute constructor
2298  * \param ctorArgs arguments o the constructor
2299  * \param properties
2300  * \param propValues
2301  * \param fields
2302  * \param fieldValues
2303  * Creates the blob of data that needs to be saved in the metadata and that represents
2304  * the custom attributed described by \p ctor, \p ctorArgs etc.
2305  * \returns a \c Byte array representing the blob of data.
2306  */
2307 MonoArray*
2308 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
2309 {
2310         MonoError error;
2311         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2312         mono_error_cleanup (&error);
2313         return result;
2314 }
2315
2316 /**
2317  * mono_reflection_get_custom_attrs_blob_checked:
2318  * \param ctor custom attribute constructor
2319  * \param ctorArgs arguments o the constructor
2320  * \param properties
2321  * \param propValues
2322  * \param fields
2323  * \param fieldValues
2324  * \param error set on error
2325  * Creates the blob of data that needs to be saved in the metadata and that represents
2326  * the custom attributed described by \p ctor, \p ctorArgs etc.
2327  * \returns a \c Byte array representing the blob of data.  On failure returns NULL and sets \p error.
2328  */
2329 MonoArray*
2330 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
2331 {
2332         MonoArray *result = NULL;
2333         MonoMethodSignature *sig;
2334         MonoObject *arg;
2335         char *buffer, *p;
2336         guint32 buflen, i;
2337
2338         error_init (error);
2339
2340         if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2341                 /* sig is freed later so allocate it in the heap */
2342                 sig = ctor_builder_to_signature_raw (NULL, (MonoReflectionCtorBuilder*)ctor, error); /* FIXME use handles */
2343                 if (!is_ok (error)) {
2344                         g_free (sig);
2345                         return NULL;
2346                 }
2347         } else {
2348                 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2349         }
2350
2351         g_assert (mono_array_length (ctorArgs) == sig->param_count);
2352         buflen = 256;
2353         p = buffer = (char *)g_malloc (buflen);
2354         /* write the prolog */
2355         *p++ = 1;
2356         *p++ = 0;
2357         for (i = 0; i < sig->param_count; ++i) {
2358                 arg = mono_array_get (ctorArgs, MonoObject*, i);
2359                 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2360                 if (!is_ok (error)) goto leave;
2361         }
2362         i = 0;
2363         if (properties)
2364                 i += mono_array_length (properties);
2365         if (fields)
2366                 i += mono_array_length (fields);
2367         *p++ = i & 0xff;
2368         *p++ = (i >> 8) & 0xff;
2369         if (properties) {
2370                 MonoObject *prop;
2371                 for (i = 0; i < mono_array_length (properties); ++i) {
2372                         MonoType *ptype;
2373                         char *pname;
2374
2375                         prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2376                         get_prop_name_and_type (prop, &pname, &ptype, error);
2377                         if (!is_ok (error)) goto leave;
2378                         *p++ = 0x54; /* PROPERTY signature */
2379                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2380                         g_free (pname);
2381                         if (!is_ok (error)) goto leave;
2382                 }
2383         }
2384
2385         if (fields) {
2386                 MonoObject *field;
2387                 for (i = 0; i < mono_array_length (fields); ++i) {
2388                         MonoType *ftype;
2389                         char *fname;
2390
2391                         field = (MonoObject *)mono_array_get (fields, gpointer, i);
2392                         get_field_name_and_type (field, &fname, &ftype, error);
2393                         if (!is_ok (error)) goto leave;
2394                         *p++ = 0x53; /* FIELD signature */
2395                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2396                         g_free (fname);
2397                         if (!is_ok (error)) goto leave;
2398                 }
2399         }
2400
2401         g_assert (p - buffer <= buflen);
2402         buflen = p - buffer;
2403         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2404         if (!is_ok (error))
2405                 goto leave;
2406         p = mono_array_addr (result, char, 0);
2407         memcpy (p, buffer, buflen);
2408 leave:
2409         g_free (buffer);
2410         if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2411                 g_free (sig);
2412         return result;
2413 }
2414
2415 static gboolean
2416 reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
2417 {
2418         error_init (error);
2419
2420         mono_loader_lock ();
2421
2422         MonoType *parent_type;
2423         MonoType *child_type;
2424         GHashTableIter iter;
2425
2426         g_hash_table_iter_init (&iter, unparented);
2427
2428         while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
2429                 MonoClass *child_class = mono_class_from_mono_type (child_type);
2430                 if (parent_type != NULL) {
2431                         MonoClass *parent_class = mono_class_from_mono_type (parent_type);
2432                         child_class->parent = NULL;
2433                         /* fool mono_class_setup_parent */
2434                         child_class->supertypes = NULL;
2435                         mono_class_setup_parent (child_class, parent_class);
2436                 } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
2437                         const char *old_n = child_class->name;
2438                         /* trick to get relative numbering right when compiling corlib */
2439                         child_class->name = "BuildingObject";
2440                         mono_class_setup_parent (child_class, mono_defaults.object_class);
2441                         child_class->name = old_n;
2442                 }
2443                 mono_class_setup_mono_type (child_class);
2444                 mono_class_setup_supertypes (child_class);
2445         }
2446
2447         mono_loader_unlock ();
2448         return is_ok (error);
2449 }
2450
2451 static gboolean
2452 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2453 {
2454         HANDLE_FUNCTION_ENTER ();
2455         error_init (error);
2456
2457         mono_loader_lock ();
2458
2459         gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
2460         if (entering_state != MonoTypeBuilderNew) {
2461                 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
2462                 goto leave;
2463         }
2464
2465         MONO_HANDLE_SETVAL (ref_tb, state, MonoTypeBuilderState, MonoTypeBuilderEntered);
2466         MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2467         GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
2468
2469         // If this type is already setup, exit. We'll fix the parenting later
2470         MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2471         if (type)
2472                 goto leave;
2473
2474         MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2475         MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
2476
2477         MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_tb, name);
2478         MonoStringHandle ref_nspace = MONO_HANDLE_NEW_GET (MonoString, ref_tb, nspace);
2479
2480         guint32 table_idx = MONO_HANDLE_GETVAL (ref_tb, table_idx);
2481         /*
2482          * The size calculation here warrants some explaining. 
2483          * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2484          * meaning we need to alloc enough space to morth a def into a gtd.
2485          */
2486         MonoClass *klass = (MonoClass *)mono_image_alloc0 (&dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2487         klass->class_kind = MONO_CLASS_DEF;
2488
2489         klass->image = &dynamic_image->image;
2490
2491         klass->inited = 1; /* we lie to the runtime */
2492         klass->name = mono_string_to_utf8_image (klass->image, ref_name, error);
2493         if (!is_ok (error))
2494                 goto leave;
2495         klass->name_space = mono_string_to_utf8_image (klass->image, ref_nspace, error);
2496         if (!is_ok (error))
2497                 goto leave;
2498         klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
2499         mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
2500         
2501         MONO_PROFILER_RAISE (class_loading, (klass));
2502
2503         klass->element_class = klass;
2504
2505         g_assert (!mono_class_has_ref_info (klass));
2506         mono_class_set_ref_info (klass, MONO_HANDLE_CAST (MonoObject, ref_tb));
2507
2508         MonoReflectionTypeHandle ref_nesting_type = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, nesting_type);
2509         /* Put into cache so mono_class_get_checked () will find it.
2510            Skip nested types as those should not be available on the global scope. */
2511         if (MONO_HANDLE_IS_NULL (ref_nesting_type))
2512                 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, table_idx);
2513
2514         /*
2515           We must register all types as we cannot rely on the name_cache hashtable since we find the class
2516           by performing a mono_class_get which does the full resolution.
2517
2518           Working around this semantics would require us to write a lot of code for no clear advantage.
2519         */
2520         mono_image_append_class_to_reflection_info_set (klass);
2521
2522         mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
2523
2524         if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2525                         (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2526                         (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2527                 klass->instance_size = sizeof (MonoObject);
2528                 klass->size_inited = 1;
2529                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2530         }
2531
2532         mono_class_setup_mono_type (klass);
2533
2534         /*
2535          * FIXME: handle interfaces.
2536          */
2537         MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
2538         MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
2539         MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
2540
2541         reflection_init_generic_class (ref_tb, error);
2542         if (!is_ok (error))
2543                 goto leave;
2544
2545         // Do here so that the search inside of the parent can see the above type that's been set.
2546         MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
2547         MonoType *parent_type = NULL;
2548         if (!MONO_HANDLE_IS_NULL (ref_parent)) {
2549                 MonoClass *parent_klass = mono_handle_class (ref_parent);
2550                 gboolean recursive_init = TRUE;
2551
2552                 if (is_sre_type_builder (parent_klass)) {
2553                         MonoTypeBuilderState parent_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
2554
2555                         if (parent_state != MonoTypeBuilderNew) {
2556                                 // Initialize types reachable from parent recursively
2557                                 // We'll fix the type hierarchy later
2558                                 recursive_init = FALSE;
2559                         }
2560                 }
2561
2562                 if (recursive_init) {
2563                         // If we haven't encountered a cycle, force the creation of ref_parent's type
2564                         mono_reflection_type_handle_mono_type (ref_parent, error);
2565                         if (!is_ok (error))
2566                                 goto leave;
2567                 }
2568
2569                 parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
2570
2571                 // If we failed to create the parent, fail the child
2572                 if (!parent_type)
2573                         goto leave;
2574         }
2575
2576         // Push the child type and parent type to process later
2577         // Note: parent_type may be null.
2578         g_assert (!g_hash_table_lookup (unparented_classes, &klass->byval_arg));
2579         g_hash_table_insert (unparented_classes, &klass->byval_arg, parent_type);
2580
2581         if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
2582                 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
2583                         goto leave;
2584
2585                 MonoType *nesting_type = mono_reflection_type_handle_mono_type (ref_nesting_type, error);
2586                 if (!is_ok (error))
2587                         goto leave;
2588                 klass->nested_in = mono_class_from_mono_type (nesting_type);
2589         }
2590
2591         /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2592
2593         MONO_PROFILER_RAISE (class_loaded, (klass));
2594         
2595 leave:
2596         mono_loader_unlock ();
2597         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2598 }
2599
2600 /**
2601  * reflection_init_generic_class:
2602  * @tb: a TypeBuilder object
2603  * @error: set on error
2604  *
2605  * Creates the generic class after all generic parameters have been added.
2606  * On success returns TRUE, on failure returns FALSE and sets @error.
2607  *
2608  * This assumes that reflection_setup_internal_class has already set up
2609  * ref_tb
2610  */
2611 static gboolean
2612 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2613 {
2614         HANDLE_FUNCTION_ENTER ();
2615
2616         error_init (error);
2617
2618         MonoTypeBuilderState ref_state = MONO_HANDLE_GETVAL (ref_tb, state);
2619         g_assert (ref_state == MonoTypeBuilderFinished);
2620
2621         MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2622         MonoClass *klass = mono_class_from_mono_type (type);
2623
2624         MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
2625         int count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
2626
2627         if (count == 0)
2628                 goto leave;
2629
2630         if (mono_class_try_get_generic_container (klass) != NULL)
2631                 goto leave; /* already setup */
2632
2633         MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2634
2635         generic_container->owner.klass = klass;
2636         generic_container->type_argc = count;
2637         generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2638
2639         klass->class_kind = MONO_CLASS_GTD;
2640         mono_class_set_generic_container (klass, generic_container);
2641
2642
2643         MonoReflectionGenericParamHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionGenericParam, NULL);
2644         for (int i = 0; i < count; i++) {
2645                 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
2646                 MonoType *param_type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), error);
2647                 if (!is_ok (error))
2648                         goto leave;
2649                 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2650                 generic_container->type_params [i] = *param;
2651                 /*Make sure we are a diferent type instance */
2652                 generic_container->type_params [i].param.owner = generic_container;
2653                 generic_container->type_params [i].info.pklass = NULL;
2654                 generic_container->type_params [i].info.flags = MONO_HANDLE_GETVAL (ref_gparam, attrs);
2655
2656                 g_assert (generic_container->type_params [i].param.owner);
2657         }
2658
2659         generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2660         MonoGenericContext* context = &generic_container->context;
2661         MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
2662         canonical_inst->type = MONO_TYPE_GENERICINST;
2663         canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
2664
2665 leave:
2666         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2667 }
2668
2669 static MonoMarshalSpec*
2670 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2671                                 MonoReflectionMarshal *minfo, MonoError *error)
2672 {
2673         MonoMarshalSpec *res;
2674
2675         error_init (error);
2676
2677         res = image_g_new0 (image, MonoMarshalSpec, 1);
2678         res->native = (MonoMarshalNative)minfo->type;
2679
2680         switch (minfo->type) {
2681         case MONO_NATIVE_LPARRAY:
2682                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2683                 if (minfo->has_size) {
2684                         res->data.array_data.param_num = minfo->param_num;
2685                         res->data.array_data.num_elem = minfo->count;
2686                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2687                 }
2688                 else {
2689                         res->data.array_data.param_num = -1;
2690                         res->data.array_data.num_elem = -1;
2691                         res->data.array_data.elem_mult = -1;
2692                 }
2693                 break;
2694
2695         case MONO_NATIVE_BYVALTSTR:
2696         case MONO_NATIVE_BYVALARRAY:
2697                 res->data.array_data.num_elem = minfo->count;
2698                 break;
2699
2700         case MONO_NATIVE_CUSTOM:
2701                 if (minfo->marshaltyperef) {
2702                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2703                         if (!is_ok (error)) {
2704                                 image_g_free (image, res);
2705                                 return NULL;
2706                         }
2707                         res->data.custom_data.custom_name =
2708                                 type_get_fully_qualified_name (marshaltyperef);
2709                 }
2710                 if (minfo->mcookie) {
2711                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2712                         if (!is_ok (error)) {
2713                                 image_g_free (image, res);
2714                                 return NULL;
2715                         }
2716                 }
2717                 break;
2718
2719         default:
2720                 break;
2721         }
2722
2723         return res;
2724 }
2725 #endif /* !DISABLE_REFLECTION_EMIT */
2726
2727 MonoReflectionMarshalAsAttributeHandle
2728 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2729                                                         MonoMarshalSpec *spec, MonoError *error)
2730 {
2731         error_init (error);
2732         
2733         MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
2734         if (!is_ok (error))
2735                 goto fail;
2736         guint32 utype = spec->native;
2737         MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2738
2739         switch (utype) {
2740         case MONO_NATIVE_LPARRAY:
2741                 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2742                 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2743                 if (spec->data.array_data.param_num != -1)
2744                         MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2745                 break;
2746
2747         case MONO_NATIVE_BYVALTSTR:
2748         case MONO_NATIVE_BYVALARRAY:
2749                 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2750                 break;
2751
2752         case MONO_NATIVE_CUSTOM:
2753                 if (spec->data.custom_data.custom_name) {
2754                         MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2755                         if (!is_ok (error))
2756                                 goto fail;
2757
2758                         if (mtype) {
2759                                 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2760                                 if (!is_ok (error))
2761                                         goto fail;
2762
2763                                 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2764                         }
2765
2766                         MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2767                         if (!is_ok (error))
2768                                 goto fail;
2769                         MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2770                 }
2771                 if (spec->data.custom_data.cookie) {
2772                         MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2773                         if (!is_ok (error))
2774                                 goto fail;
2775                         MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2776                 }
2777                 break;
2778
2779         default:
2780                 break;
2781         }
2782
2783         return minfo;
2784 fail:
2785         return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
2786 }
2787
2788 #ifndef DISABLE_REFLECTION_EMIT
2789 static MonoMethod*
2790 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2791                                          ReflectionMethodBuilder *rmb,
2792                                          MonoMethodSignature *sig,
2793                                          MonoError *error)
2794 {
2795         MonoMethod *m;
2796         MonoMethodWrapper *wrapperm;
2797         MonoMarshalSpec **specs;
2798         MonoReflectionMethodAux *method_aux;
2799         MonoImage *image;
2800         gboolean dynamic;
2801         int i;
2802
2803         error_init (error);
2804         /*
2805          * Methods created using a MethodBuilder should have their memory allocated
2806          * inside the image mempool, while dynamic methods should have their memory
2807          * malloc'd.
2808          */
2809         dynamic = rmb->refs != NULL;
2810         image = dynamic ? NULL : klass->image;
2811
2812         if (!dynamic)
2813                 g_assert (!mono_class_is_ginst (klass));
2814
2815         mono_loader_lock ();
2816
2817         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2818                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2819                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2820         else
2821                 m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
2822
2823         wrapperm = (MonoMethodWrapper*)m;
2824
2825         m->dynamic = dynamic;
2826         m->slot = -1;
2827         m->flags = rmb->attrs;
2828         m->iflags = rmb->iattrs;
2829         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2830         m->klass = klass;
2831         m->signature = sig;
2832         m->sre_method = TRUE;
2833         m->skip_visibility = rmb->skip_visibility;
2834         if (rmb->table_idx)
2835                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2836
2837         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2838                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2839                         m->string_ctor = 1;
2840
2841                 m->signature->pinvoke = 1;
2842         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2843                 m->signature->pinvoke = 1;
2844
2845                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2846
2847                 method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
2848                 mono_error_assert_ok (error);
2849                 method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
2850                 mono_error_assert_ok (error);
2851                 
2852                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2853
2854                 if (image_is_dynamic (klass->image))
2855                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2856
2857                 mono_loader_unlock ();
2858
2859                 return m;
2860         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2861                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2862                 MonoMethodHeader *header;
2863                 guint32 code_size;
2864                 gint32 max_stack, i;
2865                 gint32 num_locals = 0;
2866                 gint32 num_clauses = 0;
2867                 guint8 *code;
2868
2869                 if (rmb->ilgen) {
2870                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2871                         code_size = rmb->ilgen->code_len;
2872                         max_stack = rmb->ilgen->max_stack;
2873                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2874                         if (rmb->ilgen->ex_handlers)
2875                                 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2876                 } else {
2877                         if (rmb->code) {
2878                                 code = mono_array_addr (rmb->code, guint8, 0);
2879                                 code_size = mono_array_length (rmb->code);
2880                                 /* we probably need to run a verifier on the code... */
2881                                 max_stack = 8; 
2882                         }
2883                         else {
2884                                 code = NULL;
2885                                 code_size = 0;
2886                                 max_stack = 8;
2887                         }
2888                 }
2889
2890                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2891                 header->code_size = code_size;
2892                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2893                 memcpy ((char*)header->code, code, code_size);
2894                 header->max_stack = max_stack;
2895                 header->init_locals = rmb->init_locals;
2896                 header->num_locals = num_locals;
2897
2898                 for (i = 0; i < num_locals; ++i) {
2899                         MonoReflectionLocalBuilder *lb = 
2900                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2901
2902                         header->locals [i] = image_g_new0 (image, MonoType, 1);
2903                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2904                         mono_error_assert_ok (error);
2905                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2906                 }
2907
2908                 header->num_clauses = num_clauses;
2909                 if (num_clauses) {
2910                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2911                                                                  rmb->ilgen, num_clauses, error);
2912                         mono_error_assert_ok (error);
2913                 }
2914
2915                 wrapperm->header = header;
2916                 MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
2917                 dm->assembly = klass->image->assembly;
2918         }
2919
2920         if (rmb->generic_params) {
2921                 int count = mono_array_length (rmb->generic_params);
2922                 MonoGenericContainer *container;
2923
2924                 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2925                 container->is_method = TRUE;
2926                 container->is_anonymous = FALSE;
2927                 container->type_argc = count;
2928                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2929                 container->owner.method = m;
2930
2931                 m->is_generic = TRUE;
2932                 mono_method_set_generic_container (m, container);
2933
2934                 for (i = 0; i < count; i++) {
2935                         MonoReflectionGenericParam *gp =
2936                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2937                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2938                         mono_error_assert_ok (error);
2939                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2940                         container->type_params [i] = *param;
2941                         container->type_params [i].param.owner = container;
2942
2943                         gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2944
2945                         MonoClass *gklass = mono_class_from_mono_type (gp_type);
2946                         gklass->wastypebuilder = TRUE;
2947                 }
2948
2949                 /*
2950                  * The method signature might have pointers to generic parameters that belong to other methods.
2951                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2952                  * generic parameters.
2953                  */
2954                 for (i = 0; i < m->signature->param_count; ++i) {
2955                         MonoType *t = m->signature->params [i];
2956                         if (t->type == MONO_TYPE_MVAR) {
2957                                 MonoGenericParam *gparam =  t->data.generic_param;
2958                                 if (gparam->num < count) {
2959                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2960                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2961                                 }
2962
2963                         }
2964                 }
2965
2966                 if (mono_class_is_gtd (klass)) {
2967                         container->parent = mono_class_get_generic_container (klass);
2968                         container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2969                 }
2970                 container->context.method_inst = mono_get_shared_generic_inst (container);
2971         }
2972
2973         if (rmb->refs) {
2974                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2975                 int i;
2976                 void **data;
2977
2978                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2979
2980                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2981                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2982                 for (i = 0; i < rmb->nrefs; ++i)
2983                         data [i + 1] = rmb->refs [i];
2984         }
2985
2986         method_aux = NULL;
2987
2988         /* Parameter info */
2989         if (rmb->pinfo) {
2990                 if (!method_aux)
2991                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2992                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2993                 for (i = 0; i <= m->signature->param_count; ++i) {
2994                         MonoReflectionParamBuilder *pb;
2995                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2996                                 if ((i > 0) && (pb->attrs)) {
2997                                         /* Make a copy since it might point to a shared type structure */
2998                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2999                                         m->signature->params [i - 1]->attrs = pb->attrs;
3000                                 }
3001
3002                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3003                                         MonoDynamicImage *assembly;
3004                                         guint32 idx, len;
3005                                         MonoTypeEnum def_type;
3006                                         char *p;
3007                                         const char *p2;
3008
3009                                         if (!method_aux->param_defaults) {
3010                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3011                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3012                                         }
3013                                         assembly = (MonoDynamicImage*)klass->image;
3014                                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3015                                         /* Copy the data from the blob since it might get realloc-ed */
3016                                         p = assembly->blob.data + idx;
3017                                         len = mono_metadata_decode_blob_size (p, &p2);
3018                                         len += p2 - p;
3019                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3020                                         method_aux->param_default_types [i] = def_type;
3021                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3022                                 }
3023
3024                                 if (pb->name) {
3025                                         method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
3026                                         mono_error_assert_ok (error);
3027                                 }
3028                                 if (pb->cattrs) {
3029                                         if (!method_aux->param_cattr)
3030                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3031                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3032                                 }
3033                         }
3034                 }
3035         }
3036
3037         /* Parameter marshalling */
3038         specs = NULL;
3039         if (rmb->pinfo)         
3040                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3041                         MonoReflectionParamBuilder *pb;
3042                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3043                                 if (pb->marshal_info) {
3044                                         if (specs == NULL)
3045                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3046                                         specs [pb->position] = 
3047                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3048                                         if (!is_ok (error)) {
3049                                                 mono_loader_unlock ();
3050                                                 image_g_free (image, specs);
3051                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3052                                                 return NULL;
3053                                         }
3054                                 }
3055                         }
3056                 }
3057         if (specs != NULL) {
3058                 if (!method_aux)
3059                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3060                 method_aux->param_marshall = specs;
3061         }
3062
3063         if (image_is_dynamic (klass->image) && method_aux)
3064                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3065
3066         mono_loader_unlock ();
3067
3068         return m;
3069 }       
3070
3071 static MonoMethod*
3072 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3073 {
3074         ReflectionMethodBuilder rmb;
3075         MonoMethodSignature *sig;
3076
3077         mono_loader_lock ();
3078
3079         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3080                 return NULL;
3081
3082         g_assert (klass->image != NULL);
3083         sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
3084         mono_loader_unlock ();
3085         return_val_if_nok (error, NULL);
3086
3087         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3088         return_val_if_nok (error, NULL);
3089         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3090
3091         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
3092                 /* ilgen is no longer needed */
3093                 mb->ilgen = NULL;
3094         }
3095
3096         return mb->mhandle;
3097 }
3098
3099 static MonoMethod*
3100 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
3101 {
3102         ReflectionMethodBuilder rmb;
3103         MonoMethodSignature *sig;
3104
3105         error_init (error);
3106
3107         mono_loader_lock ();
3108
3109         MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
3110         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3111                 return NULL;
3112
3113         g_assert (klass->image != NULL);
3114         sig = method_builder_to_signature (klass->image, ref_mb, error);
3115         mono_loader_unlock ();
3116         return_val_if_nok (error, NULL);
3117
3118         MonoMethod *method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3119         return_val_if_nok (error, NULL);
3120         MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
3121         mono_save_custom_attrs (klass->image, method, mb->cattrs);
3122
3123         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
3124                 /* ilgen is no longer needed */
3125                 mb->ilgen = NULL;
3126         return method;
3127 }
3128
3129 static MonoMethod*
3130 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
3131 {
3132         HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3133         error_init (error);
3134         MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
3135         MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
3136         HANDLE_FUNCTION_RETURN_VAL (result);
3137 }
3138
3139 #endif
3140
3141 #ifndef DISABLE_REFLECTION_EMIT
3142
3143 /**
3144  * fix_partial_generic_class:
3145  * @klass: a generic instantiation MonoClass
3146  * @error: set on error
3147  *
3148  * Assumes that the generic container of @klass has its vtable
3149  * initialized, and updates the parent class, interfaces, methods and
3150  * fields of @klass by inflating the types using the generic context.
3151  *
3152  * On success returns TRUE, on failure returns FALSE and sets @error.
3153  *
3154  */
3155 static gboolean
3156 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3157 {
3158         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3159         int i;
3160
3161         error_init (error);
3162
3163         if (klass->wastypebuilder)
3164                 return TRUE;
3165
3166         if (klass->parent != gklass->parent) {
3167                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
3168                 if (mono_error_ok (error)) {
3169                         MonoClass *parent = mono_class_from_mono_type (parent_type);
3170                         mono_metadata_free_type (parent_type);
3171                         if (parent != klass->parent) {
3172                                 /*fool mono_class_setup_parent*/
3173                                 klass->supertypes = NULL;
3174                                 mono_class_setup_parent (klass, parent);
3175                         }
3176                 } else {
3177                         if (gklass->wastypebuilder)
3178                                 klass->wastypebuilder = TRUE;
3179                         return FALSE;
3180                 }
3181         }
3182
3183         if (!mono_class_get_generic_class (klass)->need_sync)
3184                 return TRUE;
3185
3186         int mcount = mono_class_get_method_count (klass);
3187         int gmcount = mono_class_get_method_count (gklass);
3188         if (mcount != gmcount) {
3189                 mono_class_set_method_count (klass, gmcount);
3190                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
3191
3192                 for (i = 0; i < gmcount; i++) {
3193                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3194                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
3195                         mono_error_assert_ok (error);
3196                 }
3197         }
3198
3199         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3200                 klass->interface_count = gklass->interface_count;
3201                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3202                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3203
3204                 for (i = 0; i < gklass->interface_count; ++i) {
3205                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3206                         return_val_if_nok (error, FALSE);
3207
3208                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3209                         mono_metadata_free_type (iface_type);
3210
3211                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
3212                                 return FALSE;
3213                 }
3214                 klass->interfaces_inited = 1;
3215         }
3216
3217         int fcount = mono_class_get_field_count (klass);
3218         int gfcount = mono_class_get_field_count (gklass);
3219         if (fcount != gfcount) {
3220                 mono_class_set_field_count (klass, gfcount);
3221                 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3222
3223                 for (i = 0; i < gfcount; i++) {
3224                         klass->fields [i] = gklass->fields [i];
3225                         klass->fields [i].parent = klass;
3226                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3227                         return_val_if_nok (error, FALSE);
3228                 }
3229         }
3230
3231         /*We can only finish with this klass once it's parent has as well*/
3232         if (gklass->wastypebuilder)
3233                 klass->wastypebuilder = TRUE;
3234         return TRUE;
3235 }
3236
3237 /**
3238  * ensure_generic_class_runtime_vtable:
3239  * @klass a generic class
3240  * @error set on error
3241  *
3242  * Ensures that the generic container of @klass has a vtable and
3243  * returns TRUE on success.  On error returns FALSE and sets @error.
3244  */
3245 static gboolean
3246 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3247 {
3248         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3249
3250         error_init (error);
3251
3252         if (!ensure_runtime_vtable (gklass, error))
3253                 return FALSE;
3254
3255         return fix_partial_generic_class (klass, error);
3256 }
3257
3258 /**
3259  * ensure_runtime_vtable:
3260  * @klass the class
3261  * @error set on error
3262  *
3263  * Ensures that @klass has a vtable and returns TRUE on success. On
3264  * error returns FALSE and sets @error.
3265  */
3266 static gboolean
3267 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3268 {
3269         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3270         int i, num, j;
3271
3272         error_init (error);
3273
3274         if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3275                 return TRUE;
3276         if (klass->parent)
3277                 if (!ensure_runtime_vtable (klass->parent, error))
3278                         return FALSE;
3279
3280         if (tb) {
3281                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3282                 num += tb->num_methods;
3283                 mono_class_set_method_count (klass, num);
3284                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3285                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3286                 for (i = 0; i < num; ++i) {
3287                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3288                         if (!ctor)
3289                                 return FALSE;
3290                         klass->methods [i] = ctor;
3291                 }
3292                 num = tb->num_methods;
3293                 j = i;
3294                 for (i = 0; i < num; ++i) {
3295                         MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
3296                         if (!meth)
3297                                 return FALSE;
3298                         klass->methods [j++] = meth;
3299                 }
3300         
3301                 if (tb->interfaces) {
3302                         klass->interface_count = mono_array_length (tb->interfaces);
3303                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3304                         for (i = 0; i < klass->interface_count; ++i) {
3305                                 MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
3306                                 return_val_if_nok (error, FALSE);
3307                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
3308                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3309                                         return FALSE;
3310                         }
3311                         klass->interfaces_inited = 1;
3312                 }
3313         } else if (mono_class_is_ginst (klass)){
3314                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3315                         mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3316                         return FALSE;
3317                 }
3318         }
3319
3320         if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3321                 int slot_num = 0;
3322                 int mcount = mono_class_get_method_count (klass);
3323                 for (i = 0; i < mcount; ++i) {
3324                         MonoMethod *im = klass->methods [i];
3325                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3326                                 im->slot = slot_num++;
3327                 }
3328                 
3329                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3330                 mono_class_setup_interface_offsets (klass);
3331                 mono_class_setup_interface_id (klass);
3332         }
3333
3334         /*
3335          * The generic vtable is needed even if image->run is not set since some
3336          * runtime code like ves_icall_Type_GetMethodsByName depends on 
3337          * method->slot being defined.
3338          */
3339
3340         /* 
3341          * tb->methods could not be freed since it is used for determining 
3342          * overrides during dynamic vtable construction.
3343          */
3344
3345         return TRUE;
3346 }
3347
3348 static MonoMethod*
3349 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3350 {
3351         error_init (error);
3352         MonoClass *klass = mono_object_class (method);
3353         if (is_sr_mono_method (klass)) {
3354                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3355                 return sr_method->method;
3356         }
3357         if (is_sre_method_builder (klass)) {
3358                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3359                 return mb->mhandle;
3360         }
3361         if (mono_is_sre_method_on_tb_inst (klass)) {
3362                 MonoClass *handle_class;
3363
3364                 MonoMethod *result =  mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3365                 return_val_if_nok (error, NULL);
3366
3367                 return result;
3368         }
3369
3370         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3371         return NULL;
3372 }
3373
3374 void
3375 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3376 {
3377         MonoReflectionTypeBuilder *tb;
3378         int i, j, onum;
3379         MonoReflectionMethod *m;
3380
3381         error_init (error);
3382         *overrides = NULL;
3383         *num_overrides = 0;
3384
3385         g_assert (image_is_dynamic (klass->image));
3386
3387         if (!mono_class_has_ref_info (klass))
3388                 return;
3389
3390         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3391         g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
3392
3393         onum = 0;
3394         if (tb->methods) {
3395                 for (i = 0; i < tb->num_methods; ++i) {
3396                         MonoReflectionMethodBuilder *mb = 
3397                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3398                         if (mb->override_methods)
3399                                 onum += mono_array_length (mb->override_methods);
3400                 }
3401         }
3402
3403         if (onum) {
3404                 *overrides = g_new0 (MonoMethod*, onum * 2);
3405
3406                 onum = 0;
3407                 for (i = 0; i < tb->num_methods; ++i) {
3408                         MonoReflectionMethodBuilder *mb = 
3409                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3410                         if (mb->override_methods) {
3411                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3412                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3413
3414                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3415                                         return_if_nok (error);
3416                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
3417
3418                                         g_assert (mb->mhandle);
3419
3420                                         onum ++;
3421                                 }
3422                         }
3423                 }
3424         }
3425
3426         *num_overrides = onum;
3427 }
3428
3429 /* This initializes the same data as mono_class_setup_fields () */
3430 static void
3431 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3432 {
3433         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3434         MonoReflectionFieldBuilder *fb;
3435         MonoClassField *field;
3436         MonoFieldDefaultValue *def_values;
3437         MonoImage *image = klass->image;
3438         const char *p, *p2;
3439         int i, instance_size, packing_size = 0;
3440         guint32 len, idx;
3441
3442         if (klass->parent) {
3443                 if (!klass->parent->size_inited)
3444                         mono_class_init (klass->parent);
3445                 instance_size = klass->parent->instance_size;
3446         } else {
3447                 instance_size = sizeof (MonoObject);
3448         }
3449
3450         int fcount = tb->num_fields;
3451         mono_class_set_field_count (klass, fcount);
3452
3453         error_init (error);
3454
3455         if (tb->class_size) {
3456                 packing_size = tb->packing_size;
3457                 instance_size += tb->class_size;
3458         }
3459         
3460         klass->fields = image_g_new0 (image, MonoClassField, fcount);
3461         def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3462         mono_class_set_field_def_values (klass, def_values);
3463         /*
3464         This is, guess what, a hack.
3465         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3466         On the static path no field class is resolved, only types are built. This is the right thing to do
3467         but we suck.
3468         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3469         */
3470         klass->size_inited = 1;
3471
3472         for (i = 0; i < fcount; ++i) {
3473                 MonoArray *rva_data;
3474                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3475                 field = &klass->fields [i];
3476                 field->parent = klass;
3477                 field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
3478                 if (!mono_error_ok (error))
3479                         return;
3480                 if (fb->attrs) {
3481                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3482                         return_if_nok (error);
3483                         field->type = mono_metadata_type_dup (klass->image, type);
3484                         field->type->attrs = fb->attrs;
3485                 } else {
3486                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3487                         return_if_nok (error);
3488                 }
3489
3490                 if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
3491                         mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
3492                         continue;
3493                 }
3494
3495                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3496                         char *base = mono_array_addr (rva_data, char, 0);
3497                         size_t size = mono_array_length (rva_data);
3498                         char *data = (char *)mono_image_alloc (klass->image, size);
3499                         memcpy (data, base, size);
3500                         def_values [i].data = data;
3501                 }
3502                 if (fb->offset != -1)
3503                         field->offset = fb->offset;
3504                 fb->handle = field;
3505                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3506
3507                 if (fb->def_value) {
3508                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3509                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3510                         idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3511                         /* Copy the data from the blob since it might get realloc-ed */
3512                         p = assembly->blob.data + idx;
3513                         len = mono_metadata_decode_blob_size (p, &p2);
3514                         len += p2 - p;
3515                         def_values [i].data = (const char *)mono_image_alloc (image, len);
3516                         memcpy ((gpointer)def_values [i].data, p, len);
3517                 }
3518         }
3519
3520         if (!mono_class_has_failure (klass)) {
3521                 mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3522         }
3523 }
3524
3525 static void
3526 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3527 {
3528         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3529         MonoReflectionPropertyBuilder *pb;
3530         MonoImage *image = klass->image;
3531         MonoProperty *properties;
3532         MonoClassPropertyInfo *info;
3533         int i;
3534
3535         error_init (error);
3536
3537         info = mono_class_get_property_info (klass);
3538         if (!info) {
3539                 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3540                 mono_class_set_property_info (klass, info);
3541         }
3542
3543         info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3544         info->first = 0;
3545
3546         properties = image_g_new0 (image, MonoProperty, info->count);
3547         info->properties = properties;
3548         for (i = 0; i < info->count; ++i) {
3549                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3550                 properties [i].parent = klass;
3551                 properties [i].attrs = pb->attrs;
3552                 properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
3553                 if (!mono_error_ok (error))
3554                         return;
3555                 if (pb->get_method)
3556                         properties [i].get = pb->get_method->mhandle;
3557                 if (pb->set_method)
3558                         properties [i].set = pb->set_method->mhandle;
3559
3560                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3561                 if (pb->def_value) {
3562                         guint32 len, idx;
3563                         const char *p, *p2;
3564                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3565                         if (!info->def_values)
3566                                 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3567                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3568                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3569                         /* Copy the data from the blob since it might get realloc-ed */
3570                         p = assembly->blob.data + idx;
3571                         len = mono_metadata_decode_blob_size (p, &p2);
3572                         len += p2 - p;
3573                         info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3574                         memcpy ((gpointer)info->def_values [i].data, p, len);
3575                 }
3576         }
3577 }
3578
3579 static void
3580 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3581 {
3582         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3583         MonoReflectionEventBuilder *eb;
3584         MonoImage *image = klass->image;
3585         MonoEvent *events;
3586         MonoClassEventInfo *info;
3587         int i;
3588
3589         error_init (error);
3590
3591         info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3592         mono_class_set_event_info (klass, info);
3593
3594         info->count = tb->events ? mono_array_length (tb->events) : 0;
3595         info->first = 0;
3596
3597         events = image_g_new0 (image, MonoEvent, info->count);
3598         info->events = events;
3599         for (i = 0; i < info->count; ++i) {
3600                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3601                 events [i].parent = klass;
3602                 events [i].attrs = eb->attrs;
3603                 events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
3604                 if (!mono_error_ok (error))
3605                         return;
3606                 if (eb->add_method)
3607                         events [i].add = eb->add_method->mhandle;
3608                 if (eb->remove_method)
3609                         events [i].remove = eb->remove_method->mhandle;
3610                 if (eb->raise_method)
3611                         events [i].raise = eb->raise_method->mhandle;
3612
3613 #ifndef MONO_SMALL_CONFIG
3614                 if (eb->other_methods) {
3615                         int j;
3616                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3617                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3618                                 MonoReflectionMethodBuilder *mb = 
3619                                         mono_array_get (eb->other_methods,
3620                                                                         MonoReflectionMethodBuilder*, j);
3621                                 events [i].other [j] = mb->mhandle;
3622                         }
3623                 }
3624 #endif
3625                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3626         }
3627 }
3628
3629 struct remove_instantiations_user_data
3630 {
3631         MonoClass *klass;
3632         MonoError *error;
3633 };
3634
3635 static gboolean
3636 remove_instantiations_of_and_ensure_contents (gpointer key,
3637                                                   gpointer value,
3638                                                   gpointer user_data)
3639 {
3640         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3641         MonoType *type = (MonoType*)key;
3642         MonoClass *klass = data->klass;
3643         gboolean already_failed = !is_ok (data->error);
3644         MonoError lerror;
3645         MonoError *error = already_failed ? &lerror : data->error;
3646
3647         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3648                 MonoClass *inst_klass = mono_class_from_mono_type (type);
3649                 //Ensure it's safe to use it.
3650                 if (!fix_partial_generic_class (inst_klass, error)) {
3651                         mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3652                         // Marked the class with failure, but since some other instantiation already failed,
3653                         // just report that one, and swallow the error from this one.
3654                         if (already_failed)
3655                                 mono_error_cleanup (error);
3656                 }
3657                 return TRUE;
3658         } else
3659                 return FALSE;
3660 }
3661
3662 /**
3663  * reflection_setup_internal_class:
3664  * @tb: a TypeBuilder object
3665  * @error: set on error
3666  *
3667  * Creates a MonoClass that represents the TypeBuilder.
3668  * This is a trick that lets us simplify a lot of reflection code
3669  * (and will allow us to support Build and Run assemblies easier).
3670  *
3671  * Returns TRUE on success. On failure, returns FALSE and sets @error.
3672  */
3673 static gboolean
3674 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3675 {
3676         MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
3677         GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
3678
3679         if (unparented_classes) {
3680                 return reflection_setup_internal_class_internal (ref_tb, error);
3681         } else {
3682                 // If we're not being called recursively
3683                 unparented_classes = g_hash_table_new (NULL, NULL);
3684                 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
3685
3686                 gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
3687                 mono_error_assert_ok (error);
3688
3689                 // Fix the relationship between the created classes and their parents
3690                 reflection_setup_class_hierarchy (unparented_classes, error);
3691                 mono_error_assert_ok (error);
3692
3693                 g_hash_table_destroy (unparented_classes);
3694                 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
3695
3696                 return ret_val;
3697         }
3698 }
3699
3700
3701 MonoReflectionTypeHandle
3702 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3703 {
3704         error_init (error);
3705
3706         reflection_setup_internal_class (ref_tb, error);
3707         mono_error_assert_ok (error);
3708
3709         MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
3710         MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
3711         MonoClass *klass = mono_class_from_mono_type (type);
3712
3713         MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
3714         mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
3715
3716         /* 
3717          * we need to lock the domain because the lock will be taken inside
3718          * So, we need to keep the locking order correct.
3719          */
3720         mono_loader_lock ();
3721         mono_domain_lock (domain);
3722         if (klass->wastypebuilder) {
3723                 mono_domain_unlock (domain);
3724                 mono_loader_unlock ();
3725
3726                 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
3727         }
3728         /*
3729          * Fields to set in klass:
3730          * the various flags: delegate/unicode/contextbound etc.
3731          */
3732         mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
3733         klass->has_cctor = 1;
3734
3735         mono_class_setup_parent (klass, klass->parent);
3736         /* fool mono_class_setup_supertypes */
3737         klass->supertypes = NULL;
3738         mono_class_setup_supertypes (klass);
3739         mono_class_setup_mono_type (klass);
3740
3741         /* enums are done right away */
3742         if (!klass->enumtype)
3743                 if (!ensure_runtime_vtable (klass, error))
3744                         goto failure;
3745
3746         MonoArrayHandle nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
3747         if (!MONO_HANDLE_IS_NULL (nested_types)) {
3748                 GList *nested = NULL;
3749                 int num_nested = mono_array_handle_length (nested_types);
3750                 MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3751                 for (int i = 0; i < num_nested; ++i) {
3752                         MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
3753
3754                         if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
3755                                 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
3756                                 mono_error_assert_ok (error);
3757                         }
3758
3759                         MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
3760                         if (!is_ok (error)) goto failure;
3761                         nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3762                 }
3763                 mono_class_set_nested_classes_property (klass, nested);
3764         }
3765
3766         klass->nested_classes_inited = TRUE;
3767
3768         typebuilder_setup_fields (klass, error);
3769         if (!is_ok (error))
3770                 goto failure;
3771         typebuilder_setup_properties (klass, error);
3772         if (!is_ok (error))
3773                 goto failure;
3774
3775         typebuilder_setup_events (klass, error);
3776         if (!is_ok (error))
3777                 goto failure;
3778
3779         klass->wastypebuilder = TRUE;
3780
3781         MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
3782         if (!MONO_HANDLE_IS_NULL (generic_params)) {
3783                 int num_params = mono_array_handle_length (generic_params);
3784                 MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3785                 for (int i = 0; i < num_params; i++) {
3786                         MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
3787                         MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
3788                         if (!is_ok (error))
3789                                 goto failure;
3790                         MonoClass *gklass = mono_class_from_mono_type (param_type);
3791
3792                         gklass->wastypebuilder = TRUE;
3793                 }
3794         }
3795
3796         /* 
3797          * If we are a generic TypeBuilder, there might be instantiations in the type cache
3798          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
3799          * we want to return normal System.MonoType objects, so clear these out from the cache.
3800          *
3801          * Together with this we must ensure the contents of all instances to match the created type.
3802          */
3803         if (domain->type_hash && mono_class_is_gtd (klass)) {
3804                 struct remove_instantiations_user_data data;
3805                 data.klass = klass;
3806                 data.error = error;
3807                 mono_error_assert_ok (error);
3808                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3809                 if (!is_ok (error))
3810                         goto failure;
3811         }
3812
3813         mono_domain_unlock (domain);
3814         mono_loader_unlock ();
3815
3816         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3817                 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3818                 mono_error_set_type_load_class (error, klass, "Not a valid enumeration");
3819                 goto failure_unlocked;
3820         }
3821
3822         MonoReflectionTypeHandle res = mono_type_get_object_handle (domain, &klass->byval_arg, error);
3823         if (!is_ok (error))
3824                 goto failure_unlocked;
3825
3826         return res;
3827
3828 failure:
3829         mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
3830         klass->wastypebuilder = TRUE;
3831         mono_domain_unlock (domain);
3832         mono_loader_unlock ();
3833 failure_unlocked:
3834         return NULL;
3835 }
3836
3837 typedef struct {
3838         MonoMethod *handle;
3839         MonoDomain *domain;
3840 } DynamicMethodReleaseData;
3841
3842 /*
3843  * The runtime automatically clean up those after finalization.
3844 */      
3845 static MonoReferenceQueue *dynamic_method_queue;
3846
3847 static void
3848 free_dynamic_method (void *dynamic_method)
3849 {
3850         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3851         MonoDomain *domain = data->domain;
3852         MonoMethod *method = data->handle;
3853         guint32 dis_link;
3854
3855         mono_domain_lock (domain);
3856         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3857         g_hash_table_remove (domain->method_to_dyn_method, method);
3858         mono_domain_unlock (domain);
3859         g_assert (dis_link);
3860         mono_gchandle_free (dis_link);
3861
3862         mono_runtime_free_method (domain, method);
3863         g_free (data);
3864 }
3865
3866 static gboolean
3867 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
3868 {
3869         MonoReferenceQueue *queue;
3870         MonoMethod *handle;
3871         DynamicMethodReleaseData *release_data;
3872         ReflectionMethodBuilder rmb;
3873         MonoMethodSignature *sig;
3874         MonoClass *klass;
3875         MonoDomain *domain;
3876         GSList *l;
3877         int i;
3878
3879         error_init (error);
3880
3881         if (mono_runtime_is_shutting_down ()) {
3882                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3883                 return FALSE;
3884         }
3885
3886         if (!(queue = dynamic_method_queue)) {
3887                 mono_loader_lock ();
3888                 if (!(queue = dynamic_method_queue))
3889                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3890                 mono_loader_unlock ();
3891         }
3892
3893         sig = dynamic_method_to_signature (ref_mb, error);
3894         return_val_if_nok (error, FALSE);
3895
3896         MonoReflectionDynamicMethod *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
3897         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3898
3899         /*
3900          * Resolve references.
3901          */
3902         /* 
3903          * Every second entry in the refs array is reserved for storing handle_class,
3904          * which is needed by the ldtoken implementation in the JIT.
3905          */
3906         rmb.nrefs = mb->nrefs;
3907         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3908         for (i = 0; i < mb->nrefs; i += 2) {
3909                 MonoClass *handle_class;
3910                 gpointer ref;
3911                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3912
3913                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3914                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3915                         /*
3916                          * The referenced DynamicMethod should already be created by the managed
3917                          * code, except in the case of circular references. In that case, we store
3918                          * method in the refs array, and fix it up later when the referenced 
3919                          * DynamicMethod is created.
3920                          */
3921                         if (method->mhandle) {
3922                                 ref = method->mhandle;
3923                         } else {
3924                                 /* FIXME: GC object stored in unmanaged memory */
3925                                 ref = method;
3926
3927                                 /* FIXME: GC object stored in unmanaged memory */
3928                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
3929                         }
3930                         handle_class = mono_defaults.methodhandle_class;
3931                 } else {
3932                         MonoException *ex = NULL;
3933                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3934                         if (!is_ok  (error)) {
3935                                 g_free (rmb.refs);
3936                                 return FALSE;
3937                         }
3938                         if (!ref)
3939                                 ex = mono_get_exception_type_load (NULL, NULL);
3940                         else if (mono_security_core_clr_enabled ())
3941                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3942
3943                         if (ex) {
3944                                 g_free (rmb.refs);
3945                                 mono_error_set_exception_instance (error, ex);
3946                                 return FALSE;
3947                         }
3948                 }
3949
3950                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3951                 rmb.refs [i + 1] = handle_class;
3952         }               
3953
3954         MonoAssembly *ass = NULL;
3955         if (mb->owner) {
3956                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3957                 if (!is_ok (error)) {
3958                         g_free (rmb.refs);
3959                         return FALSE;
3960                 }
3961                 klass = mono_class_from_mono_type (owner_type);
3962                 ass = klass->image->assembly;
3963         } else {
3964                 klass = mono_defaults.object_class;
3965                 ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
3966         }
3967
3968         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3969         ((MonoDynamicMethod*)handle)->assembly = ass;
3970         g_free (rmb.refs);
3971         return_val_if_nok (error, FALSE);
3972
3973         release_data = g_new (DynamicMethodReleaseData, 1);
3974         release_data->handle = handle;
3975         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3976         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3977                 g_free (release_data);
3978
3979         /* Fix up refs entries pointing at us */
3980         for (l = mb->referenced_by; l; l = l->next) {
3981                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3982                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3983                 gpointer *data;
3984                 
3985                 g_assert (method->mhandle);
3986
3987                 data = (gpointer*)wrapper->method_data;
3988                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3989                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3990                                 data [i + 1] = mb->mhandle;
3991                 }
3992         }
3993         g_slist_free (mb->referenced_by);
3994
3995         /* ilgen is no longer needed */
3996         mb->ilgen = NULL;
3997
3998         domain = mono_domain_get ();
3999         mono_domain_lock (domain);
4000         if (!domain->method_to_dyn_method)
4001                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4002         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4003         mono_domain_unlock (domain);
4004
4005         return TRUE;
4006 }
4007
4008 void
4009 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4010 {
4011         (void) reflection_create_dynamic_method (mb, error);
4012 }
4013
4014 #endif /* DISABLE_REFLECTION_EMIT */
4015
4016 MonoMethodSignature *
4017 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4018 {
4019         MonoMethodSignature *sig;
4020         g_assert (image_is_dynamic (image));
4021
4022         error_init (error);
4023
4024         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4025         if (sig)
4026                 return sig;
4027
4028         return mono_method_signature_checked (method, error);
4029 }
4030
4031 #ifndef DISABLE_REFLECTION_EMIT
4032
4033 /*
4034  * ensure_complete_type:
4035  *
4036  *   Ensure that KLASS is completed if it is a dynamic type, or references
4037  * dynamic types.
4038  */
4039 static void
4040 ensure_complete_type (MonoClass *klass, MonoError *error)
4041 {
4042         error_init (error);
4043
4044         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
4045                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
4046
4047                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4048                 return_if_nok (error);
4049
4050                 // Asserting here could break a lot of code
4051                 //g_assert (klass->wastypebuilder);
4052         }
4053
4054         if (mono_class_is_ginst (klass)) {
4055                 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
4056                 int i;
4057
4058                 for (i = 0; i < inst->type_argc; ++i) {
4059                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4060                         return_if_nok (error);
4061                 }
4062         }
4063 }
4064
4065 gpointer
4066 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4067 {
4068         MonoClass *oklass = obj->vtable->klass;
4069         gpointer result = NULL;
4070
4071         error_init (error);
4072
4073         if (strcmp (oklass->name, "String") == 0) {
4074                 result = mono_string_intern_checked ((MonoString*)obj, error);
4075                 return_val_if_nok (error, NULL);
4076                 *handle_class = mono_defaults.string_class;
4077                 g_assert (result);
4078         } else if (strcmp (oklass->name, "RuntimeType") == 0) {
4079                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4080                 return_val_if_nok (error, NULL);
4081                 MonoClass *mc = mono_class_from_mono_type (type);
4082                 if (!mono_class_init (mc)) {
4083                         mono_error_set_for_class_failure (error, mc);
4084                         return NULL;
4085                 }
4086
4087                 if (context) {
4088                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4089                         return_val_if_nok (error, NULL);
4090
4091                         result = mono_class_from_mono_type (inflated);
4092                         mono_metadata_free_type (inflated);
4093                 } else {
4094                         result = mono_class_from_mono_type (type);
4095                 }
4096                 *handle_class = mono_defaults.typehandle_class;
4097                 g_assert (result);
4098         } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
4099                            strcmp (oklass->name, "MonoCMethod") == 0) {
4100                 result = ((MonoReflectionMethod*)obj)->method;
4101                 if (context) {
4102                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4103                         mono_error_assert_ok (error);
4104                 }
4105                 *handle_class = mono_defaults.methodhandle_class;
4106                 g_assert (result);
4107         } else if (strcmp (oklass->name, "MonoField") == 0) {
4108                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4109
4110                 ensure_complete_type (field->parent, error);
4111                 return_val_if_nok (error, NULL);
4112
4113                 if (context) {
4114                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
4115                         return_val_if_nok (error, NULL);
4116
4117                         MonoClass *klass = mono_class_from_mono_type (inflated);
4118                         MonoClassField *inflated_field;
4119                         gpointer iter = NULL;
4120                         mono_metadata_free_type (inflated);
4121                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
4122                                 if (!strcmp (field->name, inflated_field->name))
4123                                         break;
4124                         }
4125                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4126                         result = inflated_field;
4127                 } else {
4128                         result = field;
4129                 }
4130                 *handle_class = mono_defaults.fieldhandle_class;
4131                 g_assert (result);
4132         } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
4133                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
4134                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4135                 return_val_if_nok (error, NULL);
4136                 MonoClass *klass;
4137
4138                 klass = type->data.klass;
4139                 if (klass->wastypebuilder) {
4140                         /* Already created */
4141                         result = klass;
4142                 }
4143                 else {
4144                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4145                         return_val_if_nok (error, NULL);
4146                         result = type->data.klass;
4147                         g_assert (result);
4148                 }
4149                 *handle_class = mono_defaults.typehandle_class;
4150         } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
4151                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4152                 MonoMethodSignature *sig;
4153                 int nargs, i;
4154
4155                 if (helper->arguments)
4156                         nargs = mono_array_length (helper->arguments);
4157                 else
4158                         nargs = 0;
4159
4160                 sig = mono_metadata_signature_alloc (image, nargs);
4161                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4162                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4163
4164                 if (helper->unmanaged_call_conv) { /* unmanaged */
4165                         sig->call_convention = helper->unmanaged_call_conv - 1;
4166                         sig->pinvoke = TRUE;
4167                 } else if (helper->call_conv & 0x02) {
4168                         sig->call_convention = MONO_CALL_VARARG;
4169                 } else {
4170                         sig->call_convention = MONO_CALL_DEFAULT;
4171                 }
4172
4173                 sig->param_count = nargs;
4174                 /* TODO: Copy type ? */
4175                 sig->ret = helper->return_type->type;
4176                 for (i = 0; i < nargs; ++i) {
4177                         sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
4178                         if (!is_ok (error)) {
4179                                 image_g_free (image, sig);
4180                                 return NULL;
4181                         }
4182                 }
4183
4184                 result = sig;
4185                 *handle_class = NULL;
4186         } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4187                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4188                 /* Already created by the managed code */
4189                 g_assert (method->mhandle);
4190                 result = method->mhandle;
4191                 *handle_class = mono_defaults.methodhandle_class;
4192         } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4193                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4194                 MonoType *mtype;
4195                 MonoClass *klass;
4196                 MonoMethod *method;
4197                 gpointer iter;
4198                 char *name;
4199
4200                 mtype = mono_reflection_type_get_handle (m->parent, error);
4201                 return_val_if_nok (error, NULL);
4202                 klass = mono_class_from_mono_type (mtype);
4203
4204                 /* Find the method */
4205
4206                 name = mono_string_to_utf8_checked (m->name, error);
4207                 return_val_if_nok (error, NULL);
4208                 iter = NULL;
4209                 while ((method = mono_class_get_methods (klass, &iter))) {
4210                         if (!strcmp (method->name, name))
4211                                 break;
4212                 }
4213                 g_free (name);
4214
4215                 // FIXME:
4216                 g_assert (method);
4217                 // FIXME: Check parameters/return value etc. match
4218
4219                 result = method;
4220                 *handle_class = mono_defaults.methodhandle_class;
4221         } else if (is_sre_method_builder (oklass) ||
4222                            mono_is_sre_ctor_builder (oklass) ||
4223                            is_sre_field_builder (oklass) ||
4224                            is_sre_gparam_builder (oklass) ||
4225                            is_sre_generic_instance (oklass) ||
4226                            is_sre_array (oklass) ||
4227                            is_sre_byref (oklass) ||
4228                            is_sre_pointer (oklass) ||
4229                            !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4230                            !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4231                            !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4232                 static MonoMethod *resolve_method;
4233                 if (!resolve_method) {
4234                         MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4235                         g_assert (m);
4236                         mono_memory_barrier ();
4237                         resolve_method = m;
4238                 }
4239                 void *args [16];
4240                 args [0] = obj;
4241                 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4242                 mono_error_assert_ok (error);
4243                 g_assert (obj);
4244                 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
4245         } else {
4246                 g_print ("%s\n", obj->vtable->klass->name);
4247                 g_assert_not_reached ();
4248         }
4249         return result;
4250 }
4251
4252 #else /* DISABLE_REFLECTION_EMIT */
4253
4254 MonoArray*
4255 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
4256 {
4257         g_assert_not_reached ();
4258         return NULL;
4259 }
4260
4261 void
4262 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4263 {
4264         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4265 }
4266
4267 static gboolean
4268 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4269 {
4270         g_assert_not_reached ();
4271         return FALSE;
4272 }
4273
4274 guint32
4275 mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4276 {
4277         g_assert_not_reached ();
4278         return 0;
4279 }
4280
4281 guint32
4282 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
4283 {
4284         g_assert_not_reached ();
4285         return 0;
4286 }
4287
4288 guint32
4289 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, 
4290                          gboolean create_open_instance, gboolean register_token, MonoError *error)
4291 {
4292         g_assert_not_reached ();
4293         return 0;
4294 }
4295
4296 void
4297 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4298 {
4299         error_init (error);
4300         *overrides = NULL;
4301         *num_overrides = 0;
4302 }
4303
4304 MonoReflectionTypeHandle
4305 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
4306 {
4307         g_assert_not_reached ();
4308         return NULL;
4309 }
4310
4311 void 
4312 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4313 {
4314         error_init (error);
4315 }
4316
4317 MonoType*
4318 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4319 {
4320         error_init (error);
4321         if (!ref)
4322                 return NULL;
4323         return ref->type;
4324 }
4325
4326 MonoType*
4327 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
4328 {
4329         error_init (error);
4330         if (MONO_HANDLE_IS_NULL (ref))
4331                 return NULL;
4332         return MONO_HANDLE_GETVAL (ref, type);
4333 }
4334
4335
4336 #endif /* DISABLE_REFLECTION_EMIT */
4337
4338 void
4339 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4340 {
4341         MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
4342         g_free (entry);
4343 }
4344
4345 gint32
4346 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
4347 {
4348         error_init (error);
4349         if (MONO_HANDLE_IS_NULL (obj)) {
4350                 mono_error_set_argument_null (error, "obj", "");
4351                 return 0;
4352         }
4353         return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
4354 }
4355
4356 gint32
4357 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
4358                                         MonoReflectionMethodHandle method,
4359                                         MonoArrayHandle opt_param_types,
4360                                         MonoError *error)
4361 {
4362         error_init (error);
4363         if (MONO_HANDLE_IS_NULL (method)) {
4364                 mono_error_set_argument_null (error, "method", "");
4365                 return 0;
4366         }
4367
4368         return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
4369 }
4370
4371 void
4372 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4373 {
4374         MonoError error;
4375         mono_image_create_pefile (mb, file, &error);
4376         mono_error_set_pending_exception (&error);
4377 }
4378
4379 void
4380 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4381 {
4382         MonoError error;
4383         mono_image_build_metadata (mb, &error);
4384         mono_error_set_pending_exception (&error);
4385 }
4386
4387 void
4388 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
4389 {
4390         error_init (error);
4391         /* This function may be called by ModuleBuilder.FixupTokens to update
4392          * an existing token, so replace is okay here. */
4393         mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
4394 }
4395
4396 MonoObjectHandle
4397 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
4398 {
4399         error_init (error);
4400         MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4401         return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
4402 }
4403
4404 #ifndef DISABLE_REFLECTION_EMIT
4405 MonoArray*
4406 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4407 {
4408         MonoError error;
4409         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4410         mono_error_set_pending_exception (&error);
4411         return result;
4412 }
4413 #endif
4414
4415 void
4416 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4417 {
4418         mono_reflection_dynimage_basic_init (assemblyb);
4419 }
4420
4421 void
4422 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
4423 {
4424         MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
4425
4426         MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
4427         MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
4428         g_assert (assembly);
4429
4430         mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
4431 }
4432
4433 void
4434 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
4435                                        MonoReflectionTypeHandle t,
4436                                        MonoError *error)
4437 {
4438         error_init (error);
4439         MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
4440 }
4441
4442 void
4443 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4444 {
4445         error_init (error);
4446         mono_image_module_basic_init (moduleb, error);
4447 }
4448
4449 guint32
4450 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4451 {
4452         return mono_image_insert_string (module, str, error);
4453 }
4454
4455 void
4456 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
4457 {
4458         error_init (error);
4459         MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
4460         MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4461
4462         g_assert (type);
4463         image->wrappers_type = mono_class_from_mono_type (type);
4464 }