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