Merge pull request #3871 from akoeplinger/mono.posix-windows
[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 (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
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 mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->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 (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
725                 int index = field - field->parent->fields;
726                 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->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, !mono_class_is_gtd (mc) || 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                          !mono_class_is_ginst (m->method->klass)) {
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 (mono_class_is_gtd (owner));
1587                         param->param.owner = mono_class_get_generic_container (owner);
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         /*
2302          * The size calculation here warrants some explaining. 
2303          * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2304          * meaning we need to alloc enough space to morth a def into a gtd.
2305          */
2306         klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2307         klass->class_kind = MONO_CLASS_DEF;
2308
2309         klass->image = &tb->module->dynamic_image->image;
2310
2311         klass->inited = 1; /* we lie to the runtime */
2312         klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
2313         if (!is_ok (error))
2314                 goto failure;
2315         klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
2316         if (!is_ok (error))
2317                 goto failure;
2318         klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
2319         mono_class_set_flags (klass, tb->attrs);
2320         
2321         mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2322
2323         klass->element_class = klass;
2324
2325         if (mono_class_get_ref_info (klass) == NULL) {
2326                 mono_class_set_ref_info (klass, tb);
2327
2328                 /* Put into cache so mono_class_get_checked () will find it.
2329                 Skip nested types as those should not be available on the global scope. */
2330                 if (!tb->nesting_type)
2331                         mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
2332
2333                 /*
2334                 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2335                 by performing a mono_class_get which does the full resolution.
2336
2337                 Working around this semantics would require us to write a lot of code for no clear advantage.
2338                 */
2339                 mono_image_append_class_to_reflection_info_set (klass);
2340         } else {
2341                 g_assert (mono_class_get_ref_info (klass) == tb);
2342         }
2343
2344         mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
2345
2346         if (parent != NULL) {
2347                 mono_class_setup_parent (klass, parent);
2348         } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
2349                 const char *old_n = klass->name;
2350                 /* trick to get relative numbering right when compiling corlib */
2351                 klass->name = "BuildingObject";
2352                 mono_class_setup_parent (klass, mono_defaults.object_class);
2353                 klass->name = old_n;
2354         }
2355
2356         if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2357                         (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2358                         (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2359                 klass->instance_size = sizeof (MonoObject);
2360                 klass->size_inited = 1;
2361                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2362         }
2363
2364         mono_class_setup_mono_type (klass);
2365
2366         mono_class_setup_supertypes (klass);
2367
2368         /*
2369          * FIXME: handle interfaces.
2370          */
2371
2372         tb->type.type = &klass->byval_arg;
2373
2374         if (tb->nesting_type) {
2375                 reflection_setup_internal_class ((MonoReflectionTypeBuilder*)tb->nesting_type, error);
2376                 g_assert (tb->nesting_type->type);
2377                 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
2378                 if (!is_ok (error)) goto failure;
2379                 klass->nested_in = mono_class_from_mono_type (nesting_type);
2380         }
2381
2382         /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2383
2384         mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
2385         
2386         mono_loader_unlock ();
2387         return TRUE;
2388
2389 failure:
2390         mono_loader_unlock ();
2391         return FALSE;
2392 }
2393
2394 /**
2395  * reflection_create_generic_class:
2396  * @tb: a TypeBuilder object
2397  * @error: set on error
2398  *
2399  * Creates the generic class after all generic parameters have been added.
2400  * On success returns TRUE, on failure returns FALSE and sets @error.
2401  */
2402 static gboolean
2403 reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2404 {
2405         MonoClass *klass;
2406         int count, i;
2407
2408         mono_error_init (error);
2409
2410         reflection_setup_internal_class (tb, error);
2411
2412         klass = mono_class_from_mono_type (tb->type.type);
2413
2414         count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
2415
2416         if (count == 0)
2417                 return TRUE;
2418
2419         MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2420
2421         generic_container->owner.klass = klass;
2422         generic_container->type_argc = count;
2423         generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2424
2425         klass->class_kind = MONO_CLASS_GTD;
2426         mono_class_set_generic_container (klass, generic_container);
2427
2428
2429         for (i = 0; i < count; i++) {
2430                 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
2431                 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
2432                 return_val_if_nok (error, FALSE);
2433                 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2434                 generic_container->type_params [i] = *param;
2435                 /*Make sure we are a diferent type instance */
2436                 generic_container->type_params [i].param.owner = generic_container;
2437                 generic_container->type_params [i].info.pklass = NULL;
2438                 generic_container->type_params [i].info.flags = gparam->attrs;
2439
2440                 g_assert (generic_container->type_params [i].param.owner);
2441         }
2442
2443         generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2444         return TRUE;
2445 }
2446
2447 static MonoMarshalSpec*
2448 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2449                                 MonoReflectionMarshal *minfo, MonoError *error)
2450 {
2451         MonoMarshalSpec *res;
2452
2453         mono_error_init (error);
2454
2455         res = image_g_new0 (image, MonoMarshalSpec, 1);
2456         res->native = (MonoMarshalNative)minfo->type;
2457
2458         switch (minfo->type) {
2459         case MONO_NATIVE_LPARRAY:
2460                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2461                 if (minfo->has_size) {
2462                         res->data.array_data.param_num = minfo->param_num;
2463                         res->data.array_data.num_elem = minfo->count;
2464                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2465                 }
2466                 else {
2467                         res->data.array_data.param_num = -1;
2468                         res->data.array_data.num_elem = -1;
2469                         res->data.array_data.elem_mult = -1;
2470                 }
2471                 break;
2472
2473         case MONO_NATIVE_BYVALTSTR:
2474         case MONO_NATIVE_BYVALARRAY:
2475                 res->data.array_data.num_elem = minfo->count;
2476                 break;
2477
2478         case MONO_NATIVE_CUSTOM:
2479                 if (minfo->marshaltyperef) {
2480                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2481                         if (!is_ok (error)) {
2482                                 image_g_free (image, res);
2483                                 return NULL;
2484                         }
2485                         res->data.custom_data.custom_name =
2486                                 type_get_fully_qualified_name (marshaltyperef);
2487                 }
2488                 if (minfo->mcookie) {
2489                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2490                         if (!is_ok (error)) {
2491                                 image_g_free (image, res);
2492                                 return NULL;
2493                         }
2494                 }
2495                 break;
2496
2497         default:
2498                 break;
2499         }
2500
2501         return res;
2502 }
2503 #endif /* !DISABLE_REFLECTION_EMIT */
2504
2505 MonoReflectionMarshalAsAttribute*
2506 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2507                                                         MonoMarshalSpec *spec, MonoError *error)
2508 {
2509         MonoReflectionType *rt;
2510         MonoReflectionMarshalAsAttribute *minfo;
2511         MonoType *mtype;
2512
2513         mono_error_init (error);
2514         
2515         minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
2516         if (!minfo)
2517                 return NULL;
2518         minfo->utype = spec->native;
2519
2520         switch (minfo->utype) {
2521         case MONO_NATIVE_LPARRAY:
2522                 minfo->array_subtype = spec->data.array_data.elem_type;
2523                 minfo->size_const = spec->data.array_data.num_elem;
2524                 if (spec->data.array_data.param_num != -1)
2525                         minfo->size_param_index = spec->data.array_data.param_num;
2526                 break;
2527
2528         case MONO_NATIVE_BYVALTSTR:
2529         case MONO_NATIVE_BYVALARRAY:
2530                 minfo->size_const = spec->data.array_data.num_elem;
2531                 break;
2532
2533         case MONO_NATIVE_CUSTOM:
2534                 if (spec->data.custom_data.custom_name) {
2535                         mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2536                         return_val_if_nok  (error, NULL);
2537
2538                         if (mtype) {
2539                                 rt = mono_type_get_object_checked (domain, mtype, error);
2540                                 if (!rt)
2541                                         return NULL;
2542
2543                                 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
2544                         }
2545
2546                         MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
2547                 }
2548                 if (spec->data.custom_data.cookie)
2549                         MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
2550                 break;
2551
2552         default:
2553                 break;
2554         }
2555
2556         return minfo;
2557 }
2558
2559 #ifndef DISABLE_REFLECTION_EMIT
2560 static MonoMethod*
2561 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2562                                          ReflectionMethodBuilder *rmb,
2563                                          MonoMethodSignature *sig,
2564                                          MonoError *error)
2565 {
2566         MonoMethod *m;
2567         MonoMethodWrapper *wrapperm;
2568         MonoMarshalSpec **specs;
2569         MonoReflectionMethodAux *method_aux;
2570         MonoImage *image;
2571         gboolean dynamic;
2572         int i;
2573
2574         mono_error_init (error);
2575         /*
2576          * Methods created using a MethodBuilder should have their memory allocated
2577          * inside the image mempool, while dynamic methods should have their memory
2578          * malloc'd.
2579          */
2580         dynamic = rmb->refs != NULL;
2581         image = dynamic ? NULL : klass->image;
2582
2583         if (!dynamic)
2584                 g_assert (!mono_class_is_ginst (klass));
2585
2586         mono_loader_lock ();
2587
2588         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2589                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2590                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2591         else
2592                 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
2593
2594         wrapperm = (MonoMethodWrapper*)m;
2595
2596         m->dynamic = dynamic;
2597         m->slot = -1;
2598         m->flags = rmb->attrs;
2599         m->iflags = rmb->iattrs;
2600         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2601         m->klass = klass;
2602         m->signature = sig;
2603         m->sre_method = TRUE;
2604         m->skip_visibility = rmb->skip_visibility;
2605         if (rmb->table_idx)
2606                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2607
2608         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2609                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2610                         m->string_ctor = 1;
2611
2612                 m->signature->pinvoke = 1;
2613         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2614                 m->signature->pinvoke = 1;
2615
2616                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2617
2618                 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
2619                 mono_error_assert_ok (error);
2620                 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
2621                 mono_error_assert_ok (error);
2622                 
2623                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2624
2625                 if (image_is_dynamic (klass->image))
2626                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2627
2628                 mono_loader_unlock ();
2629
2630                 return m;
2631         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2632                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2633                 MonoMethodHeader *header;
2634                 guint32 code_size;
2635                 gint32 max_stack, i;
2636                 gint32 num_locals = 0;
2637                 gint32 num_clauses = 0;
2638                 guint8 *code;
2639
2640                 if (rmb->ilgen) {
2641                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2642                         code_size = rmb->ilgen->code_len;
2643                         max_stack = rmb->ilgen->max_stack;
2644                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2645                         if (rmb->ilgen->ex_handlers)
2646                                 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2647                 } else {
2648                         if (rmb->code) {
2649                                 code = mono_array_addr (rmb->code, guint8, 0);
2650                                 code_size = mono_array_length (rmb->code);
2651                                 /* we probably need to run a verifier on the code... */
2652                                 max_stack = 8; 
2653                         }
2654                         else {
2655                                 code = NULL;
2656                                 code_size = 0;
2657                                 max_stack = 8;
2658                         }
2659                 }
2660
2661                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2662                 header->code_size = code_size;
2663                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2664                 memcpy ((char*)header->code, code, code_size);
2665                 header->max_stack = max_stack;
2666                 header->init_locals = rmb->init_locals;
2667                 header->num_locals = num_locals;
2668
2669                 for (i = 0; i < num_locals; ++i) {
2670                         MonoReflectionLocalBuilder *lb = 
2671                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2672
2673                         header->locals [i] = image_g_new0 (image, MonoType, 1);
2674                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2675                         mono_error_assert_ok (error);
2676                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2677                 }
2678
2679                 header->num_clauses = num_clauses;
2680                 if (num_clauses) {
2681                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2682                                                                  rmb->ilgen, num_clauses, error);
2683                         mono_error_assert_ok (error);
2684                 }
2685
2686                 wrapperm->header = header;
2687         }
2688
2689         if (rmb->generic_params) {
2690                 int count = mono_array_length (rmb->generic_params);
2691                 MonoGenericContainer *container;
2692
2693                 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2694                 container->is_method = TRUE;
2695                 container->is_anonymous = FALSE;
2696                 container->type_argc = count;
2697                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2698                 container->owner.method = m;
2699
2700                 m->is_generic = TRUE;
2701                 mono_method_set_generic_container (m, container);
2702
2703                 for (i = 0; i < count; i++) {
2704                         MonoReflectionGenericParam *gp =
2705                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2706                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2707                         mono_error_assert_ok (error);
2708                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2709                         container->type_params [i] = *param;
2710                         container->type_params [i].param.owner = container;
2711
2712                         gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2713
2714                         MonoClass *gklass = mono_class_from_mono_type (gp_type);
2715                         gklass->wastypebuilder = TRUE;
2716                 }
2717
2718                 /*
2719                  * The method signature might have pointers to generic parameters that belong to other methods.
2720                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2721                  * generic parameters.
2722                  */
2723                 for (i = 0; i < m->signature->param_count; ++i) {
2724                         MonoType *t = m->signature->params [i];
2725                         if (t->type == MONO_TYPE_MVAR) {
2726                                 MonoGenericParam *gparam =  t->data.generic_param;
2727                                 if (gparam->num < count) {
2728                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2729                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2730                                 }
2731
2732                         }
2733                 }
2734
2735                 if (mono_class_is_gtd (klass)) {
2736                         container->parent = mono_class_get_generic_container (klass);
2737                         container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2738                 }
2739                 container->context.method_inst = mono_get_shared_generic_inst (container);
2740         }
2741
2742         if (rmb->refs) {
2743                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2744                 int i;
2745                 void **data;
2746
2747                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2748
2749                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2750                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2751                 for (i = 0; i < rmb->nrefs; ++i)
2752                         data [i + 1] = rmb->refs [i];
2753         }
2754
2755         method_aux = NULL;
2756
2757         /* Parameter info */
2758         if (rmb->pinfo) {
2759                 if (!method_aux)
2760                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2761                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2762                 for (i = 0; i <= m->signature->param_count; ++i) {
2763                         MonoReflectionParamBuilder *pb;
2764                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2765                                 if ((i > 0) && (pb->attrs)) {
2766                                         /* Make a copy since it might point to a shared type structure */
2767                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2768                                         m->signature->params [i - 1]->attrs = pb->attrs;
2769                                 }
2770
2771                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2772                                         MonoDynamicImage *assembly;
2773                                         guint32 idx, len;
2774                                         MonoTypeEnum def_type;
2775                                         char *p;
2776                                         const char *p2;
2777
2778                                         if (!method_aux->param_defaults) {
2779                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2780                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2781                                         }
2782                                         assembly = (MonoDynamicImage*)klass->image;
2783                                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
2784                                         /* Copy the data from the blob since it might get realloc-ed */
2785                                         p = assembly->blob.data + idx;
2786                                         len = mono_metadata_decode_blob_size (p, &p2);
2787                                         len += p2 - p;
2788                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
2789                                         method_aux->param_default_types [i] = def_type;
2790                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
2791                                 }
2792
2793                                 if (pb->name) {
2794                                         method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
2795                                         mono_error_assert_ok (error);
2796                                 }
2797                                 if (pb->cattrs) {
2798                                         if (!method_aux->param_cattr)
2799                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
2800                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
2801                                 }
2802                         }
2803                 }
2804         }
2805
2806         /* Parameter marshalling */
2807         specs = NULL;
2808         if (rmb->pinfo)         
2809                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
2810                         MonoReflectionParamBuilder *pb;
2811                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2812                                 if (pb->marshal_info) {
2813                                         if (specs == NULL)
2814                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
2815                                         specs [pb->position] = 
2816                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
2817                                         if (!is_ok (error)) {
2818                                                 mono_loader_unlock ();
2819                                                 image_g_free (image, specs);
2820                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2821                                                 return NULL;
2822                                         }
2823                                 }
2824                         }
2825                 }
2826         if (specs != NULL) {
2827                 if (!method_aux)
2828                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2829                 method_aux->param_marshall = specs;
2830         }
2831
2832         if (image_is_dynamic (klass->image) && method_aux)
2833                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2834
2835         mono_loader_unlock ();
2836
2837         return m;
2838 }       
2839
2840 static MonoMethod*
2841 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
2842 {
2843         ReflectionMethodBuilder rmb;
2844         MonoMethodSignature *sig;
2845
2846         mono_loader_lock ();
2847
2848         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
2849                 return NULL;
2850
2851         g_assert (klass->image != NULL);
2852         sig = ctor_builder_to_signature (klass->image, mb, error);
2853         mono_loader_unlock ();
2854         return_val_if_nok (error, NULL);
2855
2856         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2857         return_val_if_nok (error, NULL);
2858         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2859
2860         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
2861                 /* ilgen is no longer needed */
2862                 mb->ilgen = NULL;
2863         }
2864
2865         return mb->mhandle;
2866 }
2867
2868 static MonoMethod*
2869 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
2870 {
2871         ReflectionMethodBuilder rmb;
2872         MonoMethodSignature *sig;
2873
2874         mono_error_init (error);
2875
2876         mono_loader_lock ();
2877
2878         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
2879                 return NULL;
2880
2881         g_assert (klass->image != NULL);
2882         sig = method_builder_to_signature (klass->image, mb, error);
2883         mono_loader_unlock ();
2884         return_val_if_nok (error, NULL);
2885
2886         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2887         return_val_if_nok (error, NULL);
2888         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2889
2890         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
2891                 /* ilgen is no longer needed */
2892                 mb->ilgen = NULL;
2893         return mb->mhandle;
2894 }
2895 #endif
2896
2897 #ifndef DISABLE_REFLECTION_EMIT
2898
2899 /**
2900  * fix_partial_generic_class:
2901  * @klass: a generic instantiation MonoClass
2902  * @error: set on error
2903  *
2904  * Assumes that the generic container of @klass has its vtable
2905  * initialized, and updates the parent class, interfaces, methods and
2906  * fields of @klass by inflating the types using the generic context.
2907  *
2908  * On success returns TRUE, on failure returns FALSE and sets @error.
2909  *
2910  */
2911 static gboolean
2912 fix_partial_generic_class (MonoClass *klass, MonoError *error)
2913 {
2914         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
2915         int i;
2916
2917         mono_error_init (error);
2918
2919         if (klass->wastypebuilder)
2920                 return TRUE;
2921
2922         if (klass->parent != gklass->parent) {
2923                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
2924                 if (mono_error_ok (error)) {
2925                         MonoClass *parent = mono_class_from_mono_type (parent_type);
2926                         mono_metadata_free_type (parent_type);
2927                         if (parent != klass->parent) {
2928                                 /*fool mono_class_setup_parent*/
2929                                 klass->supertypes = NULL;
2930                                 mono_class_setup_parent (klass, parent);
2931                         }
2932                 } else {
2933                         if (gklass->wastypebuilder)
2934                                 klass->wastypebuilder = TRUE;
2935                         return FALSE;
2936                 }
2937         }
2938
2939         if (!mono_class_get_generic_class (klass)->need_sync)
2940                 return TRUE;
2941
2942         if (klass->method.count != gklass->method.count) {
2943                 klass->method.count = gklass->method.count;
2944                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
2945
2946                 for (i = 0; i < klass->method.count; i++) {
2947                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
2948                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
2949                         mono_error_assert_ok (error);
2950                 }
2951         }
2952
2953         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
2954                 klass->interface_count = gklass->interface_count;
2955                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
2956                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
2957
2958                 for (i = 0; i < gklass->interface_count; ++i) {
2959                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
2960                         return_val_if_nok (error, FALSE);
2961
2962                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
2963                         mono_metadata_free_type (iface_type);
2964
2965                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
2966                                 return FALSE;
2967                 }
2968                 klass->interfaces_inited = 1;
2969         }
2970
2971         if (klass->field.count != gklass->field.count) {
2972                 klass->field.count = gklass->field.count;
2973                 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
2974
2975                 for (i = 0; i < klass->field.count; i++) {
2976                         klass->fields [i] = gklass->fields [i];
2977                         klass->fields [i].parent = klass;
2978                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
2979                         return_val_if_nok (error, FALSE);
2980                 }
2981         }
2982
2983         /*We can only finish with this klass once it's parent has as well*/
2984         if (gklass->wastypebuilder)
2985                 klass->wastypebuilder = TRUE;
2986         return TRUE;
2987 }
2988
2989 /**
2990  * ensure_generic_class_runtime_vtable:
2991  * @klass a generic class
2992  * @error set on error
2993  *
2994  * Ensures that the generic container of @klass has a vtable and
2995  * returns TRUE on success.  On error returns FALSE and sets @error.
2996  */
2997 static gboolean
2998 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
2999 {
3000         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3001
3002         mono_error_init (error);
3003
3004         if (!ensure_runtime_vtable (gklass, error))
3005                 return FALSE;
3006
3007         return fix_partial_generic_class (klass, error);
3008 }
3009
3010 /**
3011  * ensure_runtime_vtable:
3012  * @klass the class
3013  * @error set on error
3014  *
3015  * Ensures that @klass has a vtable and returns TRUE on success. On
3016  * error returns FALSE and sets @error.
3017  */
3018 static gboolean
3019 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3020 {
3021         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3022         int i, num, j;
3023
3024         mono_error_init (error);
3025
3026         if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3027                 return TRUE;
3028         if (klass->parent)
3029                 if (!ensure_runtime_vtable (klass->parent, error))
3030                         return FALSE;
3031
3032         if (tb) {
3033                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3034                 num += tb->num_methods;
3035                 klass->method.count = num;
3036                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3037                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3038                 for (i = 0; i < num; ++i) {
3039                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3040                         if (!ctor)
3041                                 return FALSE;
3042                         klass->methods [i] = ctor;
3043                 }
3044                 num = tb->num_methods;
3045                 j = i;
3046                 for (i = 0; i < num; ++i) {
3047                         MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3048                         if (!meth)
3049                                 return FALSE;
3050                         klass->methods [j++] = meth;
3051                 }
3052         
3053                 if (tb->interfaces) {
3054                         klass->interface_count = mono_array_length (tb->interfaces);
3055                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3056                         for (i = 0; i < klass->interface_count; ++i) {
3057                                 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3058                                 return_val_if_nok (error, FALSE);
3059                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
3060                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3061                                         return FALSE;
3062                         }
3063                         klass->interfaces_inited = 1;
3064                 }
3065         } else if (mono_class_is_ginst (klass)){
3066                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3067                         mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3068                         return FALSE;
3069                 }
3070         }
3071
3072         if (mono_class_is_interface (klass)) {
3073                 int slot_num = 0;
3074                 for (i = 0; i < klass->method.count; ++i) {
3075                         MonoMethod *im = klass->methods [i];
3076                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3077                                 im->slot = slot_num++;
3078                 }
3079                 
3080                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3081                 mono_class_setup_interface_offsets (klass);
3082                 mono_class_setup_interface_id (klass);
3083         }
3084
3085         /*
3086          * The generic vtable is needed even if image->run is not set since some
3087          * runtime code like ves_icall_Type_GetMethodsByName depends on 
3088          * method->slot being defined.
3089          */
3090
3091         /* 
3092          * tb->methods could not be freed since it is used for determining 
3093          * overrides during dynamic vtable construction.
3094          */
3095
3096         return TRUE;
3097 }
3098
3099 static MonoMethod*
3100 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3101 {
3102         mono_error_init (error);
3103         MonoClass *klass = mono_object_class (method);
3104         if (is_sr_mono_method (klass)) {
3105                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3106                 return sr_method->method;
3107         }
3108         if (is_sre_method_builder (klass)) {
3109                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3110                 return mb->mhandle;
3111         }
3112         if (mono_is_sre_method_on_tb_inst (klass)) {
3113                 MonoClass *handle_class;
3114
3115                 MonoMethod *result =  mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3116                 return_val_if_nok (error, NULL);
3117
3118                 return result;
3119         }
3120
3121         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3122         return NULL;
3123 }
3124
3125 void
3126 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3127 {
3128         MonoReflectionTypeBuilder *tb;
3129         int i, j, onum;
3130         MonoReflectionMethod *m;
3131
3132         mono_error_init (error);
3133         *overrides = NULL;
3134         *num_overrides = 0;
3135
3136         g_assert (image_is_dynamic (klass->image));
3137
3138         if (!mono_class_get_ref_info (klass))
3139                 return;
3140
3141         g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
3142
3143         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
3144
3145         onum = 0;
3146         if (tb->methods) {
3147                 for (i = 0; i < tb->num_methods; ++i) {
3148                         MonoReflectionMethodBuilder *mb = 
3149                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3150                         if (mb->override_methods)
3151                                 onum += mono_array_length (mb->override_methods);
3152                 }
3153         }
3154
3155         if (onum) {
3156                 *overrides = g_new0 (MonoMethod*, onum * 2);
3157
3158                 onum = 0;
3159                 for (i = 0; i < tb->num_methods; ++i) {
3160                         MonoReflectionMethodBuilder *mb = 
3161                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3162                         if (mb->override_methods) {
3163                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3164                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3165
3166                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3167                                         return_if_nok (error);
3168                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
3169
3170                                         g_assert (mb->mhandle);
3171
3172                                         onum ++;
3173                                 }
3174                         }
3175                 }
3176         }
3177
3178         *num_overrides = onum;
3179 }
3180
3181 /* This initializes the same data as mono_class_setup_fields () */
3182 static void
3183 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3184 {
3185         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3186         MonoReflectionFieldBuilder *fb;
3187         MonoClassField *field;
3188         MonoImage *image = klass->image;
3189         const char *p, *p2;
3190         int i, instance_size, packing_size = 0;
3191         guint32 len, idx;
3192
3193         if (klass->parent) {
3194                 if (!klass->parent->size_inited)
3195                         mono_class_init (klass->parent);
3196                 instance_size = klass->parent->instance_size;
3197         } else {
3198                 instance_size = sizeof (MonoObject);
3199         }
3200
3201         klass->field.count = tb->num_fields;
3202         klass->field.first = 0;
3203
3204         mono_error_init (error);
3205
3206         if (tb->class_size) {
3207                 packing_size = tb->packing_size;
3208                 instance_size += tb->class_size;
3209         }
3210         
3211         klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
3212         mono_class_alloc_ext (klass);
3213         klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
3214         /*
3215         This is, guess what, a hack.
3216         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3217         On the static path no field class is resolved, only types are built. This is the right thing to do
3218         but we suck.
3219         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3220         */
3221         klass->size_inited = 1;
3222
3223         for (i = 0; i < klass->field.count; ++i) {
3224                 MonoArray *rva_data;
3225                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3226                 field = &klass->fields [i];
3227                 field->parent = klass;
3228                 field->name = mono_string_to_utf8_image (image, fb->name, error);
3229                 if (!mono_error_ok (error))
3230                         return;
3231                 if (fb->attrs) {
3232                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3233                         return_if_nok (error);
3234                         field->type = mono_metadata_type_dup (klass->image, type);
3235                         field->type->attrs = fb->attrs;
3236                 } else {
3237                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3238                         return_if_nok (error);
3239                 }
3240
3241                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3242                         char *base = mono_array_addr (rva_data, char, 0);
3243                         size_t size = mono_array_length (rva_data);
3244                         char *data = (char *)mono_image_alloc (klass->image, size);
3245                         memcpy (data, base, size);
3246                         klass->ext->field_def_values [i].data = data;
3247                 }
3248                 if (fb->offset != -1)
3249                         field->offset = fb->offset;
3250                 fb->handle = field;
3251                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3252
3253                 if (fb->def_value) {
3254                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3255                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3256                         idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
3257                         /* Copy the data from the blob since it might get realloc-ed */
3258                         p = assembly->blob.data + idx;
3259                         len = mono_metadata_decode_blob_size (p, &p2);
3260                         len += p2 - p;
3261                         klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
3262                         memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
3263                 }
3264         }
3265
3266         mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3267 }
3268
3269 static void
3270 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3271 {
3272         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3273         MonoReflectionPropertyBuilder *pb;
3274         MonoImage *image = klass->image;
3275         MonoProperty *properties;
3276         int i;
3277
3278         mono_error_init (error);
3279
3280         if (!klass->ext)
3281                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
3282
3283         klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
3284         klass->ext->property.first = 0;
3285
3286         properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
3287         klass->ext->properties = properties;
3288         for (i = 0; i < klass->ext->property.count; ++i) {
3289                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3290                 properties [i].parent = klass;
3291                 properties [i].attrs = pb->attrs;
3292                 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
3293                 if (!mono_error_ok (error))
3294                         return;
3295                 if (pb->get_method)
3296                         properties [i].get = pb->get_method->mhandle;
3297                 if (pb->set_method)
3298                         properties [i].set = pb->set_method->mhandle;
3299
3300                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3301                 if (pb->def_value) {
3302                         guint32 len, idx;
3303                         const char *p, *p2;
3304                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3305                         if (!klass->ext->prop_def_values)
3306                                 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
3307                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3308                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
3309                         /* Copy the data from the blob since it might get realloc-ed */
3310                         p = assembly->blob.data + idx;
3311                         len = mono_metadata_decode_blob_size (p, &p2);
3312                         len += p2 - p;
3313                         klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
3314                         memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
3315                 }
3316         }
3317 }
3318
3319 static void
3320 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3321 {
3322         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3323         MonoReflectionEventBuilder *eb;
3324         MonoImage *image = klass->image;
3325         MonoEvent *events;
3326         int i;
3327
3328         mono_error_init (error);
3329
3330         if (!klass->ext)
3331                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
3332
3333         klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
3334         klass->ext->event.first = 0;
3335
3336         events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
3337         klass->ext->events = events;
3338         for (i = 0; i < klass->ext->event.count; ++i) {
3339                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3340                 events [i].parent = klass;
3341                 events [i].attrs = eb->attrs;
3342                 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
3343                 if (!mono_error_ok (error))
3344                         return;
3345                 if (eb->add_method)
3346                         events [i].add = eb->add_method->mhandle;
3347                 if (eb->remove_method)
3348                         events [i].remove = eb->remove_method->mhandle;
3349                 if (eb->raise_method)
3350                         events [i].raise = eb->raise_method->mhandle;
3351
3352 #ifndef MONO_SMALL_CONFIG
3353                 if (eb->other_methods) {
3354                         int j;
3355                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3356                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3357                                 MonoReflectionMethodBuilder *mb = 
3358                                         mono_array_get (eb->other_methods,
3359                                                                         MonoReflectionMethodBuilder*, j);
3360                                 events [i].other [j] = mb->mhandle;
3361                         }
3362                 }
3363 #endif
3364                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3365         }
3366 }
3367
3368 struct remove_instantiations_user_data
3369 {
3370         MonoClass *klass;
3371         MonoError *error;
3372 };
3373
3374 static gboolean
3375 remove_instantiations_of_and_ensure_contents (gpointer key,
3376                                                   gpointer value,
3377                                                   gpointer user_data)
3378 {
3379         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3380         MonoType *type = (MonoType*)key;
3381         MonoClass *klass = data->klass;
3382         gboolean already_failed = !is_ok (data->error);
3383         MonoError lerror;
3384         MonoError *error = already_failed ? &lerror : data->error;
3385
3386         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3387                 MonoClass *inst_klass = mono_class_from_mono_type (type);
3388                 //Ensure it's safe to use it.
3389                 if (!fix_partial_generic_class (inst_klass, error)) {
3390                         mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3391                         // Marked the class with failure, but since some other instantiation already failed,
3392                         // just report that one, and swallow the error from this one.
3393                         if (already_failed)
3394                                 mono_error_cleanup (error);
3395                 }
3396                 return TRUE;
3397         } else
3398                 return FALSE;
3399 }
3400
3401 MonoReflectionType*
3402 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
3403 {
3404         MonoError error;
3405         MonoClass *klass;
3406         MonoDomain* domain;
3407         MonoReflectionType* res;
3408         int i;
3409
3410         mono_error_init (&error);
3411
3412         reflection_create_generic_class (tb, &error);
3413         mono_error_assert_ok (&error);
3414
3415         domain = mono_object_domain (tb);
3416         klass = mono_class_from_mono_type (tb->type.type);
3417
3418         mono_save_custom_attrs (klass->image, klass, tb->cattrs);
3419
3420         /* 
3421          * we need to lock the domain because the lock will be taken inside
3422          * So, we need to keep the locking order correct.
3423          */
3424         mono_loader_lock ();
3425         mono_domain_lock (domain);
3426         if (klass->wastypebuilder) {
3427                 mono_domain_unlock (domain);
3428                 mono_loader_unlock ();
3429
3430                 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3431                 mono_error_set_pending_exception (&error);
3432
3433                 return res;
3434         }
3435         /*
3436          * Fields to set in klass:
3437          * the various flags: delegate/unicode/contextbound etc.
3438          */
3439         mono_class_set_flags (klass, tb->attrs);
3440         klass->has_cctor = 1;
3441
3442         mono_class_setup_parent (klass, klass->parent);
3443         /* fool mono_class_setup_supertypes */
3444         klass->supertypes = NULL;
3445         mono_class_setup_supertypes (klass);
3446         mono_class_setup_mono_type (klass);
3447
3448         /* enums are done right away */
3449         if (!klass->enumtype)
3450                 if (!ensure_runtime_vtable (klass, &error))
3451                         goto failure;
3452
3453         if (tb->subtypes) {
3454                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3455                         MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
3456                         mono_class_alloc_ext (klass);
3457
3458                         if (!subtb->type.type) {
3459                                 reflection_setup_internal_class (subtb, &error);
3460                                 mono_error_assert_ok (&error);
3461                         }
3462
3463                         MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
3464                         if (!is_ok (&error)) goto failure;
3465                         klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
3466                 }
3467         }
3468
3469         klass->nested_classes_inited = TRUE;
3470
3471         typebuilder_setup_fields (klass, &error);
3472         if (!mono_error_ok (&error))
3473                 goto failure;
3474         typebuilder_setup_properties (klass, &error);
3475         if (!mono_error_ok (&error))
3476                 goto failure;
3477
3478         typebuilder_setup_events (klass, &error);
3479         if (!mono_error_ok (&error))
3480                 goto failure;
3481
3482         klass->wastypebuilder = TRUE;
3483
3484         if (tb->generic_params) {
3485                 for (i = 0; i < mono_array_length (tb->generic_params); i++) {
3486                         MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3487                         MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error);
3488                         MonoClass *gklass = mono_class_from_mono_type (param_type);
3489
3490                         gklass->wastypebuilder = TRUE;
3491                 }
3492         }
3493
3494         /* 
3495          * If we are a generic TypeBuilder, there might be instantiations in the type cache
3496          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
3497          * we want to return normal System.MonoType objects, so clear these out from the cache.
3498          *
3499          * Together with this we must ensure the contents of all instances to match the created type.
3500          */
3501         if (domain->type_hash && mono_class_is_gtd (klass)) {
3502                 struct remove_instantiations_user_data data;
3503                 data.klass = klass;
3504                 data.error = &error;
3505                 mono_error_assert_ok (&error);
3506                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3507                 if (!is_ok (&error))
3508                         goto failure;
3509         }
3510
3511         mono_domain_unlock (domain);
3512         mono_loader_unlock ();
3513
3514         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3515                 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3516                 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
3517                 goto failure_unlocked;
3518         }
3519
3520         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3521         if (!is_ok (&error))
3522                 goto failure_unlocked;
3523
3524         g_assert (res != (MonoReflectionType*)tb);
3525
3526         return res;
3527
3528 failure:
3529         mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
3530         klass->wastypebuilder = TRUE;
3531         mono_domain_unlock (domain);
3532         mono_loader_unlock ();
3533 failure_unlocked:
3534         mono_error_set_pending_exception (&error);
3535         return NULL;
3536 }
3537
3538 typedef struct {
3539         MonoMethod *handle;
3540         MonoDomain *domain;
3541 } DynamicMethodReleaseData;
3542
3543 /*
3544  * The runtime automatically clean up those after finalization.
3545 */      
3546 static MonoReferenceQueue *dynamic_method_queue;
3547
3548 static void
3549 free_dynamic_method (void *dynamic_method)
3550 {
3551         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3552         MonoDomain *domain = data->domain;
3553         MonoMethod *method = data->handle;
3554         guint32 dis_link;
3555
3556         mono_domain_lock (domain);
3557         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3558         g_hash_table_remove (domain->method_to_dyn_method, method);
3559         mono_domain_unlock (domain);
3560         g_assert (dis_link);
3561         mono_gchandle_free (dis_link);
3562
3563         mono_runtime_free_method (domain, method);
3564         g_free (data);
3565 }
3566
3567 static gboolean
3568 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
3569 {
3570         MonoReferenceQueue *queue;
3571         MonoMethod *handle;
3572         DynamicMethodReleaseData *release_data;
3573         ReflectionMethodBuilder rmb;
3574         MonoMethodSignature *sig;
3575         MonoClass *klass;
3576         MonoDomain *domain;
3577         GSList *l;
3578         int i;
3579
3580         mono_error_init (error);
3581
3582         if (mono_runtime_is_shutting_down ()) {
3583                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3584                 return FALSE;
3585         }
3586
3587         if (!(queue = dynamic_method_queue)) {
3588                 mono_loader_lock ();
3589                 if (!(queue = dynamic_method_queue))
3590                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3591                 mono_loader_unlock ();
3592         }
3593
3594         sig = dynamic_method_to_signature (mb, error);
3595         return_val_if_nok (error, FALSE);
3596
3597         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3598
3599         /*
3600          * Resolve references.
3601          */
3602         /* 
3603          * Every second entry in the refs array is reserved for storing handle_class,
3604          * which is needed by the ldtoken implementation in the JIT.
3605          */
3606         rmb.nrefs = mb->nrefs;
3607         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3608         for (i = 0; i < mb->nrefs; i += 2) {
3609                 MonoClass *handle_class;
3610                 gpointer ref;
3611                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3612
3613                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3614                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3615                         /*
3616                          * The referenced DynamicMethod should already be created by the managed
3617                          * code, except in the case of circular references. In that case, we store
3618                          * method in the refs array, and fix it up later when the referenced 
3619                          * DynamicMethod is created.
3620                          */
3621                         if (method->mhandle) {
3622                                 ref = method->mhandle;
3623                         } else {
3624                                 /* FIXME: GC object stored in unmanaged memory */
3625                                 ref = method;
3626
3627                                 /* FIXME: GC object stored in unmanaged memory */
3628                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
3629                         }
3630                         handle_class = mono_defaults.methodhandle_class;
3631                 } else {
3632                         MonoException *ex = NULL;
3633                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3634                         if (!is_ok  (error)) {
3635                                 g_free (rmb.refs);
3636                                 return FALSE;
3637                         }
3638                         if (!ref)
3639                                 ex = mono_get_exception_type_load (NULL, NULL);
3640                         else if (mono_security_core_clr_enabled ())
3641                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3642
3643                         if (ex) {
3644                                 g_free (rmb.refs);
3645                                 mono_error_set_exception_instance (error, ex);
3646                                 return FALSE;
3647                         }
3648                 }
3649
3650                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3651                 rmb.refs [i + 1] = handle_class;
3652         }               
3653
3654         if (mb->owner) {
3655                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3656                 if (!is_ok (error)) {
3657                         g_free (rmb.refs);
3658                         return FALSE;
3659                 }
3660                 klass = mono_class_from_mono_type (owner_type);
3661         } else {
3662                 klass = mono_defaults.object_class;
3663         }
3664
3665         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3666         g_free (rmb.refs);
3667         return_val_if_nok (error, FALSE);
3668
3669         release_data = g_new (DynamicMethodReleaseData, 1);
3670         release_data->handle = handle;
3671         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3672         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3673                 g_free (release_data);
3674
3675         /* Fix up refs entries pointing at us */
3676         for (l = mb->referenced_by; l; l = l->next) {
3677                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3678                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3679                 gpointer *data;
3680                 
3681                 g_assert (method->mhandle);
3682
3683                 data = (gpointer*)wrapper->method_data;
3684                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3685                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3686                                 data [i + 1] = mb->mhandle;
3687                 }
3688         }
3689         g_slist_free (mb->referenced_by);
3690
3691         /* ilgen is no longer needed */
3692         mb->ilgen = NULL;
3693
3694         domain = mono_domain_get ();
3695         mono_domain_lock (domain);
3696         if (!domain->method_to_dyn_method)
3697                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3698         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3699         mono_domain_unlock (domain);
3700
3701         return TRUE;
3702 }
3703
3704 void
3705 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
3706 {
3707         MonoError error;
3708         (void) reflection_create_dynamic_method (mb, &error);
3709         mono_error_set_pending_exception (&error);
3710 }
3711
3712 #endif /* DISABLE_REFLECTION_EMIT */
3713
3714 MonoMethodSignature *
3715 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3716 {
3717         MonoMethodSignature *sig;
3718         g_assert (image_is_dynamic (image));
3719
3720         mono_error_init (error);
3721
3722         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
3723         if (sig)
3724                 return sig;
3725
3726         return mono_method_signature_checked (method, error);
3727 }
3728
3729 #ifndef DISABLE_REFLECTION_EMIT
3730
3731 /*
3732  * ensure_complete_type:
3733  *
3734  *   Ensure that KLASS is completed if it is a dynamic type, or references
3735  * dynamic types.
3736  */
3737 static void
3738 ensure_complete_type (MonoClass *klass, MonoError *error)
3739 {
3740         mono_error_init (error);
3741
3742         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
3743                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3744
3745                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3746                 return_if_nok (error);
3747
3748                 // Asserting here could break a lot of code
3749                 //g_assert (klass->wastypebuilder);
3750         }
3751
3752         if (mono_class_is_ginst (klass)) {
3753                 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
3754                 int i;
3755
3756                 for (i = 0; i < inst->type_argc; ++i) {
3757                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
3758                         return_if_nok (error);
3759                 }
3760         }
3761 }
3762
3763 gpointer
3764 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
3765 {
3766         MonoClass *oklass = obj->vtable->klass;
3767         gpointer result = NULL;
3768
3769         mono_error_init (error);
3770
3771         if (strcmp (oklass->name, "String") == 0) {
3772                 result = mono_string_intern_checked ((MonoString*)obj, error);
3773                 return_val_if_nok (error, NULL);
3774                 *handle_class = mono_defaults.string_class;
3775                 g_assert (result);
3776         } else if (strcmp (oklass->name, "RuntimeType") == 0) {
3777                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
3778                 return_val_if_nok (error, NULL);
3779                 MonoClass *mc = mono_class_from_mono_type (type);
3780                 if (!mono_class_init (mc)) {
3781                         mono_error_set_for_class_failure (error, mc);
3782                         return NULL;
3783                 }
3784
3785                 if (context) {
3786                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
3787                         return_val_if_nok (error, NULL);
3788
3789                         result = mono_class_from_mono_type (inflated);
3790                         mono_metadata_free_type (inflated);
3791                 } else {
3792                         result = mono_class_from_mono_type (type);
3793                 }
3794                 *handle_class = mono_defaults.typehandle_class;
3795                 g_assert (result);
3796         } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
3797                            strcmp (oklass->name, "MonoCMethod") == 0) {
3798                 result = ((MonoReflectionMethod*)obj)->method;
3799                 if (context) {
3800                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
3801                         mono_error_assert_ok (error);
3802                 }
3803                 *handle_class = mono_defaults.methodhandle_class;
3804                 g_assert (result);
3805         } else if (strcmp (oklass->name, "MonoField") == 0) {
3806                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
3807
3808                 ensure_complete_type (field->parent, error);
3809                 return_val_if_nok (error, NULL);
3810
3811                 if (context) {
3812                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
3813                         return_val_if_nok (error, NULL);
3814
3815                         MonoClass *klass = mono_class_from_mono_type (inflated);
3816                         MonoClassField *inflated_field;
3817                         gpointer iter = NULL;
3818                         mono_metadata_free_type (inflated);
3819                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
3820                                 if (!strcmp (field->name, inflated_field->name))
3821                                         break;
3822                         }
3823                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
3824                         result = inflated_field;
3825                 } else {
3826                         result = field;
3827                 }
3828                 *handle_class = mono_defaults.fieldhandle_class;
3829                 g_assert (result);
3830         } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
3831                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
3832                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3833                 return_val_if_nok (error, NULL);
3834                 MonoClass *klass;
3835
3836                 klass = type->data.klass;
3837                 if (klass->wastypebuilder) {
3838                         /* Already created */
3839                         result = klass;
3840                 }
3841                 else {
3842                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3843                         return_val_if_nok (error, NULL);
3844                         result = type->data.klass;
3845                         g_assert (result);
3846                 }
3847                 *handle_class = mono_defaults.typehandle_class;
3848         } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
3849                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
3850                 MonoMethodSignature *sig;
3851                 int nargs, i;
3852
3853                 if (helper->arguments)
3854                         nargs = mono_array_length (helper->arguments);
3855                 else
3856                         nargs = 0;
3857
3858                 sig = mono_metadata_signature_alloc (image, nargs);
3859                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
3860                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
3861
3862                 if (helper->unmanaged_call_conv) { /* unmanaged */
3863                         sig->call_convention = helper->unmanaged_call_conv - 1;
3864                         sig->pinvoke = TRUE;
3865                 } else if (helper->call_conv & 0x02) {
3866                         sig->call_convention = MONO_CALL_VARARG;
3867                 } else {
3868                         sig->call_convention = MONO_CALL_DEFAULT;
3869                 }
3870
3871                 sig->param_count = nargs;
3872                 /* TODO: Copy type ? */
3873                 sig->ret = helper->return_type->type;
3874                 for (i = 0; i < nargs; ++i) {
3875                         sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
3876                         if (!is_ok (error)) {
3877                                 image_g_free (image, sig);
3878                                 return NULL;
3879                         }
3880                 }
3881
3882                 result = sig;
3883                 *handle_class = NULL;
3884         } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
3885                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3886                 /* Already created by the managed code */
3887                 g_assert (method->mhandle);
3888                 result = method->mhandle;
3889                 *handle_class = mono_defaults.methodhandle_class;
3890         } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
3891                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
3892                 MonoType *mtype;
3893                 MonoClass *klass;
3894                 MonoMethod *method;
3895                 gpointer iter;
3896                 char *name;
3897
3898                 mtype = mono_reflection_type_get_handle (m->parent, error);
3899                 return_val_if_nok (error, NULL);
3900                 klass = mono_class_from_mono_type (mtype);
3901
3902                 /* Find the method */
3903
3904                 name = mono_string_to_utf8_checked (m->name, error);
3905                 return_val_if_nok (error, NULL);
3906                 iter = NULL;
3907                 while ((method = mono_class_get_methods (klass, &iter))) {
3908                         if (!strcmp (method->name, name))
3909                                 break;
3910                 }
3911                 g_free (name);
3912
3913                 // FIXME:
3914                 g_assert (method);
3915                 // FIXME: Check parameters/return value etc. match
3916
3917                 result = method;
3918                 *handle_class = mono_defaults.methodhandle_class;
3919         } else if (is_sre_method_builder (oklass) ||
3920                            mono_is_sre_ctor_builder (oklass) ||
3921                            is_sre_field_builder (oklass) ||
3922                            is_sre_gparam_builder (oklass) ||
3923                            is_sre_generic_instance (oklass) ||
3924                            is_sre_array (oklass) ||
3925                            is_sre_byref (oklass) ||
3926                            is_sre_pointer (oklass) ||
3927                            !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
3928                            !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
3929                            !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
3930                 static MonoMethod *resolve_method;
3931                 if (!resolve_method) {
3932                         MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
3933                         g_assert (m);
3934                         mono_memory_barrier ();
3935                         resolve_method = m;
3936                 }
3937                 void *args [16];
3938                 args [0] = obj;
3939                 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
3940                 mono_error_assert_ok (error);
3941                 g_assert (obj);
3942                 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
3943         } else {
3944                 g_print ("%s\n", obj->vtable->klass->name);
3945                 g_assert_not_reached ();
3946         }
3947         return result;
3948 }
3949
3950 #else /* DISABLE_REFLECTION_EMIT */
3951
3952 MonoArray*
3953 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
3954 {
3955         g_assert_not_reached ();
3956         return NULL;
3957 }
3958
3959 void
3960 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
3961 {
3962         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
3963 }
3964
3965 static void
3966 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
3967 {
3968         g_assert_not_reached ();
3969 }
3970
3971 guint32
3972 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
3973 {
3974         g_assert_not_reached ();
3975         return 0;
3976 }
3977
3978 guint32
3979 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
3980 {
3981         g_assert_not_reached ();
3982         return 0;
3983 }
3984
3985 guint32
3986 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
3987                          gboolean create_open_instance, gboolean register_token, MonoError *error)
3988 {
3989         g_assert_not_reached ();
3990         return 0;
3991 }
3992
3993 void
3994 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3995 {
3996         mono_error_init (error);
3997         *overrides = NULL;
3998         *num_overrides = 0;
3999 }
4000
4001 MonoReflectionType*
4002 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4003 {
4004         g_assert_not_reached ();
4005         return NULL;
4006 }
4007
4008 void 
4009 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4010 {
4011 }
4012
4013 MonoType*
4014 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4015 {
4016         mono_error_init (error);
4017         if (!ref)
4018                 return NULL;
4019         return ref->type;
4020 }
4021
4022 #endif /* DISABLE_REFLECTION_EMIT */
4023
4024 void
4025 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4026 {
4027         mono_gc_deregister_root ((char*) &entry->gparam);
4028         g_free (entry);
4029 }
4030
4031 gint32
4032 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
4033 {
4034         MONO_CHECK_ARG_NULL (obj, 0);
4035
4036         MonoError error;
4037         gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
4038         mono_error_set_pending_exception (&error);
4039         return result;
4040 }
4041
4042 gint32
4043 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
4044                                         MonoReflectionMethod *method,
4045                                         MonoArray *opt_param_types)
4046 {
4047         MONO_CHECK_ARG_NULL (method, 0);
4048
4049         MonoError error;
4050         gint32 result = mono_image_create_method_token (
4051                 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
4052         mono_error_set_pending_exception (&error);
4053         return result;
4054 }
4055
4056 void
4057 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4058 {
4059         MonoError error;
4060         mono_image_create_pefile (mb, file, &error);
4061         mono_error_set_pending_exception (&error);
4062 }
4063
4064 void
4065 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4066 {
4067         MonoError error;
4068         mono_image_build_metadata (mb, &error);
4069         mono_error_set_pending_exception (&error);
4070 }
4071
4072 void
4073 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
4074 {
4075         mono_image_register_token (mb->dynamic_image, token, obj);
4076 }
4077
4078 MonoObject*
4079 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
4080 {
4081         MonoObject *obj;
4082
4083         mono_loader_lock ();
4084         obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
4085         mono_loader_unlock ();
4086
4087         return obj;
4088 }
4089
4090 #ifndef DISABLE_REFLECTION_EMIT
4091 MonoArray*
4092 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4093 {
4094         MonoError error;
4095         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4096         mono_error_set_pending_exception (&error);
4097         return result;
4098 }
4099 #endif
4100
4101 void
4102 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4103 {
4104         mono_reflection_dynimage_basic_init (assemblyb);
4105 }
4106
4107 void
4108 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
4109                                                                            MonoReflectionType *t)
4110 {
4111         enumtype->type = t->type;
4112 }
4113
4114 void
4115 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
4116 {
4117         mono_image_module_basic_init (moduleb);
4118 }
4119
4120 guint32
4121 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
4122 {
4123         return mono_image_insert_string (module, str);
4124 }
4125
4126 void
4127 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
4128 {
4129         MonoDynamicImage *image = moduleb->dynamic_image;
4130
4131         g_assert (type->type);
4132         image->wrappers_type = mono_class_from_mono_type (type->type);
4133 }