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