6cfb5296a26128943ce885a525651b1131d7c796
[mono.git] / mono / metadata / sre.c
1 /*
2  * sre.c: Routines for creating an image at runtime
3  *   and related System.Reflection.Emit icalls
4  *   
5  * 
6  * Author:
7  *   Paolo Molaro (lupus@ximian.com)
8  *
9  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
11  * Copyright 2011 Rodrigo Kumpera
12  * Copyright 2016 Microsoft
13  *
14  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
15  */
16 #include <config.h>
17 #include <glib.h>
18 #include "mono/metadata/assembly.h"
19 #include "mono/metadata/debug-helpers.h"
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/exception.h"
23 #include "mono/metadata/gc-internals.h"
24 #include "mono/metadata/mono-ptr-array.h"
25 #include "mono/metadata/object-internals.h"
26 #include "mono/metadata/profiler-private.h"
27 #include "mono/metadata/reflection-internals.h"
28 #include "mono/metadata/reflection-cache.h"
29 #include "mono/metadata/sre-internals.h"
30 #include "mono/metadata/custom-attrs-internals.h"
31 #include "mono/metadata/security-manager.h"
32 #include "mono/metadata/security-core-clr.h"
33 #include "mono/metadata/tabledefs.h"
34 #include "mono/metadata/tokentype.h"
35 #include "mono/utils/checked-build.h"
36 #include "mono/utils/mono-digest.h"
37
38 void
39 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
40 {
41         mono_gc_deregister_root ((char*) &entry->gparam);
42         g_free (entry);
43 }
44
45
46
47 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
48
49 #ifndef DISABLE_REFLECTION_EMIT
50 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
51 static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
52 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
53 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
54 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
55 static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
56 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
57
58 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
59 #endif
60
61 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
62 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
63 static gboolean is_sre_array (MonoClass *klass);
64 static gboolean is_sre_byref (MonoClass *klass);
65 static gboolean is_sre_pointer (MonoClass *klass);
66 static gboolean is_sre_type_builder (MonoClass *klass);
67 static gboolean is_sre_method_builder (MonoClass *klass);
68 static gboolean is_sre_field_builder (MonoClass *klass);
69 static gboolean is_sr_mono_method (MonoClass *klass);
70 static gboolean is_sr_mono_generic_method (MonoClass *klass);
71 static gboolean is_sr_mono_generic_cmethod (MonoClass *klass);
72 static gboolean is_sr_mono_field (MonoClass *klass);
73
74 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
75 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
76 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
77
78 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
79
80 #define RESOLVE_TYPE(type, error) do {                                  \
81         type = (MonoObject *)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type, error); \
82 } while (0)
83 #define RESOLVE_ARRAY_TYPE_ELEMENT(array, index, error) do {            \
84         MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
85         __type = mono_reflection_type_resolve_user_types (__type, error); \
86         if (mono_error_ok (error))                                      \
87                 mono_array_set (arr, MonoReflectionType*, index, __type); \
88 } while (0)
89
90 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
91
92 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
93
94 void
95 mono_reflection_emit_init (void)
96 {
97         mono_dynamic_images_init ();
98 }
99
100 static char*
101 type_get_fully_qualified_name (MonoType *type)
102 {
103         MONO_REQ_GC_NEUTRAL_MODE;
104
105         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
106 }
107
108 static char*
109 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
110 {
111         MONO_REQ_GC_UNSAFE_MODE;
112
113         MonoClass *klass;
114         MonoAssembly *ta;
115
116         klass = mono_class_from_mono_type (type);
117         if (!klass) 
118                 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
119         ta = klass->image->assembly;
120         if (assembly_is_dynamic (ta) || (ta == ass)) {
121                 if (klass->generic_class || klass->generic_container)
122                         /* For generic type definitions, we want T, while REFLECTION returns T<K> */
123                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
124                 else
125                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
126         }
127
128         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
129 }
130
131 #ifndef DISABLE_REFLECTION_EMIT
132 /**
133  * mp_g_alloc:
134  *
135  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
136  * from the C heap.
137  */
138 static gpointer
139 image_g_malloc (MonoImage *image, guint size)
140 {
141         MONO_REQ_GC_NEUTRAL_MODE;
142
143         if (image)
144                 return mono_image_alloc (image, size);
145         else
146                 return g_malloc (size);
147 }
148 #endif /* !DISABLE_REFLECTION_EMIT */
149
150 /**
151  * image_g_alloc0:
152  *
153  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
154  * from the C heap.
155  */
156 gpointer
157 mono_image_g_malloc0 (MonoImage *image, guint size)
158 {
159         MONO_REQ_GC_NEUTRAL_MODE;
160
161         if (image)
162                 return mono_image_alloc0 (image, size);
163         else
164                 return g_malloc0 (size);
165 }
166
167 /**
168  * image_g_free:
169  * @image: a MonoImage
170  * @ptr: pointer
171  *
172  * If @image is NULL, free @ptr, otherwise do nothing.
173  */
174 static void
175 image_g_free (MonoImage *image, gpointer ptr)
176 {
177         if (image == NULL)
178                 g_free (ptr);
179 }
180
181 #ifndef DISABLE_REFLECTION_EMIT
182 static char*
183 image_strdup (MonoImage *image, const char *s)
184 {
185         MONO_REQ_GC_NEUTRAL_MODE;
186
187         if (image)
188                 return mono_image_strdup (image, s);
189         else
190                 return g_strdup (s);
191 }
192 #endif
193
194 #define image_g_new(image,struct_type, n_structs)               \
195     ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
196
197 #define image_g_new0(image,struct_type, n_structs)              \
198     ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
199
200
201 static void
202 alloc_table (MonoDynamicTable *table, guint nrows)
203 {
204         mono_dynimage_alloc_table (table, nrows);
205 }
206
207 static guint32
208 string_heap_insert (MonoDynamicStream *sh, const char *str)
209 {
210         return mono_dynstream_insert_string (sh, str);
211 }
212
213 static guint32
214 string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
215 {
216         return mono_dynstream_insert_mstring (sh, str, error);
217 }
218
219 static guint32
220 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
221 {
222         return mono_dynstream_add_data (stream, data, len);
223 }
224
225 static guint32
226 mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
227 {
228         return mono_dynstream_add_zero (stream, len);
229 }
230
231 static void
232 stream_data_align (MonoDynamicStream *stream)
233 {
234         mono_dynstream_data_align (stream);
235 }
236
237 /*
238  * Despite the name, we handle also TypeSpec (with the above helper).
239  */
240 static guint32
241 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
242 {
243         return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
244 }
245
246 /*
247  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
248  * dest may be misaligned.
249  */
250 static void
251 swap_with_size (char *dest, const char* val, int len, int nelem) {
252         MONO_REQ_GC_NEUTRAL_MODE;
253 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
254         int elem;
255
256         for (elem = 0; elem < nelem; ++elem) {
257                 switch (len) {
258                 case 1:
259                         *dest = *val;
260                         break;
261                 case 2:
262                         dest [0] = val [1];
263                         dest [1] = val [0];
264                         break;
265                 case 4:
266                         dest [0] = val [3];
267                         dest [1] = val [2];
268                         dest [2] = val [1];
269                         dest [3] = val [0];
270                         break;
271                 case 8:
272                         dest [0] = val [7];
273                         dest [1] = val [6];
274                         dest [2] = val [5];
275                         dest [3] = val [4];
276                         dest [4] = val [3];
277                         dest [5] = val [2];
278                         dest [6] = val [1];
279                         dest [7] = val [0];
280                         break;
281                 default:
282                         g_assert_not_reached ();
283                 }
284                 dest += len;
285                 val += len;
286         }
287 #else
288         memcpy (dest, val, len * nelem);
289 #endif
290 }
291
292 #ifndef DISABLE_REFLECTION_EMIT
293 static MonoClass *
294 default_class_from_mono_type (MonoType *type)
295 {
296         MONO_REQ_GC_NEUTRAL_MODE;
297
298         switch (type->type) {
299         case MONO_TYPE_OBJECT:
300                 return mono_defaults.object_class;
301         case MONO_TYPE_VOID:
302                 return mono_defaults.void_class;
303         case MONO_TYPE_BOOLEAN:
304                 return mono_defaults.boolean_class;
305         case MONO_TYPE_CHAR:
306                 return mono_defaults.char_class;
307         case MONO_TYPE_I1:
308                 return mono_defaults.sbyte_class;
309         case MONO_TYPE_U1:
310                 return mono_defaults.byte_class;
311         case MONO_TYPE_I2:
312                 return mono_defaults.int16_class;
313         case MONO_TYPE_U2:
314                 return mono_defaults.uint16_class;
315         case MONO_TYPE_I4:
316                 return mono_defaults.int32_class;
317         case MONO_TYPE_U4:
318                 return mono_defaults.uint32_class;
319         case MONO_TYPE_I:
320                 return mono_defaults.int_class;
321         case MONO_TYPE_U:
322                 return mono_defaults.uint_class;
323         case MONO_TYPE_I8:
324                 return mono_defaults.int64_class;
325         case MONO_TYPE_U8:
326                 return mono_defaults.uint64_class;
327         case MONO_TYPE_R4:
328                 return mono_defaults.single_class;
329         case MONO_TYPE_R8:
330                 return mono_defaults.double_class;
331         case MONO_TYPE_STRING:
332                 return mono_defaults.string_class;
333         default:
334                 g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
335                 g_assert_not_reached ();
336         }
337         
338         return NULL;
339 }
340 #endif
341
342 guint32
343 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
344 {
345         MONO_REQ_GC_UNSAFE_MODE;
346
347         guint32 num_clauses = 0;
348         int i;
349
350         MonoILExceptionInfo *ex_info;
351         for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
352                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
353                 if (ex_info->handlers)
354                         num_clauses += mono_array_length (ex_info->handlers);
355                 else
356                         num_clauses++;
357         }
358
359         return num_clauses;
360 }
361
362 #ifndef DISABLE_REFLECTION_EMIT
363 static MonoExceptionClause*
364 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
365 {
366         MONO_REQ_GC_UNSAFE_MODE;
367
368         mono_error_init (error);
369
370         MonoExceptionClause *clauses;
371         MonoExceptionClause *clause;
372         MonoILExceptionInfo *ex_info;
373         MonoILExceptionBlock *ex_block;
374         guint32 finally_start;
375         int i, j, clause_index;;
376
377         clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
378
379         clause_index = 0;
380         for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
381                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
382                 finally_start = ex_info->start + ex_info->len;
383                 if (!ex_info->handlers)
384                         continue;
385                 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
386                         ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
387                         clause = &(clauses [clause_index]);
388
389                         clause->flags = ex_block->type;
390                         clause->try_offset = ex_info->start;
391
392                         if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
393                                 clause->try_len = finally_start - ex_info->start;
394                         else
395                                 clause->try_len = ex_info->len;
396                         clause->handler_offset = ex_block->start;
397                         clause->handler_len = ex_block->len;
398                         if (ex_block->extype) {
399                                 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
400
401                                 if (!is_ok (error)) {
402                                         image_g_free (image, clauses);
403                                         return NULL;
404                                 }
405                                 clause->data.catch_class = mono_class_from_mono_type (extype);
406                         } else {
407                                 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
408                                         clause->data.filter_offset = ex_block->filter_offset;
409                                 else
410                                         clause->data.filter_offset = 0;
411                         }
412                         finally_start = ex_block->start + ex_block->len;
413
414                         clause_index ++;
415                 }
416         }
417
418         return clauses;
419 }
420 #endif /* !DISABLE_REFLECTION_EMIT */
421
422 #ifndef DISABLE_REFLECTION_EMIT
423 /*
424  * LOCKING: Acquires the loader lock. 
425  */
426 static void
427 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
428 {
429         MONO_REQ_GC_UNSAFE_MODE;
430
431         MonoCustomAttrInfo *ainfo, *tmp;
432
433         if (!cattrs || !mono_array_length (cattrs))
434                 return;
435
436         ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
437
438         mono_loader_lock ();
439         tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
440         if (tmp)
441                 mono_custom_attrs_free (tmp);
442         mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
443         mono_loader_unlock ();
444
445 }
446 #endif
447
448
449 guint32
450 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
451 {
452         MONO_REQ_GC_UNSAFE_MODE;
453
454         MonoDynamicTable *table;
455         guint32 token;
456         guint32 *values;
457         guint32 cols [MONO_ASSEMBLY_SIZE];
458         const char *pubkey;
459         guint32 publen;
460
461         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
462                 return token;
463
464         if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
465                 table = &assembly->tables [MONO_TABLE_MODULEREF];
466                 token = table->next_idx ++;
467                 table->rows ++;
468                 alloc_table (table, table->rows);
469                 values = table->values + token * MONO_MODULEREF_SIZE;
470                 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
471
472                 token <<= MONO_RESOLUTION_SCOPE_BITS;
473                 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
474                 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
475
476                 return token;
477         }
478         
479         if (assembly_is_dynamic (image->assembly))
480                 /* FIXME: */
481                 memset (cols, 0, sizeof (cols));
482         else {
483                 /* image->assembly->image is the manifest module */
484                 image = image->assembly->image;
485                 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
486         }
487
488         table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
489         token = table->next_idx ++;
490         table->rows ++;
491         alloc_table (table, table->rows);
492         values = table->values + token * MONO_ASSEMBLYREF_SIZE;
493         values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
494         values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
495         values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
496         values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
497         values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
498         values [MONO_ASSEMBLYREF_FLAGS] = 0;
499         values [MONO_ASSEMBLYREF_CULTURE] = 0;
500         values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
501
502         if (strcmp ("", image->assembly->aname.culture)) {
503                 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
504                                 image->assembly->aname.culture);
505         }
506
507         if ((pubkey = mono_image_get_public_key (image, &publen))) {
508                 guchar pubtoken [9];
509                 pubtoken [0] = 8;
510                 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
511                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
512         } else {
513                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
514         }
515         token <<= MONO_RESOLUTION_SCOPE_BITS;
516         token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
517         g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
518         return token;
519 }
520
521 #ifndef DISABLE_REFLECTION_EMIT
522 gboolean
523 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
524 {
525         MONO_REQ_GC_UNSAFE_MODE;
526
527         mono_error_init (error);
528         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
529
530         rmb->ilgen = mb->ilgen;
531         rmb->rtype = mono_reflection_type_resolve_user_types ((MonoReflectionType*)mb->rtype, error);
532         return_val_if_nok (error, FALSE);
533         rmb->parameters = mb->parameters;
534         rmb->generic_params = mb->generic_params;
535         rmb->generic_container = mb->generic_container;
536         rmb->opt_types = NULL;
537         rmb->pinfo = mb->pinfo;
538         rmb->attrs = mb->attrs;
539         rmb->iattrs = mb->iattrs;
540         rmb->call_conv = mb->call_conv;
541         rmb->code = mb->code;
542         rmb->type = mb->type;
543         rmb->name = mb->name;
544         rmb->table_idx = &mb->table_idx;
545         rmb->init_locals = mb->init_locals;
546         rmb->skip_visibility = FALSE;
547         rmb->return_modreq = mb->return_modreq;
548         rmb->return_modopt = mb->return_modopt;
549         rmb->param_modreq = mb->param_modreq;
550         rmb->param_modopt = mb->param_modopt;
551         rmb->permissions = mb->permissions;
552         rmb->mhandle = mb->mhandle;
553         rmb->nrefs = 0;
554         rmb->refs = NULL;
555
556         if (mb->dll) {
557                 rmb->charset = mb->charset;
558                 rmb->extra_flags = mb->extra_flags;
559                 rmb->native_cc = mb->native_cc;
560                 rmb->dllentry = mb->dllentry;
561                 rmb->dll = mb->dll;
562         }
563
564         return TRUE;
565 }
566
567 gboolean
568 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
569 {
570         MONO_REQ_GC_UNSAFE_MODE;
571
572         const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
573
574         mono_error_init (error);
575
576         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
577
578         rmb->ilgen = mb->ilgen;
579         rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
580         return_val_if_nok (error, FALSE);
581         rmb->parameters = mb->parameters;
582         rmb->generic_params = NULL;
583         rmb->generic_container = NULL;
584         rmb->opt_types = NULL;
585         rmb->pinfo = mb->pinfo;
586         rmb->attrs = mb->attrs;
587         rmb->iattrs = mb->iattrs;
588         rmb->call_conv = mb->call_conv;
589         rmb->code = NULL;
590         rmb->type = mb->type;
591         rmb->name = mono_string_new (mono_domain_get (), name);
592         rmb->table_idx = &mb->table_idx;
593         rmb->init_locals = mb->init_locals;
594         rmb->skip_visibility = FALSE;
595         rmb->return_modreq = NULL;
596         rmb->return_modopt = NULL;
597         rmb->param_modreq = mb->param_modreq;
598         rmb->param_modopt = mb->param_modopt;
599         rmb->permissions = mb->permissions;
600         rmb->mhandle = mb->mhandle;
601         rmb->nrefs = 0;
602         rmb->refs = NULL;
603
604         return TRUE;
605 }
606
607 static void
608 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
609 {
610         MONO_REQ_GC_UNSAFE_MODE;
611
612         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
613
614         rmb->ilgen = mb->ilgen;
615         rmb->rtype = mb->rtype;
616         rmb->parameters = mb->parameters;
617         rmb->generic_params = NULL;
618         rmb->generic_container = NULL;
619         rmb->opt_types = NULL;
620         rmb->pinfo = NULL;
621         rmb->attrs = mb->attrs;
622         rmb->iattrs = 0;
623         rmb->call_conv = mb->call_conv;
624         rmb->code = NULL;
625         rmb->type = (MonoObject *) mb->owner;
626         rmb->name = mb->name;
627         rmb->table_idx = NULL;
628         rmb->init_locals = mb->init_locals;
629         rmb->skip_visibility = mb->skip_visibility;
630         rmb->return_modreq = NULL;
631         rmb->return_modopt = NULL;
632         rmb->param_modreq = NULL;
633         rmb->param_modopt = NULL;
634         rmb->permissions = NULL;
635         rmb->mhandle = mb->mhandle;
636         rmb->nrefs = 0;
637         rmb->refs = NULL;
638 }       
639 #else /* DISABLE_REFLECTION_EMIT */
640 gboolean
641 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
642         g_assert_not_reached ();
643         return FALSE;
644 }
645 gboolean
646 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
647 {
648         g_assert_not_reached ();
649         return FALSE;
650 }
651 #endif /* DISABLE_REFLECTION_EMIT */
652
653 #ifndef DISABLE_REFLECTION_EMIT
654 static guint32
655 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
656 {
657         MONO_REQ_GC_NEUTRAL_MODE;
658
659         MonoDynamicTable *table;
660         guint32 *values;
661         guint32 token, pclass;
662
663         switch (parent & MONO_TYPEDEFORREF_MASK) {
664         case MONO_TYPEDEFORREF_TYPEREF:
665                 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
666                 break;
667         case MONO_TYPEDEFORREF_TYPESPEC:
668                 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
669                 break;
670         case MONO_TYPEDEFORREF_TYPEDEF:
671                 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
672                 break;
673         default:
674                 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
675                 return 0;
676         }
677         /* extract the index */
678         parent >>= MONO_TYPEDEFORREF_BITS;
679
680         table = &assembly->tables [MONO_TABLE_MEMBERREF];
681
682         if (assembly->save) {
683                 alloc_table (table, table->rows + 1);
684                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
685                 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
686                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
687                 values [MONO_MEMBERREF_SIGNATURE] = sig;
688         }
689
690         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
691         table->next_idx ++;
692
693         return token;
694 }
695
696 /*
697  * Insert a memberef row into the metadata: the token that point to the memberref
698  * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
699  * mono_image_get_fieldref_token()).
700  * The sig param is an index to an already built signature.
701  */
702 static guint32
703 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
704 {
705         MONO_REQ_GC_NEUTRAL_MODE;
706
707         guint32 parent = mono_image_typedef_or_ref (assembly, type);
708         return mono_image_add_memberef_row (assembly, parent, name, sig);
709 }
710
711
712 static guint32
713 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
714 {
715         MONO_REQ_GC_NEUTRAL_MODE;
716
717         guint32 token;
718         MonoMethodSignature *sig;
719         
720         create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
721
722         if (create_typespec) {
723                 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
724                 if (token)
725                         return token;
726         } 
727
728         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
729         if (token && !create_typespec)
730                 return token;
731
732         g_assert (!method->is_inflated);
733         if (!token) {
734                 /*
735                  * A methodref signature can't contain an unmanaged calling convention.
736                  */
737                 sig = mono_metadata_signature_dup (mono_method_signature (method));
738                 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
739                         sig->call_convention = MONO_CALL_DEFAULT;
740                 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
741                         method->name,  mono_dynimage_encode_method_signature (assembly, sig));
742                 g_free (sig);
743                 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
744         }
745
746         if (create_typespec) {
747                 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
748                 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
749                 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
750
751                 if (assembly->save) {
752                         guint32 *values;
753
754                         alloc_table (table, table->rows + 1);
755                         values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
756                         values [MONO_METHODSPEC_METHOD] = token;
757                         values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
758                 }
759
760                 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
761                 table->next_idx ++;
762                 /*methodspec and memberef tokens are diferent, */
763                 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
764                 return token;
765         }
766         return token;
767 }
768
769 static guint32
770 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
771 {
772         guint32 token, parent, sig;
773         ReflectionMethodBuilder rmb;
774         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
775         
776         mono_error_init (error);
777         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
778         if (token)
779                 return token;
780
781         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
782                 return 0;
783
784         /*
785          * A methodref signature can't contain an unmanaged calling convention.
786          * Since some flags are encoded as part of call_conv, we need to check against it.
787         */
788         if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
789                 rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
790
791         sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
792         return_val_if_nok (error, 0);
793
794         if (tb->generic_params) {
795                 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
796                 return_val_if_nok (error, 0);
797         } else {
798                 MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
799                 return_val_if_nok (error, 0);
800
801                 parent = mono_image_typedef_or_ref (assembly, t);
802         }
803
804         char *name = mono_string_to_utf8_checked (method->name, error);
805         return_val_if_nok (error, 0);
806
807         token = mono_image_add_memberef_row (assembly, parent, name, sig);
808         g_free (name);
809
810         g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
811
812         return token;
813 }
814
815 static guint32
816 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
817                                      const gchar *name, guint32 sig)
818 {
819         MonoDynamicTable *table;
820         guint32 token;
821         guint32 *values;
822         
823         table = &assembly->tables [MONO_TABLE_MEMBERREF];
824
825         if (assembly->save) {
826                 alloc_table (table, table->rows + 1);
827                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
828                 values [MONO_MEMBERREF_CLASS] = original;
829                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
830                 values [MONO_MEMBERREF_SIGNATURE] = sig;
831         }
832
833         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
834         table->next_idx ++;
835
836         return token;
837 }
838
839 static guint32
840 mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
841 {
842         MonoDynamicTable *table;
843         guint32 *values;
844         guint32 token, mtoken = 0;
845
846         mono_error_init (error);
847         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
848         if (token)
849                 return token;
850
851         table = &assembly->tables [MONO_TABLE_METHODSPEC];
852
853         mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
854         if (!mono_error_ok (error))
855                 return 0;
856
857         switch (mono_metadata_token_table (mtoken)) {
858         case MONO_TABLE_MEMBERREF:
859                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
860                 break;
861         case MONO_TABLE_METHOD:
862                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
863                 break;
864         default:
865                 g_assert_not_reached ();
866         }
867
868         if (assembly->save) {
869                 alloc_table (table, table->rows + 1);
870                 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
871                 values [MONO_METHODSPEC_METHOD] = mtoken;
872                 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
873         }
874
875         token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
876         table->next_idx ++;
877
878         mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
879         return token;
880 }
881
882 static guint32
883 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
884 {
885         guint32 token;
886
887         mono_error_init (error);
888
889         if (mb->generic_params && create_methodspec) 
890                 return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
891
892         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
893         if (token)
894                 return token;
895
896         token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
897         if (!mono_error_ok (error))
898                 return 0;
899         mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
900         return token;
901 }
902
903 static guint32
904 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
905 {
906         guint32 token, parent, sig;
907         ReflectionMethodBuilder rmb;
908         char *name;
909         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
910         
911         mono_error_init (error);
912         
913         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
914         if (token)
915                 return token;
916
917         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
918                 return 0;
919
920         if (tb->generic_params) {
921                 parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
922                 return_val_if_nok (error, 0);
923         } else {
924                 MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
925                 return_val_if_nok (error, 0);
926                 parent = mono_image_typedef_or_ref (assembly, type);
927         }
928         
929         name = mono_string_to_utf8_checked (rmb.name, error);
930         return_val_if_nok (error, 0);
931         sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
932         return_val_if_nok (error, 0);
933
934         token = mono_image_add_memberef_row (assembly, parent, name, sig);
935
936         g_free (name);
937         mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
938         return token;
939 }
940 #endif
941
942 static gboolean
943 is_field_on_inst (MonoClassField *field)
944 {
945         return field->parent->generic_class && field->parent->generic_class->is_dynamic;
946 }
947
948 #ifndef DISABLE_REFLECTION_EMIT
949 static guint32
950 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
951 {
952         MonoType *type;
953         guint32 token;
954
955         g_assert (field);
956         g_assert (field->parent);
957
958         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
959         if (token)
960                 return token;
961
962         if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
963                 int index = field - field->parent->fields;
964                 type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
965         } else {
966                 type = mono_field_get_type (field);
967         }
968         token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
969                                                                                         mono_field_get_name (field),
970                                                                                         mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
971         mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
972         return token;
973 }
974
975 static guint32
976 mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
977 {
978         guint32 token;
979         MonoClass *klass;
980         MonoGenericClass *gclass;
981         MonoType *type;
982         char *name;
983
984         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
985         if (token)
986                 return token;
987         if (is_sre_field_builder (mono_object_class (f->fb))) {
988                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
989                 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
990                 return_val_if_nok (error, 0);
991                 klass = mono_class_from_mono_type (type);
992                 gclass = type->data.generic_class;
993                 g_assert (gclass->is_dynamic);
994
995                 guint32 sig_token = mono_dynimage_encode_field_signature (assembly, fb, error);
996                 return_val_if_nok (error, 0);
997                 name = mono_string_to_utf8_checked (fb->name, error);
998                 return_val_if_nok (error, 0);
999                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
1000                 g_free (name);          
1001         } else if (is_sr_mono_field (mono_object_class (f->fb))) {
1002                 guint32 sig;
1003                 MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
1004
1005                 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
1006                 return_val_if_nok (error, 0);
1007                 klass = mono_class_from_mono_type (type);
1008
1009                 sig = mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, field->type);
1010                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
1011         } else {
1012                 char *name = mono_type_get_full_name (mono_object_class (f->fb));
1013                 g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
1014         }
1015
1016         mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
1017         return token;
1018 }
1019
1020 static guint32
1021 mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
1022 {
1023         guint32 sig, token;
1024         MonoClass *klass;
1025         MonoGenericClass *gclass;
1026         MonoType *type;
1027
1028         mono_error_init (error);
1029
1030         /* A ctor cannot be a generic method, so we can ignore create_methodspec */
1031
1032         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
1033         if (token)
1034                 return token;
1035
1036         if (mono_is_sre_ctor_builder (mono_object_class (c->cb))) {
1037                 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
1038                 ReflectionMethodBuilder rmb;
1039                 char *name;
1040
1041                 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
1042                 return_val_if_nok (error, 0);
1043                 klass = mono_class_from_mono_type (type);
1044
1045                 gclass = type->data.generic_class;
1046                 g_assert (gclass->is_dynamic);
1047
1048                 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
1049                         return 0;
1050
1051                 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1052                 return_val_if_nok (error, 0);
1053
1054                 name = mono_string_to_utf8_checked (rmb.name, error);
1055                 return_val_if_nok (error, 0);
1056
1057                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1058                 g_free (name);
1059         } else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb))) {
1060                 MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
1061
1062                 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
1063                 return_val_if_nok (error, 0);
1064                 klass = mono_class_from_mono_type (type);
1065
1066                 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1067                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1068         } else {
1069                 char *name = mono_type_get_full_name (mono_object_class (c->cb));
1070                 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1071         }
1072
1073
1074         mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
1075         return token;
1076 }
1077
1078 MonoMethod*
1079 mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
1080 {
1081         MonoClass *klass;
1082         MonoGenericContext tmp_context;
1083         MonoType **type_argv;
1084         MonoGenericInst *ginst;
1085         MonoMethod *method, *inflated;
1086         int count, i;
1087
1088         mono_error_init (error);
1089
1090         mono_reflection_init_type_builder_generics ((MonoObject*)m->inst, error);
1091         return_val_if_nok (error, NULL);
1092
1093         method = inflate_method (m->inst, (MonoObject*)m->mb, error);
1094         return_val_if_nok (error, NULL);
1095
1096         klass = method->klass;
1097
1098         if (m->method_args == NULL)
1099                 return method;
1100
1101         if (method->is_inflated)
1102                 method = ((MonoMethodInflated *) method)->declaring;
1103
1104         count = mono_array_length (m->method_args);
1105
1106         type_argv = g_new0 (MonoType *, count);
1107         for (i = 0; i < count; i++) {
1108                 MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
1109                 type_argv [i] = mono_reflection_type_get_handle (garg, error);
1110                 return_val_if_nok (error, NULL);
1111         }
1112         ginst = mono_metadata_get_generic_inst (count, type_argv);
1113         g_free (type_argv);
1114
1115         tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
1116         tmp_context.method_inst = ginst;
1117
1118         inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
1119         mono_error_assert_ok (error);
1120         return inflated;
1121 }
1122
1123 static guint32
1124 mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
1125 {
1126         guint32 sig, token = 0;
1127         MonoType *type;
1128         MonoClass *klass;
1129
1130         mono_error_init (error);
1131
1132         if (m->method_args) {
1133                 MonoMethod *inflated;
1134
1135                 inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
1136                 return_val_if_nok (error, 0);
1137
1138                 if (create_methodspec)
1139                         token = mono_image_get_methodspec_token (assembly, inflated);
1140                 else
1141                         token = mono_image_get_inflated_method_token (assembly, inflated);
1142                 return token;
1143         }
1144
1145         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
1146         if (token)
1147                 return token;
1148
1149         if (is_sre_method_builder (mono_object_class (m->mb))) {
1150                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
1151                 MonoGenericClass *gclass;
1152                 ReflectionMethodBuilder rmb;
1153                 char *name;
1154
1155                 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1156                 return_val_if_nok (error, 0);
1157                 klass = mono_class_from_mono_type (type);
1158                 gclass = type->data.generic_class;
1159                 g_assert (gclass->is_dynamic);
1160
1161                 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1162                         return 0;
1163
1164                 sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1165                 return_val_if_nok (error, 0);
1166
1167                 name = mono_string_to_utf8_checked (rmb.name, error);
1168                 return_val_if_nok (error, 0);
1169
1170                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
1171                 g_free (name);          
1172         } else if (is_sr_mono_method (mono_object_class (m->mb))) {
1173                 MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
1174
1175                 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
1176                 return_val_if_nok (error, 0);
1177                 klass = mono_class_from_mono_type (type);
1178
1179                 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (mm));
1180                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
1181         } else {
1182                 char *name = mono_type_get_full_name (mono_object_class (m->mb));
1183                 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
1184         }
1185
1186         mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
1187         return token;
1188 }
1189
1190 static guint32
1191 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
1192 {
1193         MonoDynamicTable *table;
1194         guint32 *values;
1195         guint32 token, mtoken = 0, sig;
1196         MonoMethodInflated *imethod;
1197         MonoMethod *declaring;
1198
1199         table = &assembly->tables [MONO_TABLE_METHODSPEC];
1200
1201         g_assert (method->is_inflated);
1202         imethod = (MonoMethodInflated *) method;
1203         declaring = imethod->declaring;
1204
1205         sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
1206         mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
1207
1208         if (!mono_method_signature (declaring)->generic_param_count)
1209                 return mtoken;
1210
1211         switch (mono_metadata_token_table (mtoken)) {
1212         case MONO_TABLE_MEMBERREF:
1213                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
1214                 break;
1215         case MONO_TABLE_METHOD:
1216                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
1217                 break;
1218         default:
1219                 g_assert_not_reached ();
1220         }
1221
1222         sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
1223
1224         if (assembly->save) {
1225                 alloc_table (table, table->rows + 1);
1226                 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
1227                 values [MONO_METHODSPEC_METHOD] = mtoken;
1228                 values [MONO_METHODSPEC_SIGNATURE] = sig;
1229         }
1230
1231         token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
1232         table->next_idx ++;
1233
1234         return token;
1235 }
1236
1237 static guint32
1238 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
1239 {
1240         MonoMethodInflated *imethod;
1241         guint32 token;
1242         
1243         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
1244         if (token)
1245                 return token;
1246
1247         g_assert (method->is_inflated);
1248         imethod = (MonoMethodInflated *) method;
1249
1250         if (mono_method_signature (imethod->declaring)->generic_param_count) {
1251                 token = method_encode_methodspec (assembly, method);
1252         } else {
1253                 guint32 sig = mono_dynimage_encode_method_signature (
1254                         assembly, mono_method_signature (imethod->declaring));
1255                 token = mono_image_get_memberref_token (
1256                         assembly, &method->klass->byval_arg, method->name, sig);
1257         }
1258
1259         g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
1260         return token;
1261 }
1262
1263 static guint32
1264 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
1265 {
1266         MonoMethodInflated *imethod = (MonoMethodInflated *) m;
1267         guint32 sig, token;
1268
1269         sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
1270         token = mono_image_get_memberref_token (
1271                 assembly, &m->klass->byval_arg, m->name, sig);
1272
1273         return token;
1274 }
1275
1276 /*
1277  * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
1278  */
1279 static MonoType*
1280 add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
1281 {
1282         int i, count, len, pos;
1283         MonoType *t;
1284
1285         mono_error_init (error);
1286
1287         count = 0;
1288         if (modreq)
1289                 count += mono_array_length (modreq);
1290         if (modopt)
1291                 count += mono_array_length (modopt);
1292
1293         if (count == 0)
1294                 return mono_metadata_type_dup (NULL, type);
1295
1296         len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
1297         t = (MonoType *)g_malloc (len);
1298         memcpy (t, type, MONO_SIZEOF_TYPE);
1299
1300         t->num_mods = count;
1301         pos = 0;
1302         if (modreq) {
1303                 for (i = 0; i < mono_array_length (modreq); ++i) {
1304                         MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
1305                         if (!is_ok (error))
1306                                 goto fail;
1307                         t->modifiers [pos].required = 1;
1308                         t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1309                         pos ++;
1310                 }
1311         }
1312         if (modopt) {
1313                 for (i = 0; i < mono_array_length (modopt); ++i) {
1314                         MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
1315                         if (!is_ok (error))
1316                                 goto fail;
1317                         t->modifiers [pos].required = 0;
1318                         t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
1319                         pos ++;
1320                 }
1321         }
1322
1323         return t;
1324 fail:
1325         g_free (t);
1326         return NULL;
1327 }
1328
1329 void
1330 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
1331 {
1332         MonoReflectionTypeBuilder *tb;
1333
1334         mono_error_init (error);
1335
1336         if (!is_sre_type_builder(mono_object_class (type)))
1337                 return;
1338         tb = (MonoReflectionTypeBuilder *)type;
1339
1340         if (tb && tb->generic_container)
1341                 mono_reflection_create_generic_class (tb, error);
1342 }
1343
1344 static guint32
1345 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
1346 {
1347         MonoDynamicTable *table;
1348         MonoType *custom = NULL, *type;
1349         guint32 *values;
1350         guint32 token, pclass, parent, sig;
1351         gchar *name;
1352
1353         mono_error_init (error);
1354
1355         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
1356         if (token)
1357                 return token;
1358
1359         MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
1360         return_val_if_nok (error, 0);
1361         /* FIXME: is this call necessary? */
1362         mono_class_from_mono_type (typeb);
1363
1364         /*FIXME this is one more layer of ugliness due how types are created.*/
1365         mono_reflection_init_type_builder_generics (fb->type, error);
1366         return_val_if_nok (error, 0);
1367
1368         /* fb->type does not include the custom modifiers */
1369         /* FIXME: We should do this in one place when a fieldbuilder is created */
1370         type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1371         return_val_if_nok (error, 0);
1372
1373         if (fb->modreq || fb->modopt) {
1374                 type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
1375                 return_val_if_nok (error, 0);
1376         }
1377
1378         sig = mono_dynimage_encode_fieldref_signature (assembly, NULL, type);
1379         g_free (custom);
1380
1381         parent = mono_dynimage_encode_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
1382         return_val_if_nok (error, 0);
1383         g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
1384         
1385         pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
1386         parent >>= MONO_TYPEDEFORREF_BITS;
1387
1388         table = &assembly->tables [MONO_TABLE_MEMBERREF];
1389
1390         name = mono_string_to_utf8_checked (fb->name, error);
1391         return_val_if_nok (error, 0);
1392
1393         if (assembly->save) {
1394                 alloc_table (table, table->rows + 1);
1395                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
1396                 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
1397                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
1398                 values [MONO_MEMBERREF_SIGNATURE] = sig;
1399         }
1400
1401         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
1402         table->next_idx ++;
1403         mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
1404         g_free (name);
1405         return token;
1406 }
1407
1408 static guint32 
1409 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
1410 {
1411         guint32 idx;
1412         MonoDynamicTable *table;
1413         guint32 *values;
1414
1415         mono_error_init (error);
1416
1417         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
1418         idx = table->next_idx ++;
1419         table->rows ++;
1420         alloc_table (table, table->rows);
1421         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
1422
1423         values [MONO_STAND_ALONE_SIGNATURE] =
1424                 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
1425         return_val_if_nok (error, 0);
1426         
1427         return idx;
1428 }
1429
1430 static int
1431 reflection_cc_to_file (int call_conv) {
1432         switch (call_conv & 0x3) {
1433         case 0:
1434         case 1: return MONO_CALL_DEFAULT;
1435         case 2: return MONO_CALL_VARARG;
1436         default:
1437                 g_assert_not_reached ();
1438         }
1439         return 0;
1440 }
1441 #endif /* !DISABLE_REFLECTION_EMIT */
1442
1443 struct _ArrayMethod {
1444         MonoType *parent;
1445         MonoMethodSignature *sig;
1446         char *name;
1447         guint32 token;
1448 };
1449
1450 void
1451 mono_sre_array_method_free (ArrayMethod *am)
1452 {
1453         g_free (am->sig);
1454         g_free (am->name);
1455         g_free (am);
1456 }
1457
1458 #ifndef DISABLE_REFLECTION_EMIT
1459 static guint32
1460 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
1461 {
1462         guint32 nparams, i;
1463         GList *tmp;
1464         char *name = NULL;
1465         MonoMethodSignature *sig;
1466         ArrayMethod *am = NULL;
1467         MonoType *mtype;
1468
1469         mono_error_init (error);
1470
1471         nparams = mono_array_length (m->parameters);
1472         sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
1473         sig->hasthis = 1;
1474         sig->sentinelpos = -1;
1475         sig->call_convention = reflection_cc_to_file (m->call_conv);
1476         sig->param_count = nparams;
1477         if (m->ret) {
1478                 sig->ret = mono_reflection_type_get_handle (m->ret, error);
1479                 if (!is_ok (error))
1480                         goto fail;
1481         } else
1482                 sig->ret = &mono_defaults.void_class->byval_arg;
1483
1484         mtype = mono_reflection_type_get_handle (m->parent, error);
1485         if (!is_ok (error))
1486                 goto fail;
1487
1488         for (i = 0; i < nparams; ++i) {
1489                 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
1490                 if (!is_ok (error))
1491                         goto fail;
1492         }
1493
1494         name = mono_string_to_utf8_checked (m->name, error);
1495         if (!is_ok (error))
1496                 goto fail;
1497         for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
1498                 am = (ArrayMethod *)tmp->data;
1499                 if (strcmp (name, am->name) == 0 && 
1500                                 mono_metadata_type_equal (am->parent, mtype) &&
1501                                 mono_metadata_signature_equal (am->sig, sig)) {
1502                         g_free (name);
1503                         g_free (sig);
1504                         m->table_idx = am->token & 0xffffff;
1505                         return am->token;
1506                 }
1507         }
1508         am = g_new0 (ArrayMethod, 1);
1509         am->name = name;
1510         am->sig = sig;
1511         am->parent = mtype;
1512         am->token = mono_image_get_memberref_token (assembly, am->parent, name,
1513                 mono_dynimage_encode_method_signature (assembly, sig));
1514         assembly->array_methods = g_list_prepend (assembly->array_methods, am);
1515         m->table_idx = am->token & 0xffffff;
1516         return am->token;
1517 fail:
1518         g_free (am);
1519         g_free (name);
1520         g_free (sig);
1521         return 0;
1522
1523 }
1524 #endif
1525
1526 #ifndef DISABLE_REFLECTION_EMIT
1527
1528 /*
1529  * mono_image_insert_string:
1530  * @module: module builder object
1531  * @str: a string
1532  *
1533  * Insert @str into the user string stream of @module.
1534  */
1535 guint32
1536 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
1537 {
1538         MonoDynamicImage *assembly;
1539         guint32 idx;
1540         char buf [16];
1541         char *b = buf;
1542         
1543         if (!module->dynamic_image)
1544                 mono_image_module_basic_init (module);
1545
1546         assembly = module->dynamic_image;
1547         
1548         if (assembly->save) {
1549                 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
1550                 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1551 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1552         {
1553                 char *swapped = g_malloc (2 * mono_string_length (str));
1554                 const char *p = (const char*)mono_string_chars (str);
1555
1556                 swap_with_size (swapped, p, 2, mono_string_length (str));
1557                 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
1558                 g_free (swapped);
1559         }
1560 #else
1561                 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
1562 #endif
1563                 mono_image_add_stream_data (&assembly->us, "", 1);
1564         } else {
1565                 idx = assembly->us.index ++;
1566         }
1567
1568         mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
1569
1570         return MONO_TOKEN_STRING | idx;
1571 }
1572
1573 guint32
1574 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
1575 {
1576         MonoClass *klass;
1577         guint32 token = 0;
1578         MonoMethodSignature *sig;
1579
1580         mono_error_init (error);
1581
1582         klass = obj->vtable->klass;
1583         if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1584                 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1585                 MonoMethodSignature *old;
1586                 guint32 sig_token, parent;
1587                 int nargs, i;
1588
1589                 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1590
1591                 nargs = mono_array_length (opt_param_types);
1592                 old = mono_method_signature (method);
1593                 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1594
1595                 sig->hasthis = old->hasthis;
1596                 sig->explicit_this = old->explicit_this;
1597                 sig->call_convention = old->call_convention;
1598                 sig->generic_param_count = old->generic_param_count;
1599                 sig->param_count = old->param_count + nargs;
1600                 sig->sentinelpos = old->param_count;
1601                 sig->ret = old->ret;
1602
1603                 for (i = 0; i < old->param_count; i++)
1604                         sig->params [i] = old->params [i];
1605
1606                 for (i = 0; i < nargs; i++) {
1607                         MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1608                         sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1609                         if (!is_ok (error)) goto fail;
1610                 }
1611
1612                 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1613                 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1614                 parent >>= MONO_TYPEDEFORREF_BITS;
1615
1616                 parent <<= MONO_MEMBERREF_PARENT_BITS;
1617                 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1618
1619                 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1620                 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1621         } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1622                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1623                 ReflectionMethodBuilder rmb;
1624                 guint32 parent, sig_token;
1625                 int nopt_args, nparams, ngparams, i;
1626
1627                 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1628                         goto fail;
1629                 
1630                 rmb.opt_types = opt_param_types;
1631                 nopt_args = mono_array_length (opt_param_types);
1632
1633                 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1634                 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1635                 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1636
1637                 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1638                 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1639                 sig->call_convention = rmb.call_conv;
1640                 sig->generic_param_count = ngparams;
1641                 sig->param_count = nparams + nopt_args;
1642                 sig->sentinelpos = nparams;
1643                 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1644                 if (!is_ok (error)) goto fail;
1645
1646                 for (i = 0; i < nparams; i++) {
1647                         MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1648                         sig->params [i] = mono_reflection_type_get_handle (rt, error);
1649                         if (!is_ok (error)) goto fail;
1650                 }
1651
1652                 for (i = 0; i < nopt_args; i++) {
1653                         MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1654                         sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1655                         if (!is_ok (error)) goto fail;
1656                 }
1657
1658                 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1659                 if (!is_ok (error))
1660                         goto fail;
1661
1662                 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1663                 if (!mono_error_ok (error))
1664                         goto fail;
1665                 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1666
1667                 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1668                 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1669
1670                 char *name = mono_string_to_utf8_checked (rmb.name, error);
1671                 if (!is_ok (error)) goto fail;
1672                 token = mono_image_get_varargs_method_token (
1673                         assembly, parent, name, sig_token);
1674                 g_free (name);
1675         } else {
1676                 g_error ("requested method token for %s\n", klass->name);
1677         }
1678
1679         g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1680         mono_dynamic_image_register_token (assembly, token, obj);
1681         return token;
1682 fail:
1683         g_assert (!mono_error_ok (error));
1684         return 0;
1685 }
1686
1687 /*
1688  * mono_image_create_token:
1689  * @assembly: a dynamic assembly
1690  * @obj:
1691  * @register_token: Whenever to register the token in the assembly->tokens hash. 
1692  *
1693  * Get a token to insert in the IL code stream for the given MemberInfo.
1694  * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, 
1695  * the table_idx-es were recomputed, so registering the token would overwrite an existing 
1696  * entry.
1697  */
1698 guint32
1699 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
1700                          gboolean create_open_instance, gboolean register_token,
1701                          MonoError *error)
1702 {
1703         MonoClass *klass;
1704         guint32 token = 0;
1705
1706         mono_error_init (error);
1707
1708         klass = obj->vtable->klass;
1709
1710         /* Check for user defined reflection objects */
1711         /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1712         if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1713                 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1714                 return 0;
1715         }
1716
1717         if (strcmp (klass->name, "MethodBuilder") == 0) {
1718                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1719                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1720
1721                 if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
1722                         token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1723                 else {
1724                         token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
1725                         if (!mono_error_ok (error))
1726                                 return 0;
1727                 }
1728                 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1729         } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
1730                 MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
1731                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
1732
1733                 if (tb->module->dynamic_image == assembly && !tb->generic_params)
1734                         token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
1735                 else {
1736                         token = mono_image_get_ctorbuilder_token (assembly, mb, error);
1737                         if (!mono_error_ok (error))
1738                                 return 0;
1739                 }
1740                 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
1741         } else if (strcmp (klass->name, "FieldBuilder") == 0) {
1742                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
1743                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
1744                 if (tb->generic_params) {
1745                         token = mono_image_get_generic_field_token (assembly, fb, error);
1746                         return_val_if_nok (error, 0);
1747                 } else {
1748                         if (tb->module->dynamic_image == assembly) {
1749                                 token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
1750                         } else {
1751                                 token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
1752                         }
1753                 }
1754         } else if (strcmp (klass->name, "TypeBuilder") == 0) {
1755                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
1756                 if (create_open_instance && tb->generic_params) {
1757                         MonoType *type;
1758                         mono_reflection_init_type_builder_generics (obj, error);
1759                         return_val_if_nok (error, 0);
1760                         type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1761                         return_val_if_nok (error, 0);
1762                         token = mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
1763                         token = mono_metadata_token_from_dor (token);
1764                 } else if (tb->module->dynamic_image == assembly) {
1765                         token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
1766                 } else {
1767                         MonoType *type;
1768                         type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1769                         return_val_if_nok (error, 0);
1770                         token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
1771                 }
1772         } else if (strcmp (klass->name, "RuntimeType") == 0) {
1773                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1774                 return_val_if_nok (error, 0);
1775                 MonoClass *mc = mono_class_from_mono_type (type);
1776                 token = mono_metadata_token_from_dor (
1777                         mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
1778         } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
1779                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1780                 return_val_if_nok (error, 0);
1781                 token = mono_metadata_token_from_dor (
1782                         mono_image_typedef_or_ref (assembly, type));
1783         } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
1784                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1785                 return_val_if_nok (error, 0);
1786                 token = mono_metadata_token_from_dor (
1787                         mono_image_typedef_or_ref (assembly, type));
1788         } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1789                    strcmp (klass->name, "MonoMethod") == 0 ||
1790                    strcmp (klass->name, "MonoGenericMethod") == 0 ||
1791                    strcmp (klass->name, "MonoGenericCMethod") == 0) {
1792                 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1793                 if (m->method->is_inflated) {
1794                         if (create_open_instance)
1795                                 token = mono_image_get_methodspec_token (assembly, m->method);
1796                         else
1797                                 token = mono_image_get_inflated_method_token (assembly, m->method);
1798                 } else if ((m->method->klass->image == &assembly->image) &&
1799                          !m->method->klass->generic_class) {
1800                         static guint32 method_table_idx = 0xffffff;
1801                         if (m->method->klass->wastypebuilder) {
1802                                 /* we use the same token as the one that was assigned
1803                                  * to the Methodbuilder.
1804                                  * FIXME: do the equivalent for Fields.
1805                                  */
1806                                 token = m->method->token;
1807                         } else {
1808                                 /*
1809                                  * Each token should have a unique index, but the indexes are
1810                                  * assigned by managed code, so we don't know about them. An
1811                                  * easy solution is to count backwards...
1812                                  */
1813                                 method_table_idx --;
1814                                 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1815                         }
1816                 } else {
1817                         token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1818                 }
1819                 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1820         } else if (strcmp (klass->name, "MonoField") == 0) {
1821                 MonoReflectionField *f = (MonoReflectionField *)obj;
1822                 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1823                         static guint32 field_table_idx = 0xffffff;
1824                         field_table_idx --;
1825                         token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1826                 } else {
1827                         token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1828                 }
1829                 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1830         } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1831                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1832                 token = mono_image_get_array_token (assembly, m, error);
1833                 return_val_if_nok (error, 0);
1834         } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1835                 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1836                 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1837                 return_val_if_nok (error, 0);
1838         } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1839                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1840                 return_val_if_nok (error, 0);
1841                 token = mono_metadata_token_from_dor (
1842                         mono_image_typedef_or_ref (assembly, type));
1843         } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
1844                 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
1845                 token = mono_image_get_field_on_inst_token (assembly, f, error);
1846                 return_val_if_nok (error, 0);
1847         } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
1848                 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
1849                 token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
1850                 if (!mono_error_ok (error))
1851                         return 0;
1852         } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
1853                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
1854                 token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
1855                 if (!mono_error_ok (error))
1856                         return 0;
1857         } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
1858                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1859                 return_val_if_nok (error, 0);
1860                 token = mono_metadata_token_from_dor (
1861                                 mono_image_typedef_or_ref (assembly, type));
1862         } else {
1863                 g_error ("requested token for %s\n", klass->name);
1864         }
1865
1866         if (register_token)
1867                 mono_image_register_token (assembly, token, obj);
1868
1869         return token;
1870 }
1871
1872
1873 #endif
1874
1875 #ifndef DISABLE_REFLECTION_EMIT
1876
1877 /*
1878  * mono_reflection_dynimage_basic_init:
1879  * @assembly: an assembly builder object
1880  *
1881  * Create the MonoImage that represents the assembly builder and setup some
1882  * of the helper hash table and the basic metadata streams.
1883  */
1884 void
1885 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1886 {
1887         MonoError error;
1888         MonoDynamicAssembly *assembly;
1889         MonoDynamicImage *image;
1890         MonoDomain *domain = mono_object_domain (assemblyb);
1891         
1892         if (assemblyb->dynamic_assembly)
1893                 return;
1894
1895 #if HAVE_BOEHM_GC
1896         /* assembly->assembly.image might be GC allocated */
1897         assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1898 #else
1899         assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1900 #endif
1901
1902         mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1903         
1904         assembly->assembly.ref_count = 1;
1905         assembly->assembly.dynamic = TRUE;
1906         assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1907         assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1908         assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1909         if (mono_error_set_pending_exception (&error))
1910                 return;
1911         if (assemblyb->culture) {
1912                 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1913                 if (mono_error_set_pending_exception (&error))
1914                         return;
1915         } else
1916                 assembly->assembly.aname.culture = g_strdup ("");
1917
1918         if (assemblyb->version) {
1919                         char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1920                         if (mono_error_set_pending_exception (&error))
1921                                 return;
1922                         char **version = g_strsplit (vstr, ".", 4);
1923                         char **parts = version;
1924                         assembly->assembly.aname.major = atoi (*parts++);
1925                         assembly->assembly.aname.minor = atoi (*parts++);
1926                         assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1927                         assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1928
1929                         g_strfreev (version);
1930                         g_free (vstr);
1931         } else {
1932                         assembly->assembly.aname.major = 0;
1933                         assembly->assembly.aname.minor = 0;
1934                         assembly->assembly.aname.build = 0;
1935                         assembly->assembly.aname.revision = 0;
1936         }
1937
1938         assembly->run = assemblyb->access != 2;
1939         assembly->save = assemblyb->access != 1;
1940         assembly->domain = domain;
1941
1942         char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1943         if (mono_error_set_pending_exception (&error))
1944                 return;
1945         image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1946         image->initial_image = TRUE;
1947         assembly->assembly.aname.name = image->image.name;
1948         assembly->assembly.image = &image->image;
1949         if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1950                 /* -1 to correct for the trailing NULL byte */
1951                 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1952                         g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1953                 }
1954                 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);           
1955         }
1956
1957         mono_domain_assemblies_lock (domain);
1958         domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1959         mono_domain_assemblies_unlock (domain);
1960
1961         register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1962         
1963         mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1964         
1965         mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1966 }
1967
1968 #endif /* !DISABLE_REFLECTION_EMIT */
1969
1970 #ifndef DISABLE_REFLECTION_EMIT
1971
1972 MonoReflectionModule *
1973 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
1974 {
1975         char *name;
1976         MonoImage *image;
1977         MonoImageOpenStatus status;
1978         MonoDynamicAssembly *assembly;
1979         guint32 module_count;
1980         MonoImage **new_modules;
1981         gboolean *new_modules_loaded;
1982         
1983         mono_error_init (error);
1984         
1985         name = mono_string_to_utf8_checked (fileName, error);
1986         return_val_if_nok (error, NULL);
1987
1988         image = mono_image_open (name, &status);
1989         if (!image) {
1990                 if (status == MONO_IMAGE_ERROR_ERRNO)
1991                         mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
1992                 else
1993                         mono_error_set_bad_image_name (error, name, NULL);
1994                 g_free (name);
1995                 return NULL;
1996         }
1997
1998         g_free (name);
1999
2000         assembly = ab->dynamic_assembly;
2001         image->assembly = (MonoAssembly*)assembly;
2002
2003         module_count = image->assembly->image->module_count;
2004         new_modules = g_new0 (MonoImage *, module_count + 1);
2005         new_modules_loaded = g_new0 (gboolean, module_count + 1);
2006
2007         if (image->assembly->image->modules)
2008                 memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
2009         if (image->assembly->image->modules_loaded)
2010                 memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
2011         new_modules [module_count] = image;
2012         new_modules_loaded [module_count] = TRUE;
2013         mono_image_addref (image);
2014
2015         g_free (image->assembly->image->modules);
2016         image->assembly->image->modules = new_modules;
2017         image->assembly->image->modules_loaded = new_modules_loaded;
2018         image->assembly->image->module_count ++;
2019
2020         mono_assembly_load_references (image, &status);
2021         if (status) {
2022                 mono_image_close (image);
2023                 mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
2024                 return NULL;
2025         }
2026
2027         return mono_module_get_object_checked (mono_domain_get (), image, error);
2028 }
2029
2030 #endif /* DISABLE_REFLECTION_EMIT */
2031
2032 #ifndef DISABLE_REFLECTION_EMIT
2033 static gpointer
2034 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
2035 {
2036         CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
2037 }
2038
2039 static gpointer
2040 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
2041 {
2042         CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
2043 }
2044
2045 static gboolean
2046 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
2047 {
2048         MonoDynamicImage *image = moduleb->dynamic_image;
2049         MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
2050         mono_error_init (error);
2051         if (!image) {
2052                 int module_count;
2053                 MonoImage **new_modules;
2054                 MonoImage *ass;
2055                 char *name, *fqname;
2056                 /*
2057                  * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
2058                  * we don't know which module it belongs to, since that is only 
2059                  * determined at assembly save time.
2060                  */
2061                 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
2062                 name = mono_string_to_utf8_checked (ab->name, error);
2063                 return_val_if_nok (error, FALSE);
2064                 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
2065                 if (!is_ok (error)) {
2066                         g_free (name);
2067                         return FALSE;
2068                 }
2069                 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
2070
2071                 moduleb->module.image = &image->image;
2072                 moduleb->dynamic_image = image;
2073                 register_module (mono_object_domain (moduleb), moduleb, image);
2074
2075                 /* register the module with the assembly */
2076                 ass = ab->dynamic_assembly->assembly.image;
2077                 module_count = ass->module_count;
2078                 new_modules = g_new0 (MonoImage *, module_count + 1);
2079
2080                 if (ass->modules)
2081                         memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
2082                 new_modules [module_count] = &image->image;
2083                 mono_image_addref (&image->image);
2084
2085                 g_free (ass->modules);
2086                 ass->modules = new_modules;
2087                 ass->module_count ++;
2088         }
2089         return TRUE;
2090 }
2091
2092 static void
2093 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
2094 {
2095         MonoError error;
2096         (void) image_module_basic_init (moduleb, &error);
2097         mono_error_set_pending_exception (&error);
2098 }
2099
2100 #endif
2101
2102 static gboolean
2103 is_corlib_type (MonoClass *klass)
2104 {
2105         return klass->image == mono_defaults.corlib;
2106 }
2107
2108 #define check_corlib_type_cached(_class, _namespace, _name) do { \
2109         static MonoClass *cached_class; \
2110         if (cached_class) \
2111                 return cached_class == _class; \
2112         if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
2113                 cached_class = _class; \
2114                 return TRUE; \
2115         } \
2116         return FALSE; \
2117 } while (0) \
2118
2119
2120
2121 #ifndef DISABLE_REFLECTION_EMIT
2122 static gboolean
2123 is_sre_array (MonoClass *klass)
2124 {
2125         check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
2126 }
2127
2128 static gboolean
2129 is_sre_byref (MonoClass *klass)
2130 {
2131         check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
2132 }
2133
2134 static gboolean
2135 is_sre_pointer (MonoClass *klass)
2136 {
2137         check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
2138 }
2139
2140 static gboolean
2141 is_sre_generic_instance (MonoClass *klass)
2142 {
2143         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
2144 }
2145
2146 static gboolean
2147 is_sre_type_builder (MonoClass *klass)
2148 {
2149         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
2150 }
2151
2152 static gboolean
2153 is_sre_method_builder (MonoClass *klass)
2154 {
2155         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
2156 }
2157
2158 gboolean
2159 mono_is_sre_ctor_builder (MonoClass *klass)
2160 {
2161         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
2162 }
2163
2164 static gboolean
2165 is_sre_field_builder (MonoClass *klass)
2166 {
2167         check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
2168 }
2169
2170 gboolean
2171 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2172 {
2173         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
2174 }
2175
2176 gboolean
2177 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2178 {
2179         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
2180 }
2181
2182 static MonoReflectionType*
2183 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
2184 {
2185         static MonoMethod *method_get_underlying_system_type = NULL;
2186         MonoReflectionType *rt;
2187         MonoMethod *usertype_method;
2188
2189         mono_error_init (error);
2190
2191         if (!method_get_underlying_system_type)
2192                 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
2193
2194         usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
2195
2196         rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
2197
2198         return rt;
2199 }
2200
2201 MonoReflectionType*
2202 mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error)
2203 {
2204         mono_error_init (error);
2205         if (!type || type->type)
2206                 return type;
2207
2208         if (mono_reflection_is_usertype (type)) {
2209                 type = mono_reflection_type_get_underlying_system_type (type, error);
2210                 return_val_if_nok (error, NULL);
2211                 if (mono_reflection_is_usertype (type)) {
2212                         mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
2213                         return NULL;
2214                 }
2215         }
2216
2217         return type;
2218 }
2219
2220
2221 MonoType*
2222 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
2223 {
2224         MonoClass *klass;
2225         mono_error_init (error);
2226
2227         if (!ref)
2228                 return NULL;
2229         if (ref->type)
2230                 return ref->type;
2231
2232         if (mono_reflection_is_usertype (ref)) {
2233                 ref = mono_reflection_type_get_underlying_system_type (ref, error);
2234                 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
2235                         return NULL;
2236                 if (ref->type)
2237                         return ref->type;
2238         }
2239
2240         klass = mono_object_class (ref);
2241
2242         if (is_sre_array (klass)) {
2243                 MonoType *res;
2244                 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
2245                 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
2246                 return_val_if_nok (error, NULL);
2247                 g_assert (base);
2248                 if (sre_array->rank == 0) //single dimentional array
2249                         res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
2250                 else
2251                         res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
2252                 sre_array->type.type = res;
2253                 return res;
2254         } else if (is_sre_byref (klass)) {
2255                 MonoType *res;
2256                 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
2257                 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
2258                 return_val_if_nok (error, NULL);
2259                 g_assert (base);
2260                 res = &mono_class_from_mono_type (base)->this_arg;
2261                 sre_byref->type.type = res;
2262                 return res;
2263         } else if (is_sre_pointer (klass)) {
2264                 MonoType *res;
2265                 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
2266                 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
2267                 return_val_if_nok (error, NULL);
2268                 g_assert (base);
2269                 res = &mono_ptr_class_get (base)->byval_arg;
2270                 sre_pointer->type.type = res;
2271                 return res;
2272         } else if (is_sre_generic_instance (klass)) {
2273                 MonoType *res, **types;
2274                 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
2275                 int i, count;
2276
2277                 count = mono_array_length (gclass->type_arguments);
2278                 types = g_new0 (MonoType*, count);
2279                 for (i = 0; i < count; ++i) {
2280                         MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
2281                         types [i] = mono_reflection_type_get_handle (t, error);
2282                         if (!types[i] || !is_ok (error)) {
2283                                 g_free (types);
2284                                 return NULL;
2285                         }
2286                 }
2287
2288                 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
2289                 g_free (types);
2290                 g_assert (res);
2291                 gclass->type.type = res;
2292                 return res;
2293         }
2294
2295         g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
2296         return NULL;
2297 }
2298
2299 void
2300 ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
2301 {
2302         MonoError error;
2303         mono_reflection_type_get_handle (type, &error);
2304         mono_error_set_pending_exception (&error);
2305 }
2306
2307 static gboolean
2308 reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
2309 {
2310         MonoDomain *domain = mono_object_domain ((MonoObject*)type);
2311         MonoClass *klass;
2312
2313         mono_error_init (error);
2314
2315         MonoType *res = mono_reflection_type_get_handle (type, error);
2316
2317         if (!res && is_ok (error)) {
2318                 mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
2319         }
2320         return_val_if_nok (error, FALSE);
2321
2322         klass = mono_class_from_mono_type (res);
2323
2324         mono_loader_lock (); /*same locking as mono_type_get_object_checked */
2325         mono_domain_lock (domain);
2326
2327         if (!image_is_dynamic (klass->image)) {
2328                 mono_class_setup_supertypes (klass);
2329         } else {
2330                 if (!domain->type_hash)
2331                         domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
2332                                         (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
2333                 mono_g_hash_table_insert (domain->type_hash, res, type);
2334         }
2335         mono_domain_unlock (domain);
2336         mono_loader_unlock ();
2337
2338         return TRUE;
2339 }
2340
2341 void
2342 mono_reflection_register_with_runtime (MonoReflectionType *type)
2343 {
2344         MonoError error;
2345         (void) reflection_register_with_runtime (type, &error);
2346         mono_error_set_pending_exception (&error);
2347 }
2348
2349 /**
2350  * LOCKING: Assumes the loader lock is held.
2351  */
2352 static MonoMethodSignature*
2353 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
2354         MonoMethodSignature *sig;
2355         int count, i;
2356
2357         mono_error_init (error);
2358
2359         count = parameters? mono_array_length (parameters): 0;
2360
2361         sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
2362         sig->param_count = count;
2363         sig->sentinelpos = -1; /* FIXME */
2364         for (i = 0; i < count; ++i) {
2365                 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
2366                 if (!is_ok (error)) {
2367                         image_g_free (image, sig);
2368                         return NULL;
2369                 }
2370         }
2371         return sig;
2372 }
2373
2374 /**
2375  * LOCKING: Assumes the loader lock is held.
2376  */
2377 static MonoMethodSignature*
2378 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
2379         MonoMethodSignature *sig;
2380
2381         mono_error_init (error);
2382
2383         sig = parameters_to_signature (image, ctor->parameters, error);
2384         return_val_if_nok (error, NULL);
2385         sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2386         sig->ret = &mono_defaults.void_class->byval_arg;
2387         return sig;
2388 }
2389
2390 /**
2391  * LOCKING: Assumes the loader lock is held.
2392  */
2393 static MonoMethodSignature*
2394 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
2395         MonoMethodSignature *sig;
2396
2397         mono_error_init (error);
2398
2399         sig = parameters_to_signature (image, method->parameters, error);
2400         return_val_if_nok (error, NULL);
2401         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2402         if (method->rtype) {
2403                 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
2404                 if (!is_ok (error)) {
2405                         image_g_free (image, sig);
2406                         return NULL;
2407                 }
2408         } else {
2409                 sig->ret = &mono_defaults.void_class->byval_arg;
2410         }
2411         sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
2412         return sig;
2413 }
2414
2415 static MonoMethodSignature*
2416 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
2417         MonoMethodSignature *sig;
2418
2419         mono_error_init (error);
2420
2421         sig = parameters_to_signature (NULL, method->parameters, error);
2422         return_val_if_nok (error, NULL);
2423         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2424         if (method->rtype) {
2425                 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
2426                 if (!is_ok (error)) {
2427                         g_free (sig);
2428                         return NULL;
2429                 }
2430         } else {
2431                 sig->ret = &mono_defaults.void_class->byval_arg;
2432         }
2433         sig->generic_param_count = 0;
2434         return sig;
2435 }
2436
2437 static void
2438 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
2439 {
2440         mono_error_init (error);
2441         MonoClass *klass = mono_object_class (prop);
2442         if (strcmp (klass->name, "PropertyBuilder") == 0) {
2443                 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
2444                 *name = mono_string_to_utf8_checked (pb->name, error);
2445                 return_if_nok (error);
2446                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
2447         } else {
2448                 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
2449                 *name = g_strdup (p->property->name);
2450                 if (p->property->get)
2451                         *type = mono_method_signature (p->property->get)->ret;
2452                 else
2453                         *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
2454         }
2455 }
2456
2457 static void
2458 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
2459 {
2460         mono_error_init (error);
2461         MonoClass *klass = mono_object_class (field);
2462         if (strcmp (klass->name, "FieldBuilder") == 0) {
2463                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
2464                 *name = mono_string_to_utf8_checked (fb->name, error);
2465                 return_if_nok (error);
2466                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
2467         } else {
2468                 MonoReflectionField *f = (MonoReflectionField *)field;
2469                 *name = g_strdup (mono_field_get_name (f->field));
2470                 *type = f->field->type;
2471         }
2472 }
2473
2474 #else /* DISABLE_REFLECTION_EMIT */
2475
2476 void
2477 mono_reflection_register_with_runtime (MonoReflectionType *type)
2478 {
2479         /* This is empty */
2480 }
2481
2482 static gboolean
2483 is_sre_type_builder (MonoClass *klass)
2484 {
2485         return FALSE;
2486 }
2487
2488 static gboolean
2489 is_sre_generic_instance (MonoClass *klass)
2490 {
2491         return FALSE;
2492 }
2493
2494 gboolean
2495 mono_is_sre_ctor_builder (MonoClass *klass)
2496 {
2497         return FALSE;
2498 }
2499
2500 gboolean
2501 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2502 {
2503         return FALSE;
2504 }
2505
2506 gboolean
2507 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2508 {
2509         return FALSE;
2510 }
2511
2512 void
2513 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
2514 {
2515         mono_error_init (error);
2516 }
2517
2518 #endif /* !DISABLE_REFLECTION_EMIT */
2519
2520
2521 static gboolean
2522 is_sr_mono_field (MonoClass *klass)
2523 {
2524         check_corlib_type_cached (klass, "System.Reflection", "MonoField");
2525 }
2526
2527 gboolean
2528 mono_is_sr_mono_property (MonoClass *klass)
2529 {
2530         check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
2531 }
2532
2533 static gboolean
2534 is_sr_mono_method (MonoClass *klass)
2535 {
2536         check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
2537 }
2538
2539 gboolean
2540 mono_is_sr_mono_cmethod (MonoClass *klass)
2541 {
2542         check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
2543 }
2544
2545 static gboolean
2546 is_sr_mono_generic_method (MonoClass *klass)
2547 {
2548         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
2549 }
2550
2551 static gboolean
2552 is_sr_mono_generic_cmethod (MonoClass *klass)
2553 {
2554         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
2555 }
2556
2557 gboolean
2558 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
2559 {
2560         return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
2561 }
2562
2563 gboolean
2564 mono_is_sre_type_builder (MonoClass *klass)
2565 {
2566         return is_sre_type_builder (klass);
2567 }
2568
2569 gboolean
2570 mono_is_sre_generic_instance (MonoClass *klass)
2571 {
2572         return is_sre_generic_instance (klass);
2573 }
2574
2575
2576
2577 /**
2578  * encode_cattr_value:
2579  * Encode a value in a custom attribute stream of bytes.
2580  * The value to encode is either supplied as an object in argument val
2581  * (valuetypes are boxed), or as a pointer to the data in the
2582  * argument argval.
2583  * @type represents the type of the value
2584  * @buffer is the start of the buffer
2585  * @p the current position in the buffer
2586  * @buflen contains the size of the buffer and is used to return the new buffer size
2587  * if this needs to be realloced.
2588  * @retbuffer and @retp return the start and the position of the buffer
2589  * @error set on error.
2590  */
2591 static void
2592 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2593 {
2594         MonoTypeEnum simple_type;
2595         
2596         mono_error_init (error);
2597         if ((p-buffer) + 10 >= *buflen) {
2598                 char *newbuf;
2599                 *buflen *= 2;
2600                 newbuf = (char *)g_realloc (buffer, *buflen);
2601                 p = newbuf + (p-buffer);
2602                 buffer = newbuf;
2603         }
2604         if (!argval)
2605                 argval = ((char*)arg + sizeof (MonoObject));
2606         simple_type = type->type;
2607 handle_enum:
2608         switch (simple_type) {
2609         case MONO_TYPE_BOOLEAN:
2610         case MONO_TYPE_U1:
2611         case MONO_TYPE_I1:
2612                 *p++ = *argval;
2613                 break;
2614         case MONO_TYPE_CHAR:
2615         case MONO_TYPE_U2:
2616         case MONO_TYPE_I2:
2617                 swap_with_size (p, argval, 2, 1);
2618                 p += 2;
2619                 break;
2620         case MONO_TYPE_U4:
2621         case MONO_TYPE_I4:
2622         case MONO_TYPE_R4:
2623                 swap_with_size (p, argval, 4, 1);
2624                 p += 4;
2625                 break;
2626         case MONO_TYPE_R8:
2627                 swap_with_size (p, argval, 8, 1);
2628                 p += 8;
2629                 break;
2630         case MONO_TYPE_U8:
2631         case MONO_TYPE_I8:
2632                 swap_with_size (p, argval, 8, 1);
2633                 p += 8;
2634                 break;
2635         case MONO_TYPE_VALUETYPE:
2636                 if (type->data.klass->enumtype) {
2637                         simple_type = mono_class_enum_basetype (type->data.klass)->type;
2638                         goto handle_enum;
2639                 } else {
2640                         g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2641                 }
2642                 break;
2643         case MONO_TYPE_STRING: {
2644                 char *str;
2645                 guint32 slen;
2646                 if (!arg) {
2647                         *p++ = 0xFF;
2648                         break;
2649                 }
2650                 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2651                 return_if_nok (error);
2652                 slen = strlen (str);
2653                 if ((p-buffer) + 10 + slen >= *buflen) {
2654                         char *newbuf;
2655                         *buflen *= 2;
2656                         *buflen += slen;
2657                         newbuf = (char *)g_realloc (buffer, *buflen);
2658                         p = newbuf + (p-buffer);
2659                         buffer = newbuf;
2660                 }
2661                 mono_metadata_encode_value (slen, p, &p);
2662                 memcpy (p, str, slen);
2663                 p += slen;
2664                 g_free (str);
2665                 break;
2666         }
2667         case MONO_TYPE_CLASS: {
2668                 char *str;
2669                 guint32 slen;
2670                 MonoType *arg_type;
2671                 if (!arg) {
2672                         *p++ = 0xFF;
2673                         break;
2674                 }
2675 handle_type:
2676                 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2677                 return_if_nok (error);
2678
2679                 str = type_get_qualified_name (arg_type, NULL);
2680                 slen = strlen (str);
2681                 if ((p-buffer) + 10 + slen >= *buflen) {
2682                         char *newbuf;
2683                         *buflen *= 2;
2684                         *buflen += slen;
2685                         newbuf = (char *)g_realloc (buffer, *buflen);
2686                         p = newbuf + (p-buffer);
2687                         buffer = newbuf;
2688                 }
2689                 mono_metadata_encode_value (slen, p, &p);
2690                 memcpy (p, str, slen);
2691                 p += slen;
2692                 g_free (str);
2693                 break;
2694         }
2695         case MONO_TYPE_SZARRAY: {
2696                 int len, i;
2697                 MonoClass *eclass, *arg_eclass;
2698
2699                 if (!arg) {
2700                         *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2701                         break;
2702                 }
2703                 len = mono_array_length ((MonoArray*)arg);
2704                 *p++ = len & 0xff;
2705                 *p++ = (len >> 8) & 0xff;
2706                 *p++ = (len >> 16) & 0xff;
2707                 *p++ = (len >> 24) & 0xff;
2708                 *retp = p;
2709                 *retbuffer = buffer;
2710                 eclass = type->data.klass;
2711                 arg_eclass = mono_object_class (arg)->element_class;
2712
2713                 if (!eclass) {
2714                         /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2715                         eclass = mono_defaults.object_class;
2716                 }
2717                 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2718                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2719                         int elsize = mono_class_array_element_size (arg_eclass);
2720                         for (i = 0; i < len; ++i) {
2721                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2722                                 return_if_nok (error);
2723                                 elptr += elsize;
2724                         }
2725                 } else if (eclass->valuetype && arg_eclass->valuetype) {
2726                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2727                         int elsize = mono_class_array_element_size (eclass);
2728                         for (i = 0; i < len; ++i) {
2729                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2730                                 return_if_nok (error);
2731                                 elptr += elsize;
2732                         }
2733                 } else {
2734                         for (i = 0; i < len; ++i) {
2735                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2736                                 return_if_nok (error);
2737                         }
2738                 }
2739                 break;
2740         }
2741         case MONO_TYPE_OBJECT: {
2742                 MonoClass *klass;
2743                 char *str;
2744                 guint32 slen;
2745
2746                 /*
2747                  * The parameter type is 'object' but the type of the actual
2748                  * argument is not. So we have to add type information to the blob
2749                  * too. This is completely undocumented in the spec.
2750                  */
2751
2752                 if (arg == NULL) {
2753                         *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
2754                         *p++ = 0xFF;
2755                         break;
2756                 }
2757                 
2758                 klass = mono_object_class (arg);
2759
2760                 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2761                         *p++ = 0x50;
2762                         goto handle_type;
2763                 } else {
2764                         return_if_nok (error);
2765                 }
2766
2767                 if (klass->enumtype) {
2768                         *p++ = 0x55;
2769                 } else if (klass == mono_defaults.string_class) {
2770                         simple_type = MONO_TYPE_STRING;
2771                         *p++ = 0x0E;
2772                         goto handle_enum;
2773                 } else if (klass->rank == 1) {
2774                         *p++ = 0x1D;
2775                         if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2776                                 /* See Partition II, Appendix B3 */
2777                                 *p++ = 0x51;
2778                         else
2779                                 *p++ = klass->element_class->byval_arg.type;
2780                         encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2781                         return_if_nok (error);
2782                         break;
2783                 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2784                         *p++ = simple_type = klass->byval_arg.type;
2785                         goto handle_enum;
2786                 } else {
2787                         g_error ("unhandled type in custom attr");
2788                 }
2789                 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2790                 slen = strlen (str);
2791                 if ((p-buffer) + 10 + slen >= *buflen) {
2792                         char *newbuf;
2793                         *buflen *= 2;
2794                         *buflen += slen;
2795                         newbuf = (char *)g_realloc (buffer, *buflen);
2796                         p = newbuf + (p-buffer);
2797                         buffer = newbuf;
2798                 }
2799                 mono_metadata_encode_value (slen, p, &p);
2800                 memcpy (p, str, slen);
2801                 p += slen;
2802                 g_free (str);
2803                 simple_type = mono_class_enum_basetype (klass)->type;
2804                 goto handle_enum;
2805         }
2806         default:
2807                 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2808         }
2809         *retp = p;
2810         *retbuffer = buffer;
2811 }
2812
2813 static void
2814 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2815 {
2816         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2817                 char *str = type_get_qualified_name (type, NULL);
2818                 int slen = strlen (str);
2819
2820                 *p++ = 0x55;
2821                 /*
2822                  * This seems to be optional...
2823                  * *p++ = 0x80;
2824                  */
2825                 mono_metadata_encode_value (slen, p, &p);
2826                 memcpy (p, str, slen);
2827                 p += slen;
2828                 g_free (str);
2829         } else if (type->type == MONO_TYPE_OBJECT) {
2830                 *p++ = 0x51;
2831         } else if (type->type == MONO_TYPE_CLASS) {
2832                 /* it should be a type: encode_cattr_value () has the check */
2833                 *p++ = 0x50;
2834         } else {
2835                 mono_metadata_encode_value (type->type, p, &p);
2836                 if (type->type == MONO_TYPE_SZARRAY)
2837                         /* See the examples in Partition VI, Annex B */
2838                         encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2839         }
2840
2841         *retp = p;
2842 }
2843
2844 #ifndef DISABLE_REFLECTION_EMIT
2845 static void
2846 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2847 {
2848         int len;
2849
2850         mono_error_init (error);
2851
2852         /* Preallocate a large enough buffer */
2853         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2854                 char *str = type_get_qualified_name (type, NULL);
2855                 len = strlen (str);
2856                 g_free (str);
2857         } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2858                 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2859                 len = strlen (str);
2860                 g_free (str);
2861         } else {
2862                 len = 0;
2863         }
2864         len += strlen (name);
2865
2866         if ((p-buffer) + 20 + len >= *buflen) {
2867                 char *newbuf;
2868                 *buflen *= 2;
2869                 *buflen += len;
2870                 newbuf = (char *)g_realloc (buffer, *buflen);
2871                 p = newbuf + (p-buffer);
2872                 buffer = newbuf;
2873         }
2874
2875         encode_field_or_prop_type (type, p, &p);
2876
2877         len = strlen (name);
2878         mono_metadata_encode_value (len, p, &p);
2879         memcpy (p, name, len);
2880         p += len;
2881         encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2882         return_if_nok (error);
2883         *retp = p;
2884         *retbuffer = buffer;
2885 }
2886
2887 /**
2888  * mono_reflection_get_custom_attrs_blob:
2889  * @ctor: custom attribute constructor
2890  * @ctorArgs: arguments o the constructor
2891  * @properties:
2892  * @propValues:
2893  * @fields:
2894  * @fieldValues:
2895  * 
2896  * Creates the blob of data that needs to be saved in the metadata and that represents
2897  * the custom attributed described by @ctor, @ctorArgs etc.
2898  * Returns: a Byte array representing the blob of data.
2899  */
2900 MonoArray*
2901 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
2902 {
2903         MonoError error;
2904         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2905         mono_error_cleanup (&error);
2906         return result;
2907 }
2908
2909 /**
2910  * mono_reflection_get_custom_attrs_blob_checked:
2911  * @ctor: custom attribute constructor
2912  * @ctorArgs: arguments o the constructor
2913  * @properties:
2914  * @propValues:
2915  * @fields:
2916  * @fieldValues:
2917  * @error: set on error
2918  * 
2919  * Creates the blob of data that needs to be saved in the metadata and that represents
2920  * the custom attributed described by @ctor, @ctorArgs etc.
2921  * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
2922  */
2923 MonoArray*
2924 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
2925 {
2926         MonoArray *result = NULL;
2927         MonoMethodSignature *sig;
2928         MonoObject *arg;
2929         char *buffer, *p;
2930         guint32 buflen, i;
2931
2932         mono_error_init (error);
2933
2934         if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2935                 /* sig is freed later so allocate it in the heap */
2936                 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2937                 if (!is_ok (error)) {
2938                         g_free (sig);
2939                         return NULL;
2940                 }
2941         } else {
2942                 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2943         }
2944
2945         g_assert (mono_array_length (ctorArgs) == sig->param_count);
2946         buflen = 256;
2947         p = buffer = (char *)g_malloc (buflen);
2948         /* write the prolog */
2949         *p++ = 1;
2950         *p++ = 0;
2951         for (i = 0; i < sig->param_count; ++i) {
2952                 arg = mono_array_get (ctorArgs, MonoObject*, i);
2953                 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2954                 if (!is_ok (error)) goto leave;
2955         }
2956         i = 0;
2957         if (properties)
2958                 i += mono_array_length (properties);
2959         if (fields)
2960                 i += mono_array_length (fields);
2961         *p++ = i & 0xff;
2962         *p++ = (i >> 8) & 0xff;
2963         if (properties) {
2964                 MonoObject *prop;
2965                 for (i = 0; i < mono_array_length (properties); ++i) {
2966                         MonoType *ptype;
2967                         char *pname;
2968
2969                         prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2970                         get_prop_name_and_type (prop, &pname, &ptype, error);
2971                         if (!is_ok (error)) goto leave;
2972                         *p++ = 0x54; /* PROPERTY signature */
2973                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2974                         g_free (pname);
2975                         if (!is_ok (error)) goto leave;
2976                 }
2977         }
2978
2979         if (fields) {
2980                 MonoObject *field;
2981                 for (i = 0; i < mono_array_length (fields); ++i) {
2982                         MonoType *ftype;
2983                         char *fname;
2984
2985                         field = (MonoObject *)mono_array_get (fields, gpointer, i);
2986                         get_field_name_and_type (field, &fname, &ftype, error);
2987                         if (!is_ok (error)) goto leave;
2988                         *p++ = 0x53; /* FIELD signature */
2989                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2990                         g_free (fname);
2991                         if (!is_ok (error)) goto leave;
2992                 }
2993         }
2994
2995         g_assert (p - buffer <= buflen);
2996         buflen = p - buffer;
2997         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2998         if (!is_ok (error))
2999                 goto leave;
3000         p = mono_array_addr (result, char, 0);
3001         memcpy (p, buffer, buflen);
3002 leave:
3003         g_free (buffer);
3004         if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
3005                 g_free (sig);
3006         return result;
3007 }
3008
3009 /**
3010  * reflection_setup_internal_class:
3011  * @tb: a TypeBuilder object
3012  * @error: set on error
3013  *
3014  * Creates a MonoClass that represents the TypeBuilder.
3015  * This is a trick that lets us simplify a lot of reflection code
3016  * (and will allow us to support Build and Run assemblies easier).
3017  *
3018  * Returns TRUE on success. On failure, returns FALSE and sets @error.
3019  */
3020 static gboolean
3021 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3022 {
3023         MonoClass *klass, *parent;
3024
3025         mono_error_init (error);
3026         RESOLVE_TYPE (tb->parent, error);
3027         return_val_if_nok (error, FALSE);
3028
3029         mono_loader_lock ();
3030
3031         if (tb->parent) {
3032                 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
3033                 if (!is_ok (error)) {
3034                         mono_loader_unlock ();
3035                         return FALSE;
3036                 }
3037                 /* check so we can compile corlib correctly */
3038                 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
3039                         /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
3040                         parent = parent_type->data.klass;
3041                 } else {
3042                         parent = mono_class_from_mono_type (parent_type);
3043                 }
3044         } else {
3045                 parent = NULL;
3046         }
3047         
3048         /* the type has already being created: it means we just have to change the parent */
3049         if (tb->type.type) {
3050                 klass = mono_class_from_mono_type (tb->type.type);
3051                 klass->parent = NULL;
3052                 /* fool mono_class_setup_parent */
3053                 klass->supertypes = NULL;
3054                 mono_class_setup_parent (klass, parent);
3055                 mono_class_setup_mono_type (klass);
3056                 mono_loader_unlock ();
3057                 return TRUE;
3058         }
3059
3060         klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
3061
3062         klass->image = &tb->module->dynamic_image->image;
3063
3064         klass->inited = 1; /* we lie to the runtime */
3065         klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
3066         if (!is_ok (error))
3067                 goto failure;
3068         klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
3069         if (!is_ok (error))
3070                 goto failure;
3071         klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
3072         klass->flags = tb->attrs;
3073         
3074         mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
3075
3076         klass->element_class = klass;
3077
3078         if (mono_class_get_ref_info (klass) == NULL) {
3079
3080                 mono_class_set_ref_info (klass, tb);
3081
3082                 /* Put into cache so mono_class_get_checked () will find it.
3083                 Skip nested types as those should not be available on the global scope. */
3084                 if (!tb->nesting_type)
3085                         mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
3086
3087                 /*
3088                 We must register all types as we cannot rely on the name_cache hashtable since we find the class
3089                 by performing a mono_class_get which does the full resolution.
3090
3091                 Working around this semantics would require us to write a lot of code for no clear advantage.
3092                 */
3093                 mono_image_append_class_to_reflection_info_set (klass);
3094         } else {
3095                 g_assert (mono_class_get_ref_info (klass) == tb);
3096         }
3097
3098         mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
3099
3100         if (parent != NULL) {
3101                 mono_class_setup_parent (klass, parent);
3102         } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
3103                 const char *old_n = klass->name;
3104                 /* trick to get relative numbering right when compiling corlib */
3105                 klass->name = "BuildingObject";
3106                 mono_class_setup_parent (klass, mono_defaults.object_class);
3107                 klass->name = old_n;
3108         }
3109
3110         if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
3111                         (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
3112                         (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
3113                 klass->instance_size = sizeof (MonoObject);
3114                 klass->size_inited = 1;
3115                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
3116         }
3117
3118         mono_class_setup_mono_type (klass);
3119
3120         mono_class_setup_supertypes (klass);
3121
3122         /*
3123          * FIXME: handle interfaces.
3124          */
3125
3126         tb->type.type = &klass->byval_arg;
3127
3128         if (tb->nesting_type) {
3129                 g_assert (tb->nesting_type->type);
3130                 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
3131                 if (!is_ok (error)) goto failure;
3132                 klass->nested_in = mono_class_from_mono_type (nesting_type);
3133         }
3134
3135         /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
3136
3137         mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
3138         
3139         mono_loader_unlock ();
3140         return TRUE;
3141
3142 failure:
3143         mono_loader_unlock ();
3144         return FALSE;
3145 }
3146
3147 /**
3148  * ves_icall_TypeBuilder_setup_internal_class:
3149  * @tb: a TypeBuilder object
3150  *
3151  * (icall)
3152  * Creates a MonoClass that represents the TypeBuilder.
3153  * This is a trick that lets us simplify a lot of reflection code
3154  * (and will allow us to support Build and Run assemblies easier).
3155  *
3156  */
3157 void
3158 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
3159 {
3160         MonoError error;
3161         (void) reflection_setup_internal_class (tb, &error);
3162         mono_error_set_pending_exception (&error);
3163 }
3164
3165 /*
3166  * ves_icall_TypeBuilder_setup_generic_class:
3167  * @tb: a TypeBuilder object
3168  *
3169  * Setup the generic class before adding the first generic parameter.
3170  */
3171 void
3172 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
3173 {
3174 }
3175
3176 /**
3177  * mono_reflection_create_generic_class:
3178  * @tb: a TypeBuilder object
3179  * @error: set on error
3180  *
3181  * Creates the generic class after all generic parameters have been added.
3182  * On success returns TRUE, on failure returns FALSE and sets @error.
3183  * 
3184  */
3185 gboolean
3186 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3187 {
3188
3189         MonoClass *klass;
3190         int count, i;
3191
3192         mono_error_init (error);
3193
3194         klass = mono_class_from_mono_type (tb->type.type);
3195
3196         count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
3197
3198         if (klass->generic_container || (count == 0))
3199                 return TRUE;
3200
3201         g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
3202
3203         klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3204
3205         klass->generic_container->owner.klass = klass;
3206         klass->generic_container->type_argc = count;
3207         klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
3208
3209         klass->is_generic = 1;
3210
3211         for (i = 0; i < count; i++) {
3212                 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3213                 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
3214                 return_val_if_nok (error, FALSE);
3215                 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
3216                 klass->generic_container->type_params [i] = *param;
3217                 /*Make sure we are a diferent type instance */
3218                 klass->generic_container->type_params [i].param.owner = klass->generic_container;
3219                 klass->generic_container->type_params [i].info.pklass = NULL;
3220                 klass->generic_container->type_params [i].info.flags = gparam->attrs;
3221
3222                 g_assert (klass->generic_container->type_params [i].param.owner);
3223         }
3224
3225         klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
3226         return TRUE;
3227 }
3228
3229 static MonoMarshalSpec*
3230 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
3231                                 MonoReflectionMarshal *minfo, MonoError *error)
3232 {
3233         MonoMarshalSpec *res;
3234
3235         mono_error_init (error);
3236
3237         res = image_g_new0 (image, MonoMarshalSpec, 1);
3238         res->native = (MonoMarshalNative)minfo->type;
3239
3240         switch (minfo->type) {
3241         case MONO_NATIVE_LPARRAY:
3242                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
3243                 if (minfo->has_size) {
3244                         res->data.array_data.param_num = minfo->param_num;
3245                         res->data.array_data.num_elem = minfo->count;
3246                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
3247                 }
3248                 else {
3249                         res->data.array_data.param_num = -1;
3250                         res->data.array_data.num_elem = -1;
3251                         res->data.array_data.elem_mult = -1;
3252                 }
3253                 break;
3254
3255         case MONO_NATIVE_BYVALTSTR:
3256         case MONO_NATIVE_BYVALARRAY:
3257                 res->data.array_data.num_elem = minfo->count;
3258                 break;
3259
3260         case MONO_NATIVE_CUSTOM:
3261                 if (minfo->marshaltyperef) {
3262                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
3263                         if (!is_ok (error)) {
3264                                 image_g_free (image, res);
3265                                 return NULL;
3266                         }
3267                         res->data.custom_data.custom_name =
3268                                 type_get_fully_qualified_name (marshaltyperef);
3269                 }
3270                 if (minfo->mcookie) {
3271                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
3272                         if (!is_ok (error)) {
3273                                 image_g_free (image, res);
3274                                 return NULL;
3275                         }
3276                 }
3277                 break;
3278
3279         default:
3280                 break;
3281         }
3282
3283         return res;
3284 }
3285 #endif /* !DISABLE_REFLECTION_EMIT */
3286
3287 MonoReflectionMarshalAsAttribute*
3288 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
3289                                                         MonoMarshalSpec *spec, MonoError *error)
3290 {
3291         MonoReflectionType *rt;
3292         MonoReflectionMarshalAsAttribute *minfo;
3293         MonoType *mtype;
3294
3295         mono_error_init (error);
3296         
3297         minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
3298         if (!minfo)
3299                 return NULL;
3300         minfo->utype = spec->native;
3301
3302         switch (minfo->utype) {
3303         case MONO_NATIVE_LPARRAY:
3304                 minfo->array_subtype = spec->data.array_data.elem_type;
3305                 minfo->size_const = spec->data.array_data.num_elem;
3306                 if (spec->data.array_data.param_num != -1)
3307                         minfo->size_param_index = spec->data.array_data.param_num;
3308                 break;
3309
3310         case MONO_NATIVE_BYVALTSTR:
3311         case MONO_NATIVE_BYVALARRAY:
3312                 minfo->size_const = spec->data.array_data.num_elem;
3313                 break;
3314
3315         case MONO_NATIVE_CUSTOM:
3316                 if (spec->data.custom_data.custom_name) {
3317                         mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
3318                         return_val_if_nok  (error, NULL);
3319
3320                         if (mtype) {
3321                                 rt = mono_type_get_object_checked (domain, mtype, error);
3322                                 if (!rt)
3323                                         return NULL;
3324
3325                                 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
3326                         }
3327
3328                         MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
3329                 }
3330                 if (spec->data.custom_data.cookie)
3331                         MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
3332                 break;
3333
3334         default:
3335                 break;
3336         }
3337
3338         return minfo;
3339 }
3340
3341 #ifndef DISABLE_REFLECTION_EMIT
3342 static MonoMethod*
3343 reflection_methodbuilder_to_mono_method (MonoClass *klass,
3344                                          ReflectionMethodBuilder *rmb,
3345                                          MonoMethodSignature *sig,
3346                                          MonoError *error)
3347 {
3348         MonoMethod *m;
3349         MonoMethodWrapper *wrapperm;
3350         MonoMarshalSpec **specs;
3351         MonoReflectionMethodAux *method_aux;
3352         MonoImage *image;
3353         gboolean dynamic;
3354         int i;
3355
3356         mono_error_init (error);
3357         /*
3358          * Methods created using a MethodBuilder should have their memory allocated
3359          * inside the image mempool, while dynamic methods should have their memory
3360          * malloc'd.
3361          */
3362         dynamic = rmb->refs != NULL;
3363         image = dynamic ? NULL : klass->image;
3364
3365         if (!dynamic)
3366                 g_assert (!klass->generic_class);
3367
3368         mono_loader_lock ();
3369
3370         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
3371                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
3372                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
3373         else
3374                 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
3375
3376         wrapperm = (MonoMethodWrapper*)m;
3377
3378         m->dynamic = dynamic;
3379         m->slot = -1;
3380         m->flags = rmb->attrs;
3381         m->iflags = rmb->iattrs;
3382         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
3383         m->klass = klass;
3384         m->signature = sig;
3385         m->sre_method = TRUE;
3386         m->skip_visibility = rmb->skip_visibility;
3387         if (rmb->table_idx)
3388                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
3389
3390         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
3391                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
3392                         m->string_ctor = 1;
3393
3394                 m->signature->pinvoke = 1;
3395         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3396                 m->signature->pinvoke = 1;
3397
3398                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3399
3400                 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
3401                 mono_error_assert_ok (error);
3402                 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
3403                 mono_error_assert_ok (error);
3404                 
3405                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
3406
3407                 if (image_is_dynamic (klass->image))
3408                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3409
3410                 mono_loader_unlock ();
3411
3412                 return m;
3413         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
3414                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
3415                 MonoMethodHeader *header;
3416                 guint32 code_size;
3417                 gint32 max_stack, i;
3418                 gint32 num_locals = 0;
3419                 gint32 num_clauses = 0;
3420                 guint8 *code;
3421
3422                 if (rmb->ilgen) {
3423                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
3424                         code_size = rmb->ilgen->code_len;
3425                         max_stack = rmb->ilgen->max_stack;
3426                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
3427                         if (rmb->ilgen->ex_handlers)
3428                                 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
3429                 } else {
3430                         if (rmb->code) {
3431                                 code = mono_array_addr (rmb->code, guint8, 0);
3432                                 code_size = mono_array_length (rmb->code);
3433                                 /* we probably need to run a verifier on the code... */
3434                                 max_stack = 8; 
3435                         }
3436                         else {
3437                                 code = NULL;
3438                                 code_size = 0;
3439                                 max_stack = 8;
3440                         }
3441                 }
3442
3443                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
3444                 header->code_size = code_size;
3445                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
3446                 memcpy ((char*)header->code, code, code_size);
3447                 header->max_stack = max_stack;
3448                 header->init_locals = rmb->init_locals;
3449                 header->num_locals = num_locals;
3450
3451                 for (i = 0; i < num_locals; ++i) {
3452                         MonoReflectionLocalBuilder *lb = 
3453                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
3454
3455                         header->locals [i] = image_g_new0 (image, MonoType, 1);
3456                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
3457                         mono_error_assert_ok (error);
3458                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
3459                 }
3460
3461                 header->num_clauses = num_clauses;
3462                 if (num_clauses) {
3463                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
3464                                                                  rmb->ilgen, num_clauses, error);
3465                         mono_error_assert_ok (error);
3466                 }
3467
3468                 wrapperm->header = header;
3469         }
3470
3471         if (rmb->generic_params) {
3472                 int count = mono_array_length (rmb->generic_params);
3473                 MonoGenericContainer *container = rmb->generic_container;
3474
3475                 g_assert (container);
3476
3477                 container->type_argc = count;
3478                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
3479                 container->owner.method = m;
3480                 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
3481
3482                 m->is_generic = TRUE;
3483                 mono_method_set_generic_container (m, container);
3484
3485                 for (i = 0; i < count; i++) {
3486                         MonoReflectionGenericParam *gp =
3487                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
3488                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
3489                         mono_error_assert_ok (error);
3490                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
3491                         container->type_params [i] = *param;
3492                 }
3493
3494                 /*
3495                  * The method signature might have pointers to generic parameters that belong to other methods.
3496                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3497                  * generic parameters.
3498                  */
3499                 for (i = 0; i < m->signature->param_count; ++i) {
3500                         MonoType *t = m->signature->params [i];
3501                         if (t->type == MONO_TYPE_MVAR) {
3502                                 MonoGenericParam *gparam =  t->data.generic_param;
3503                                 if (gparam->num < count) {
3504                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
3505                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
3506                                 }
3507
3508                         }
3509                 }
3510
3511                 if (klass->generic_container) {
3512                         container->parent = klass->generic_container;
3513                         container->context.class_inst = klass->generic_container->context.class_inst;
3514                 }
3515                 container->context.method_inst = mono_get_shared_generic_inst (container);
3516         }
3517
3518         if (rmb->refs) {
3519                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
3520                 int i;
3521                 void **data;
3522
3523                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
3524
3525                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
3526                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
3527                 for (i = 0; i < rmb->nrefs; ++i)
3528                         data [i + 1] = rmb->refs [i];
3529         }
3530
3531         method_aux = NULL;
3532
3533         /* Parameter info */
3534         if (rmb->pinfo) {
3535                 if (!method_aux)
3536                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3537                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
3538                 for (i = 0; i <= m->signature->param_count; ++i) {
3539                         MonoReflectionParamBuilder *pb;
3540                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3541                                 if ((i > 0) && (pb->attrs)) {
3542                                         /* Make a copy since it might point to a shared type structure */
3543                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
3544                                         m->signature->params [i - 1]->attrs = pb->attrs;
3545                                 }
3546
3547                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3548                                         MonoDynamicImage *assembly;
3549                                         guint32 idx, len;
3550                                         MonoTypeEnum def_type;
3551                                         char *p;
3552                                         const char *p2;
3553
3554                                         if (!method_aux->param_defaults) {
3555                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3556                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3557                                         }
3558                                         assembly = (MonoDynamicImage*)klass->image;
3559                                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3560                                         /* Copy the data from the blob since it might get realloc-ed */
3561                                         p = assembly->blob.data + idx;
3562                                         len = mono_metadata_decode_blob_size (p, &p2);
3563                                         len += p2 - p;
3564                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3565                                         method_aux->param_default_types [i] = def_type;
3566                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3567                                 }
3568
3569                                 if (pb->name) {
3570                                         method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
3571                                         mono_error_assert_ok (error);
3572                                 }
3573                                 if (pb->cattrs) {
3574                                         if (!method_aux->param_cattr)
3575                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3576                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3577                                 }
3578                         }
3579                 }
3580         }
3581
3582         /* Parameter marshalling */
3583         specs = NULL;
3584         if (rmb->pinfo)         
3585                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3586                         MonoReflectionParamBuilder *pb;
3587                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3588                                 if (pb->marshal_info) {
3589                                         if (specs == NULL)
3590                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3591                                         specs [pb->position] = 
3592                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3593                                         if (!is_ok (error)) {
3594                                                 mono_loader_unlock ();
3595                                                 image_g_free (image, specs);
3596                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3597                                                 return NULL;
3598                                         }
3599                                 }
3600                         }
3601                 }
3602         if (specs != NULL) {
3603                 if (!method_aux)
3604                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3605                 method_aux->param_marshall = specs;
3606         }
3607
3608         if (image_is_dynamic (klass->image) && method_aux)
3609                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3610
3611         mono_loader_unlock ();
3612
3613         return m;
3614 }       
3615
3616 static MonoMethod*
3617 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3618 {
3619         ReflectionMethodBuilder rmb;
3620         MonoMethodSignature *sig;
3621
3622         mono_loader_lock ();
3623         g_assert (klass->image != NULL);
3624         sig = ctor_builder_to_signature (klass->image, mb, error);
3625         mono_loader_unlock ();
3626         return_val_if_nok (error, NULL);
3627
3628         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3629                 return NULL;
3630
3631         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3632         return_val_if_nok (error, NULL);
3633         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3634
3635         /* If we are in a generic class, we might be called multiple times from inflate_method */
3636         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3637                 /* ilgen is no longer needed */
3638                 mb->ilgen = NULL;
3639         }
3640
3641         return mb->mhandle;
3642 }
3643
3644 static MonoMethod*
3645 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
3646 {
3647         ReflectionMethodBuilder rmb;
3648         MonoMethodSignature *sig;
3649
3650         mono_error_init (error);
3651
3652         mono_loader_lock ();
3653         g_assert (klass->image != NULL);
3654         sig = method_builder_to_signature (klass->image, mb, error);
3655         mono_loader_unlock ();
3656         return_val_if_nok (error, NULL);
3657
3658         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3659                 return NULL;
3660
3661         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3662         return_val_if_nok (error, NULL);
3663         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3664
3665         /* If we are in a generic class, we might be called multiple times from inflate_method */
3666         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3667                 /* ilgen is no longer needed */
3668                 mb->ilgen = NULL;
3669         }
3670         return mb->mhandle;
3671 }
3672
3673 static MonoClassField*
3674 fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
3675 {
3676         MonoClassField *field;
3677         MonoType *custom;
3678
3679         mono_error_init (error);
3680
3681         field = g_new0 (MonoClassField, 1);
3682
3683         field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
3684         mono_error_assert_ok (error);
3685         if (fb->attrs || fb->modreq || fb->modopt) {
3686                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3687                 if (!is_ok (error)) {
3688                         g_free (field);
3689                         return NULL;
3690                 }
3691                 field->type = mono_metadata_type_dup (NULL, type);
3692                 field->type->attrs = fb->attrs;
3693
3694                 g_assert (image_is_dynamic (klass->image));
3695                 custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
3696                 g_free (field->type);
3697                 if (!is_ok (error)) {
3698                         g_free (field);
3699                         return NULL;
3700                 }
3701                 field->type = mono_metadata_type_dup (klass->image, custom);
3702                 g_free (custom);
3703         } else {
3704                 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3705                 if (!is_ok (error)) {
3706                         g_free (field);
3707                         return NULL;
3708                 }
3709         }
3710         if (fb->offset != -1)
3711                 field->offset = fb->offset;
3712         field->parent = klass;
3713         mono_save_custom_attrs (klass->image, field, fb->cattrs);
3714
3715         // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
3716
3717         return field;
3718 }
3719 #endif
3720
3721 #ifndef DISABLE_REFLECTION_EMIT
3722
3723 static MonoMethod *
3724 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
3725 {
3726         MonoMethodInflated *imethod;
3727         MonoGenericContext *context;
3728         int i;
3729
3730         /*
3731          * With generic code sharing the klass might not be inflated.
3732          * This can happen because classes inflated with their own
3733          * type arguments are "normalized" to the uninflated class.
3734          */
3735         if (!klass->generic_class)
3736                 return method;
3737
3738         context = mono_class_get_context (klass);
3739
3740         if (klass->method.count && klass->methods) {
3741                 /* Find the already created inflated method */
3742                 for (i = 0; i < klass->method.count; ++i) {
3743                         g_assert (klass->methods [i]->is_inflated);
3744                         if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
3745                                 break;
3746                 }
3747                 g_assert (i < klass->method.count);
3748                 imethod = (MonoMethodInflated*)klass->methods [i];
3749         } else {
3750                 MonoError error;
3751                 imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
3752                 mono_error_assert_ok (&error);
3753         }
3754
3755         if (method->is_generic && image_is_dynamic (method->klass->image)) {
3756                 MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
3757
3758                 mono_image_lock ((MonoImage*)image);
3759                 mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
3760                 mono_image_unlock ((MonoImage*)image);
3761         }
3762         return (MonoMethod *) imethod;
3763 }
3764
3765 static MonoMethod *
3766 inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
3767 {
3768         MonoMethod *method;
3769         MonoClass *gklass;
3770
3771         mono_error_init (error);
3772
3773         MonoClass *type_class = mono_object_class (type);
3774
3775         if (is_sre_generic_instance (type_class)) {
3776                 MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
3777                 MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
3778                 return_val_if_nok (error, NULL);
3779                 gklass = mono_class_from_mono_type (generic_type);
3780         } else if (is_sre_type_builder (type_class)) {
3781                 MonoType *t = mono_reflection_type_get_handle (type, error);
3782                 return_val_if_nok (error, NULL);
3783                 gklass = mono_class_from_mono_type (t);
3784         } else if (type->type) {
3785                 gklass = mono_class_from_mono_type (type->type);
3786                 gklass = mono_class_get_generic_type_definition (gklass);
3787         } else {
3788                 g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
3789         }
3790
3791         if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
3792                 if (((MonoReflectionMethodBuilder*)obj)->mhandle)
3793                         method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
3794                 else {
3795                         method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
3796                         if (!method)
3797                                 return NULL;
3798                 }
3799         else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
3800                 method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
3801                 if (!method)
3802                         return NULL;
3803         } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
3804                 method = ((MonoReflectionMethod *) obj)->method;
3805         else {
3806                 method = NULL; /* prevent compiler warning */
3807                 g_error ("can't handle type %s", obj->vtable->klass->name);
3808         }
3809
3810         MonoType *t = mono_reflection_type_get_handle (type, error);
3811         return_val_if_nok (error, NULL);
3812         return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
3813 }
3814
3815 static void
3816 reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoError *error)
3817 {
3818         MonoGenericClass *gclass;
3819         MonoClass *klass, *gklass;
3820         MonoType *gtype;
3821
3822         mono_error_init (error);
3823
3824         gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
3825         return_if_nok (error);
3826         klass = mono_class_from_mono_type (gtype);
3827         g_assert (gtype->type == MONO_TYPE_GENERICINST);
3828         gclass = gtype->data.generic_class;
3829
3830         if (!gclass->is_dynamic)
3831                 return;
3832
3833         gklass = gclass->container_class;
3834         mono_class_init (gklass);
3835
3836         /* Mark this as needing synchronization with its generic container */
3837         gclass->need_sync = TRUE;
3838 }
3839
3840 void
3841 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
3842 {
3843         MonoError error;
3844         reflection_generic_class_initialize (type, &error);
3845         mono_error_set_pending_exception (&error);
3846 }
3847
3848 /**
3849  * fix_partial_generic_class:
3850  * @klass: a generic instantiation MonoClass
3851  * @error: set on error
3852  *
3853  * Assumes that the generic container of @klass has its vtable
3854  * initialized, and updates the parent class, interfaces, methods and
3855  * fields of @klass by inflating the types using the generic context.
3856  *
3857  * On success returns TRUE, on failure returns FALSE and sets @error.
3858  *
3859  */
3860 static gboolean
3861 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3862 {
3863         MonoClass *gklass = klass->generic_class->container_class;
3864         int i;
3865
3866         mono_error_init (error);
3867
3868         if (klass->wastypebuilder)
3869                 return TRUE;
3870
3871         if (klass->parent != gklass->parent) {
3872                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
3873                 if (mono_error_ok (error)) {
3874                         MonoClass *parent = mono_class_from_mono_type (parent_type);
3875                         mono_metadata_free_type (parent_type);
3876                         if (parent != klass->parent) {
3877                                 /*fool mono_class_setup_parent*/
3878                                 klass->supertypes = NULL;
3879                                 mono_class_setup_parent (klass, parent);
3880                         }
3881                 } else {
3882                         if (gklass->wastypebuilder)
3883                                 klass->wastypebuilder = TRUE;
3884                         return FALSE;
3885                 }
3886         }
3887
3888         if (!klass->generic_class->need_sync)
3889                 return TRUE;
3890
3891         if (klass->method.count != gklass->method.count) {
3892                 klass->method.count = gklass->method.count;
3893                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
3894
3895                 for (i = 0; i < klass->method.count; i++) {
3896                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3897                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
3898                         mono_error_assert_ok (error);
3899                 }
3900         }
3901
3902         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3903                 klass->interface_count = gklass->interface_count;
3904                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3905                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3906
3907                 for (i = 0; i < gklass->interface_count; ++i) {
3908                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3909                         return_val_if_nok (error, FALSE);
3910
3911                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3912                         mono_metadata_free_type (iface_type);
3913
3914                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
3915                                 return FALSE;
3916                 }
3917                 klass->interfaces_inited = 1;
3918         }
3919
3920         if (klass->field.count != gklass->field.count) {
3921                 klass->field.count = gklass->field.count;
3922                 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
3923
3924                 for (i = 0; i < klass->field.count; i++) {
3925                         klass->fields [i] = gklass->fields [i];
3926                         klass->fields [i].parent = klass;
3927                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3928                         return_val_if_nok (error, FALSE);
3929                 }
3930         }
3931
3932         /*We can only finish with this klass once it's parent has as well*/
3933         if (gklass->wastypebuilder)
3934                 klass->wastypebuilder = TRUE;
3935         return TRUE;
3936 }
3937
3938 /**
3939  * ensure_generic_class_runtime_vtable:
3940  * @klass a generic class
3941  * @error set on error
3942  *
3943  * Ensures that the generic container of @klass has a vtable and
3944  * returns TRUE on success.  On error returns FALSE and sets @error.
3945  */
3946 static gboolean
3947 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3948 {
3949         MonoClass *gklass = klass->generic_class->container_class;
3950
3951         mono_error_init (error);
3952
3953         if (!ensure_runtime_vtable (gklass, error))
3954                 return FALSE;
3955
3956         return fix_partial_generic_class (klass, error);
3957 }
3958
3959 /**
3960  * ensure_runtime_vtable:
3961  * @klass the class
3962  * @error set on error
3963  *
3964  * Ensures that @klass has a vtable and returns TRUE on success. On
3965  * error returns FALSE and sets @error.
3966  */
3967 static gboolean
3968 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3969 {
3970         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3971         int i, num, j;
3972
3973         mono_error_init (error);
3974
3975         if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
3976                 return TRUE;
3977         if (klass->parent)
3978                 if (!ensure_runtime_vtable (klass->parent, error))
3979                         return FALSE;
3980
3981         if (tb) {
3982                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3983                 num += tb->num_methods;
3984                 klass->method.count = num;
3985                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3986                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3987                 for (i = 0; i < num; ++i) {
3988                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3989                         if (!ctor)
3990                                 return FALSE;
3991                         klass->methods [i] = ctor;
3992                 }
3993                 num = tb->num_methods;
3994                 j = i;
3995                 for (i = 0; i < num; ++i) {
3996                         MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3997                         if (!meth)
3998                                 return FALSE;
3999                         klass->methods [j++] = meth;
4000                 }
4001         
4002                 if (tb->interfaces) {
4003                         klass->interface_count = mono_array_length (tb->interfaces);
4004                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
4005                         for (i = 0; i < klass->interface_count; ++i) {
4006                                 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
4007                                 return_val_if_nok (error, FALSE);
4008                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
4009                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
4010                                         return FALSE;
4011                         }
4012                         klass->interfaces_inited = 1;
4013                 }
4014         } else if (klass->generic_class){
4015                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
4016                         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4017                         return FALSE;
4018                 }
4019         }
4020
4021         if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
4022                 int slot_num = 0;
4023                 for (i = 0; i < klass->method.count; ++i) {
4024                         MonoMethod *im = klass->methods [i];
4025                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
4026                                 im->slot = slot_num++;
4027                 }
4028                 
4029                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
4030                 mono_class_setup_interface_offsets (klass);
4031                 mono_class_setup_interface_id (klass);
4032         }
4033
4034         /*
4035          * The generic vtable is needed even if image->run is not set since some
4036          * runtime code like ves_icall_Type_GetMethodsByName depends on 
4037          * method->slot being defined.
4038          */
4039
4040         /* 
4041          * tb->methods could not be freed since it is used for determining 
4042          * overrides during dynamic vtable construction.
4043          */
4044
4045         return TRUE;
4046 }
4047
4048 static MonoMethod*
4049 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
4050 {
4051         mono_error_init (error);
4052         MonoClass *klass = mono_object_class (method);
4053         if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
4054                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
4055                 return sr_method->method;
4056         }
4057         if (is_sre_method_builder (klass)) {
4058                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
4059                 return mb->mhandle;
4060         }
4061         if (mono_is_sre_method_on_tb_inst (klass)) {
4062                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
4063                 MonoMethod *result;
4064                 /*FIXME move this to a proper method and unify with resolve_object*/
4065                 if (m->method_args) {
4066                         result = mono_reflection_method_on_tb_inst_get_handle (m, error);
4067                 } else {
4068                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
4069                         return_val_if_nok (error, NULL);
4070                         MonoClass *inflated_klass = mono_class_from_mono_type (type);
4071                         MonoMethod *mono_method;
4072
4073                         if (is_sre_method_builder (mono_object_class (m->mb)))
4074                                 mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
4075                         else if (is_sr_mono_method (mono_object_class (m->mb)))
4076                                 mono_method = ((MonoReflectionMethod *)m->mb)->method;
4077                         else
4078                                 g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
4079
4080                         result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
4081                 }
4082                 return result;
4083         }
4084
4085         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
4086         return NULL;
4087 }
4088
4089 void
4090 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4091 {
4092         MonoReflectionTypeBuilder *tb;
4093         int i, j, onum;
4094         MonoReflectionMethod *m;
4095
4096         mono_error_init (error);
4097         *overrides = NULL;
4098         *num_overrides = 0;
4099
4100         g_assert (image_is_dynamic (klass->image));
4101
4102         if (!mono_class_get_ref_info (klass))
4103                 return;
4104
4105         g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
4106
4107         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
4108
4109         onum = 0;
4110         if (tb->methods) {
4111                 for (i = 0; i < tb->num_methods; ++i) {
4112                         MonoReflectionMethodBuilder *mb = 
4113                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4114                         if (mb->override_methods)
4115                                 onum += mono_array_length (mb->override_methods);
4116                 }
4117         }
4118
4119         if (onum) {
4120                 *overrides = g_new0 (MonoMethod*, onum * 2);
4121
4122                 onum = 0;
4123                 for (i = 0; i < tb->num_methods; ++i) {
4124                         MonoReflectionMethodBuilder *mb = 
4125                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4126                         if (mb->override_methods) {
4127                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
4128                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
4129
4130                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
4131                                         return_if_nok (error);
4132                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
4133
4134                                         g_assert (mb->mhandle);
4135
4136                                         onum ++;
4137                                 }
4138                         }
4139                 }
4140         }
4141
4142         *num_overrides = onum;
4143 }
4144
4145 static void
4146 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
4147 {
4148         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4149         MonoReflectionFieldBuilder *fb;
4150         MonoClassField *field;
4151         MonoImage *image = klass->image;
4152         const char *p, *p2;
4153         int i;
4154         guint32 len, idx, real_size = 0;
4155
4156         klass->field.count = tb->num_fields;
4157         klass->field.first = 0;
4158
4159         mono_error_init (error);
4160
4161         if (tb->class_size) {
4162                 if ((tb->packing_size & 0xffffff00) != 0) {
4163                         char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
4164                         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
4165                         return;
4166                 }
4167                 klass->packing_size = tb->packing_size;
4168                 real_size = klass->instance_size + tb->class_size;
4169         }
4170
4171         if (!klass->field.count) {
4172                 klass->instance_size = MAX (klass->instance_size, real_size);
4173                 return;
4174         }
4175         
4176         klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
4177         mono_class_alloc_ext (klass);
4178         klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
4179         /*
4180         This is, guess what, a hack.
4181         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
4182         On the static path no field class is resolved, only types are built. This is the right thing to do
4183         but we suck.
4184         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
4185         */
4186         klass->size_inited = 1;
4187
4188         for (i = 0; i < klass->field.count; ++i) {
4189                 MonoArray *rva_data;
4190                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4191                 field = &klass->fields [i];
4192                 field->name = mono_string_to_utf8_image (image, fb->name, error);
4193                 if (!mono_error_ok (error))
4194                         return;
4195                 if (fb->attrs) {
4196                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4197                         return_if_nok (error);
4198                         field->type = mono_metadata_type_dup (klass->image, type);
4199                         field->type->attrs = fb->attrs;
4200                 } else {
4201                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4202                         return_if_nok (error);
4203                 }
4204
4205                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
4206                         char *base = mono_array_addr (rva_data, char, 0);
4207                         size_t size = mono_array_length (rva_data);
4208                         char *data = (char *)mono_image_alloc (klass->image, size);
4209                         memcpy (data, base, size);
4210                         klass->ext->field_def_values [i].data = data;
4211                 }
4212                 if (fb->offset != -1)
4213                         field->offset = fb->offset;
4214                 field->parent = klass;
4215                 fb->handle = field;
4216                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
4217
4218                 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
4219                         klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
4220                 }
4221                 if (fb->def_value) {
4222                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4223                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
4224                         idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
4225                         /* Copy the data from the blob since it might get realloc-ed */
4226                         p = assembly->blob.data + idx;
4227                         len = mono_metadata_decode_blob_size (p, &p2);
4228                         len += p2 - p;
4229                         klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
4230                         memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
4231                 }
4232         }
4233
4234         klass->instance_size = MAX (klass->instance_size, real_size);
4235         mono_class_layout_fields (klass, klass->instance_size);
4236 }
4237
4238 static void
4239 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
4240 {
4241         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4242         MonoReflectionPropertyBuilder *pb;
4243         MonoImage *image = klass->image;
4244         MonoProperty *properties;
4245         int i;
4246
4247         mono_error_init (error);
4248
4249         if (!klass->ext)
4250                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4251
4252         klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
4253         klass->ext->property.first = 0;
4254
4255         properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
4256         klass->ext->properties = properties;
4257         for (i = 0; i < klass->ext->property.count; ++i) {
4258                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
4259                 properties [i].parent = klass;
4260                 properties [i].attrs = pb->attrs;
4261                 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
4262                 if (!mono_error_ok (error))
4263                         return;
4264                 if (pb->get_method)
4265                         properties [i].get = pb->get_method->mhandle;
4266                 if (pb->set_method)
4267                         properties [i].set = pb->set_method->mhandle;
4268
4269                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
4270                 if (pb->def_value) {
4271                         guint32 len, idx;
4272                         const char *p, *p2;
4273                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4274                         if (!klass->ext->prop_def_values)
4275                                 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
4276                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
4277                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
4278                         /* Copy the data from the blob since it might get realloc-ed */
4279                         p = assembly->blob.data + idx;
4280                         len = mono_metadata_decode_blob_size (p, &p2);
4281                         len += p2 - p;
4282                         klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
4283                         memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
4284                 }
4285         }
4286 }
4287
4288 static MonoReflectionEvent *
4289 reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
4290 {
4291         mono_error_init (error);
4292
4293         MonoEvent *event = g_new0 (MonoEvent, 1);
4294         MonoClass *klass;
4295
4296         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4297         if (!is_ok (error)) {
4298                 g_free (event);
4299                 return NULL;
4300         }
4301         klass = mono_class_from_mono_type (type);
4302
4303         event->parent = klass;
4304         event->attrs = eb->attrs;
4305         event->name = mono_string_to_utf8_checked (eb->name, error);
4306         if (!is_ok (error)) {
4307                 g_free (event);
4308                 return NULL;
4309         }
4310         if (eb->add_method)
4311                 event->add = eb->add_method->mhandle;
4312         if (eb->remove_method)
4313                 event->remove = eb->remove_method->mhandle;
4314         if (eb->raise_method)
4315                 event->raise = eb->raise_method->mhandle;
4316
4317 #ifndef MONO_SMALL_CONFIG
4318         if (eb->other_methods) {
4319                 int j;
4320                 event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
4321                 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4322                         MonoReflectionMethodBuilder *mb = 
4323                                 mono_array_get (eb->other_methods,
4324                                                 MonoReflectionMethodBuilder*, j);
4325                         event->other [j] = mb->mhandle;
4326                 }
4327         }
4328 #endif
4329
4330         MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
4331         if (!is_ok (error)) {
4332 #ifndef MONO_SMALL_CONFIG
4333                 g_free (event->other);
4334 #endif
4335                 g_free (event);
4336                 return NULL;
4337         }
4338         return ev_obj;
4339 }
4340
4341 MonoReflectionEvent *
4342 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
4343 {
4344         MonoError error;
4345         MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
4346         mono_error_set_pending_exception (&error);
4347         return result;
4348 }
4349
4350 static void
4351 typebuilder_setup_events (MonoClass *klass, MonoError *error)
4352 {
4353         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4354         MonoReflectionEventBuilder *eb;
4355         MonoImage *image = klass->image;
4356         MonoEvent *events;
4357         int i;
4358
4359         mono_error_init (error);
4360
4361         if (!klass->ext)
4362                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4363
4364         klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
4365         klass->ext->event.first = 0;
4366
4367         events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
4368         klass->ext->events = events;
4369         for (i = 0; i < klass->ext->event.count; ++i) {
4370                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
4371                 events [i].parent = klass;
4372                 events [i].attrs = eb->attrs;
4373                 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
4374                 if (!mono_error_ok (error))
4375                         return;
4376                 if (eb->add_method)
4377                         events [i].add = eb->add_method->mhandle;
4378                 if (eb->remove_method)
4379                         events [i].remove = eb->remove_method->mhandle;
4380                 if (eb->raise_method)
4381                         events [i].raise = eb->raise_method->mhandle;
4382
4383 #ifndef MONO_SMALL_CONFIG
4384                 if (eb->other_methods) {
4385                         int j;
4386                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
4387                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4388                                 MonoReflectionMethodBuilder *mb = 
4389                                         mono_array_get (eb->other_methods,
4390                                                                         MonoReflectionMethodBuilder*, j);
4391                                 events [i].other [j] = mb->mhandle;
4392                         }
4393                 }
4394 #endif
4395                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
4396         }
4397 }
4398
4399 struct remove_instantiations_user_data
4400 {
4401         MonoClass *klass;
4402         MonoError *error;
4403 };
4404
4405 static gboolean
4406 remove_instantiations_of_and_ensure_contents (gpointer key,
4407                                                   gpointer value,
4408                                                   gpointer user_data)
4409 {
4410         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
4411         MonoType *type = (MonoType*)key;
4412         MonoClass *klass = data->klass;
4413         gboolean already_failed = !is_ok (data->error);
4414         MonoError lerror;
4415         MonoError *error = already_failed ? &lerror : data->error;
4416
4417         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
4418                 MonoClass *inst_klass = mono_class_from_mono_type (type);
4419                 //Ensure it's safe to use it.
4420                 if (!fix_partial_generic_class (inst_klass, error)) {
4421                         mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4422                         // Marked the class with failure, but since some other instantiation already failed,
4423                         // just report that one, and swallow the error from this one.
4424                         if (already_failed)
4425                                 mono_error_cleanup (error);
4426                 }
4427                 return TRUE;
4428         } else
4429                 return FALSE;
4430 }
4431
4432 static void
4433 check_array_for_usertypes (MonoArray *arr, MonoError *error)
4434 {
4435         mono_error_init (error);
4436         int i;
4437
4438         if (!arr)
4439                 return;
4440
4441         for (i = 0; i < mono_array_length (arr); ++i) {
4442                 RESOLVE_ARRAY_TYPE_ELEMENT (arr, i, error);
4443                 if (!mono_error_ok (error))
4444                         break;
4445         }
4446 }
4447
4448 void
4449 mono_reflection_check_array_for_usertypes (MonoArray *arr, MonoError *error)
4450 {
4451         check_array_for_usertypes (arr, error);
4452 }
4453
4454 MonoReflectionType*
4455 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4456 {
4457         MonoError error;
4458         MonoClass *klass;
4459         MonoDomain* domain;
4460         MonoReflectionType* res;
4461         int i, j;
4462
4463         mono_error_init (&error);
4464
4465         domain = mono_object_domain (tb);
4466         klass = mono_class_from_mono_type (tb->type.type);
4467
4468         /*
4469          * Check for user defined Type subclasses.
4470          */
4471         RESOLVE_TYPE (tb->parent, &error);
4472         if (!is_ok (&error))
4473                 goto failure_unlocked;
4474         check_array_for_usertypes (tb->interfaces, &error);
4475         if (!is_ok (&error))
4476                 goto failure_unlocked;
4477         if (tb->fields) {
4478                 for (i = 0; i < mono_array_length (tb->fields); ++i) {
4479                         MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4480                         if (fb) {
4481                                 RESOLVE_TYPE (fb->type, &error);
4482                                 if (!is_ok (&error))
4483                                         goto failure_unlocked;
4484                                 check_array_for_usertypes (fb->modreq, &error);
4485                                 if (!is_ok (&error))
4486                                         goto failure_unlocked;
4487                                 check_array_for_usertypes (fb->modopt, &error);
4488                                 if (!is_ok (&error))
4489                                         goto failure_unlocked;
4490                                 if (fb->marshal_info && fb->marshal_info->marshaltyperef) {
4491                                         RESOLVE_TYPE (fb->marshal_info->marshaltyperef, &error);
4492                                         if (!is_ok (&error))
4493                                                 goto failure_unlocked;
4494                                 }
4495                         }
4496                 }
4497         }
4498         if (tb->methods) {
4499                 for (i = 0; i < mono_array_length (tb->methods); ++i) {
4500                         MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)mono_array_get (tb->methods, gpointer, i);
4501                         if (mb) {
4502                                 RESOLVE_TYPE (mb->rtype, &error);
4503                                 if (!is_ok (&error))
4504                                         goto failure_unlocked;
4505                                 check_array_for_usertypes (mb->return_modreq, &error);
4506                                 if (!is_ok (&error))
4507                                         goto failure_unlocked;
4508                                 check_array_for_usertypes (mb->return_modopt, &error);
4509                                 if (!is_ok (&error))
4510                                         goto failure_unlocked;
4511                                 check_array_for_usertypes (mb->parameters, &error);
4512                                 if (!is_ok (&error))
4513                                         goto failure_unlocked;
4514                                 if (mb->param_modreq)
4515                                         for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
4516                                                 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
4517                                                 if (!is_ok (&error))
4518                                                         goto failure_unlocked;
4519                                         }
4520                                 if (mb->param_modopt)
4521                                         for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
4522                                                 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
4523                                                 if (!is_ok (&error))
4524                                                         goto failure_unlocked;
4525                                         }
4526                         }
4527                 }
4528         }
4529         if (tb->ctors) {
4530                 for (i = 0; i < mono_array_length (tb->ctors); ++i) {
4531                         MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)mono_array_get (tb->ctors, gpointer, i);
4532                         if (mb) {
4533                                 check_array_for_usertypes (mb->parameters, &error);
4534                                 if (!is_ok (&error))
4535                                         goto failure_unlocked;
4536                                 if (mb->param_modreq)
4537                                         for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
4538                                                 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
4539                                                 if (!is_ok (&error))
4540                                                         goto failure_unlocked;
4541                                         }
4542                                 if (mb->param_modopt)
4543                                         for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
4544                                                 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
4545                                                 if (!is_ok (&error))
4546                                                         goto failure_unlocked;
4547                                         }
4548                         }
4549                 }
4550         }
4551
4552         mono_save_custom_attrs (klass->image, klass, tb->cattrs);
4553
4554         /* 
4555          * we need to lock the domain because the lock will be taken inside
4556          * So, we need to keep the locking order correct.
4557          */
4558         mono_loader_lock ();
4559         mono_domain_lock (domain);
4560         if (klass->wastypebuilder) {
4561                 mono_domain_unlock (domain);
4562                 mono_loader_unlock ();
4563
4564                 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4565                 mono_error_set_pending_exception (&error);
4566
4567                 return res;
4568         }
4569         /*
4570          * Fields to set in klass:
4571          * the various flags: delegate/unicode/contextbound etc.
4572          */
4573         klass->flags = tb->attrs;
4574         klass->has_cctor = 1;
4575
4576         mono_class_setup_parent (klass, klass->parent);
4577         /* fool mono_class_setup_supertypes */
4578         klass->supertypes = NULL;
4579         mono_class_setup_supertypes (klass);
4580         mono_class_setup_mono_type (klass);
4581
4582 #if 0
4583         if (!((MonoDynamicImage*)klass->image)->run) {
4584                 if (klass->generic_container) {
4585                         /* FIXME: The code below can't handle generic classes */
4586                         klass->wastypebuilder = TRUE;
4587                         mono_loader_unlock ();
4588                         mono_domain_unlock (domain);
4589
4590                         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4591                         mono_error_set_pending_exception (&error);
4592
4593                         return res;
4594                 }
4595         }
4596 #endif
4597
4598         /* enums are done right away */
4599         if (!klass->enumtype)
4600                 if (!ensure_runtime_vtable (klass, &error))
4601                         goto failure;
4602
4603         if (tb->subtypes) {
4604                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
4605                         MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
4606                         mono_class_alloc_ext (klass);
4607                         MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
4608                         if (!is_ok (&error)) goto failure;
4609                         klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
4610                 }
4611         }
4612
4613         klass->nested_classes_inited = TRUE;
4614
4615         /* fields and object layout */
4616         if (klass->parent) {
4617                 if (!klass->parent->size_inited)
4618                         mono_class_init (klass->parent);
4619                 klass->instance_size = klass->parent->instance_size;
4620                 klass->sizes.class_size = 0;
4621                 klass->min_align = klass->parent->min_align;
4622                 /* if the type has no fields we won't call the field_setup
4623                  * routine which sets up klass->has_references.
4624                  */
4625                 klass->has_references |= klass->parent->has_references;
4626         } else {
4627                 klass->instance_size = sizeof (MonoObject);
4628                 klass->min_align = 1;
4629         }
4630
4631         /* FIXME: handle packing_size and instance_size */
4632         typebuilder_setup_fields (klass, &error);
4633         if (!mono_error_ok (&error))
4634                 goto failure;
4635         typebuilder_setup_properties (klass, &error);
4636         if (!mono_error_ok (&error))
4637                 goto failure;
4638
4639         typebuilder_setup_events (klass, &error);
4640         if (!mono_error_ok (&error))
4641                 goto failure;
4642
4643         klass->wastypebuilder = TRUE;
4644
4645         /* 
4646          * If we are a generic TypeBuilder, there might be instantiations in the type cache
4647          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
4648          * we want to return normal System.MonoType objects, so clear these out from the cache.
4649          *
4650          * Together with this we must ensure the contents of all instances to match the created type.
4651          */
4652         if (domain->type_hash && klass->generic_container) {
4653                 struct remove_instantiations_user_data data;
4654                 data.klass = klass;
4655                 data.error = &error;
4656                 mono_error_assert_ok (&error);
4657                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
4658                 if (!is_ok (&error))
4659                         goto failure;
4660         }
4661
4662         mono_domain_unlock (domain);
4663         mono_loader_unlock ();
4664
4665         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
4666                 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4667                 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
4668                 goto failure_unlocked;
4669         }
4670
4671         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4672         if (!is_ok (&error))
4673                 goto failure_unlocked;
4674
4675         g_assert (res != (MonoReflectionType*)tb);
4676
4677         return res;
4678
4679 failure:
4680         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4681         klass->wastypebuilder = TRUE;
4682         mono_domain_unlock (domain);
4683         mono_loader_unlock ();
4684 failure_unlocked:
4685         mono_error_set_pending_exception (&error);
4686         return NULL;
4687 }
4688
4689 static gboolean
4690 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
4691 {
4692         MonoGenericParamFull *param;
4693         MonoImage *image;
4694         MonoClass *pklass;
4695
4696         mono_error_init (error);
4697
4698         image = &gparam->tbuilder->module->dynamic_image->image;
4699
4700         param = mono_image_new0 (image, MonoGenericParamFull, 1);
4701
4702         param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
4703         mono_error_assert_ok (error);
4704         param->param.num = gparam->index;
4705
4706         if (gparam->mbuilder) {
4707                 if (!gparam->mbuilder->generic_container) {
4708                         MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
4709                         return_val_if_nok (error, FALSE);
4710
4711                         MonoClass *klass = mono_class_from_mono_type (tb);
4712                         gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4713                         gparam->mbuilder->generic_container->is_method = TRUE;
4714                         /* 
4715                          * Cannot set owner.method, since the MonoMethod is not created yet.
4716                          * Set the image field instead, so type_in_image () works.
4717                          */
4718                         gparam->mbuilder->generic_container->is_anonymous = TRUE;
4719                         gparam->mbuilder->generic_container->owner.image = klass->image;
4720                 }
4721                 param->param.owner = gparam->mbuilder->generic_container;
4722         } else if (gparam->tbuilder) {
4723                 if (!gparam->tbuilder->generic_container) {
4724                         MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
4725                         return_val_if_nok (error, FALSE);
4726                         MonoClass *klass = mono_class_from_mono_type (tb);
4727                         gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4728                         gparam->tbuilder->generic_container->owner.klass = klass;
4729                 }
4730                 param->param.owner = gparam->tbuilder->generic_container;
4731         }
4732
4733         pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
4734
4735         gparam->type.type = &pklass->byval_arg;
4736
4737         mono_class_set_ref_info (pklass, gparam);
4738         mono_image_append_class_to_reflection_info_set (pklass);
4739
4740         return TRUE;
4741 }
4742
4743 void
4744 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
4745 {
4746         MonoError error;
4747         (void) reflection_initialize_generic_parameter (gparam, &error);
4748         mono_error_set_pending_exception (&error);
4749 }
4750
4751
4752 typedef struct {
4753         MonoMethod *handle;
4754         MonoDomain *domain;
4755 } DynamicMethodReleaseData;
4756
4757 /*
4758  * The runtime automatically clean up those after finalization.
4759 */      
4760 static MonoReferenceQueue *dynamic_method_queue;
4761
4762 static void
4763 free_dynamic_method (void *dynamic_method)
4764 {
4765         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
4766         MonoDomain *domain = data->domain;
4767         MonoMethod *method = data->handle;
4768         guint32 dis_link;
4769
4770         mono_domain_lock (domain);
4771         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
4772         g_hash_table_remove (domain->method_to_dyn_method, method);
4773         mono_domain_unlock (domain);
4774         g_assert (dis_link);
4775         mono_gchandle_free (dis_link);
4776
4777         mono_runtime_free_method (domain, method);
4778         g_free (data);
4779 }
4780
4781 static gboolean
4782 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
4783 {
4784         MonoReferenceQueue *queue;
4785         MonoMethod *handle;
4786         DynamicMethodReleaseData *release_data;
4787         ReflectionMethodBuilder rmb;
4788         MonoMethodSignature *sig;
4789         MonoClass *klass;
4790         MonoDomain *domain;
4791         GSList *l;
4792         int i;
4793
4794         mono_error_init (error);
4795
4796         if (mono_runtime_is_shutting_down ()) {
4797                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
4798                 return FALSE;
4799         }
4800
4801         if (!(queue = dynamic_method_queue)) {
4802                 mono_loader_lock ();
4803                 if (!(queue = dynamic_method_queue))
4804                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
4805                 mono_loader_unlock ();
4806         }
4807
4808         sig = dynamic_method_to_signature (mb, error);
4809         return_val_if_nok (error, FALSE);
4810
4811         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
4812
4813         /*
4814          * Resolve references.
4815          */
4816         /* 
4817          * Every second entry in the refs array is reserved for storing handle_class,
4818          * which is needed by the ldtoken implementation in the JIT.
4819          */
4820         rmb.nrefs = mb->nrefs;
4821         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
4822         for (i = 0; i < mb->nrefs; i += 2) {
4823                 MonoClass *handle_class;
4824                 gpointer ref;
4825                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
4826
4827                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4828                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4829                         /*
4830                          * The referenced DynamicMethod should already be created by the managed
4831                          * code, except in the case of circular references. In that case, we store
4832                          * method in the refs array, and fix it up later when the referenced 
4833                          * DynamicMethod is created.
4834                          */
4835                         if (method->mhandle) {
4836                                 ref = method->mhandle;
4837                         } else {
4838                                 /* FIXME: GC object stored in unmanaged memory */
4839                                 ref = method;
4840
4841                                 /* FIXME: GC object stored in unmanaged memory */
4842                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
4843                         }
4844                         handle_class = mono_defaults.methodhandle_class;
4845                 } else {
4846                         MonoException *ex = NULL;
4847                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
4848                         if (!is_ok  (error)) {
4849                                 g_free (rmb.refs);
4850                                 return FALSE;
4851                         }
4852                         if (!ref)
4853                                 ex = mono_get_exception_type_load (NULL, NULL);
4854                         else if (mono_security_core_clr_enabled ())
4855                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
4856
4857                         if (ex) {
4858                                 g_free (rmb.refs);
4859                                 mono_error_set_exception_instance (error, ex);
4860                                 return FALSE;
4861                         }
4862                 }
4863
4864                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4865                 rmb.refs [i + 1] = handle_class;
4866         }               
4867
4868         if (mb->owner) {
4869                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
4870                 if (!is_ok (error)) {
4871                         g_free (rmb.refs);
4872                         return FALSE;
4873                 }
4874                 klass = mono_class_from_mono_type (owner_type);
4875         } else {
4876                 klass = mono_defaults.object_class;
4877         }
4878
4879         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
4880         g_free (rmb.refs);
4881         return_val_if_nok (error, FALSE);
4882
4883         release_data = g_new (DynamicMethodReleaseData, 1);
4884         release_data->handle = handle;
4885         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
4886         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
4887                 g_free (release_data);
4888
4889         /* Fix up refs entries pointing at us */
4890         for (l = mb->referenced_by; l; l = l->next) {
4891                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
4892                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
4893                 gpointer *data;
4894                 
4895                 g_assert (method->mhandle);
4896
4897                 data = (gpointer*)wrapper->method_data;
4898                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
4899                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
4900                                 data [i + 1] = mb->mhandle;
4901                 }
4902         }
4903         g_slist_free (mb->referenced_by);
4904
4905         /* ilgen is no longer needed */
4906         mb->ilgen = NULL;
4907
4908         domain = mono_domain_get ();
4909         mono_domain_lock (domain);
4910         if (!domain->method_to_dyn_method)
4911                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4912         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4913         mono_domain_unlock (domain);
4914
4915         return TRUE;
4916 }
4917
4918 void
4919 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4920 {
4921         MonoError error;
4922         (void) reflection_create_dynamic_method (mb, &error);
4923         mono_error_set_pending_exception (&error);
4924 }
4925
4926 #endif /* DISABLE_REFLECTION_EMIT */
4927
4928 MonoMethodSignature *
4929 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4930 {
4931         MonoMethodSignature *sig;
4932         g_assert (image_is_dynamic (image));
4933
4934         mono_error_init (error);
4935
4936         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4937         if (sig)
4938                 return sig;
4939
4940         return mono_method_signature_checked (method, error);
4941 }
4942
4943 #ifndef DISABLE_REFLECTION_EMIT
4944
4945 /*
4946  * ensure_complete_type:
4947  *
4948  *   Ensure that KLASS is completed if it is a dynamic type, or references
4949  * dynamic types.
4950  */
4951 static void
4952 ensure_complete_type (MonoClass *klass, MonoError *error)
4953 {
4954         mono_error_init (error);
4955
4956         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
4957                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4958
4959                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4960                 return_if_nok (error);
4961
4962                 // Asserting here could break a lot of code
4963                 //g_assert (klass->wastypebuilder);
4964         }
4965
4966         if (klass->generic_class) {
4967                 MonoGenericInst *inst = klass->generic_class->context.class_inst;
4968                 int i;
4969
4970                 for (i = 0; i < inst->type_argc; ++i) {
4971                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4972                         return_if_nok (error);
4973                 }
4974         }
4975 }
4976
4977 gpointer
4978 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4979 {
4980         gpointer result = NULL;
4981
4982         mono_error_init (error);
4983
4984         if (strcmp (obj->vtable->klass->name, "String") == 0) {
4985                 result = mono_string_intern_checked ((MonoString*)obj, error);
4986                 return_val_if_nok (error, NULL);
4987                 *handle_class = mono_defaults.string_class;
4988                 g_assert (result);
4989         } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
4990                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4991                 return_val_if_nok (error, NULL);
4992                 MonoClass *mc = mono_class_from_mono_type (type);
4993                 if (!mono_class_init (mc)) {
4994                         mono_error_set_for_class_failure (error, mc);
4995                         return NULL;
4996                 }
4997
4998                 if (context) {
4999                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
5000                         return_val_if_nok (error, NULL);
5001
5002                         result = mono_class_from_mono_type (inflated);
5003                         mono_metadata_free_type (inflated);
5004                 } else {
5005                         result = mono_class_from_mono_type (type);
5006                 }
5007                 *handle_class = mono_defaults.typehandle_class;
5008                 g_assert (result);
5009         } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
5010                    strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
5011                    strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
5012                    strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
5013                 result = ((MonoReflectionMethod*)obj)->method;
5014                 if (context) {
5015                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5016                         mono_error_assert_ok (error);
5017                 }
5018                 *handle_class = mono_defaults.methodhandle_class;
5019                 g_assert (result);
5020         } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
5021                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
5022                 result = mb->mhandle;
5023                 if (!result) {
5024                         /* Type is not yet created */
5025                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
5026
5027                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5028                         return_val_if_nok (error, NULL);
5029
5030                         /*
5031                          * Hopefully this has been filled in by calling CreateType() on the
5032                          * TypeBuilder.
5033                          */
5034                         /*
5035                          * TODO: This won't work if the application finishes another 
5036                          * TypeBuilder instance instead of this one.
5037                          */
5038                         result = mb->mhandle;
5039                 }
5040                 if (context) {
5041                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5042                         mono_error_assert_ok (error);
5043                 }
5044                 *handle_class = mono_defaults.methodhandle_class;
5045         } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
5046                 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
5047
5048                 result = cb->mhandle;
5049                 if (!result) {
5050                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
5051
5052                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5053                         return_val_if_nok (error, NULL);
5054                         result = cb->mhandle;
5055                 }
5056                 if (context) {
5057                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5058                         mono_error_assert_ok (error);
5059                 }
5060                 *handle_class = mono_defaults.methodhandle_class;
5061         } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
5062                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
5063
5064                 ensure_complete_type (field->parent, error);
5065                 return_val_if_nok (error, NULL);
5066
5067                 if (context) {
5068                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
5069                         return_val_if_nok (error, NULL);
5070
5071                         MonoClass *klass = mono_class_from_mono_type (inflated);
5072                         MonoClassField *inflated_field;
5073                         gpointer iter = NULL;
5074                         mono_metadata_free_type (inflated);
5075                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
5076                                 if (!strcmp (field->name, inflated_field->name))
5077                                         break;
5078                         }
5079                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
5080                         result = inflated_field;
5081                 } else {
5082                         result = field;
5083                 }
5084                 *handle_class = mono_defaults.fieldhandle_class;
5085                 g_assert (result);
5086         } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
5087                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
5088                 result = fb->handle;
5089
5090                 if (!result) {
5091                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
5092
5093                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5094                         return_val_if_nok (error, NULL);
5095                         result = fb->handle;
5096                 }
5097
5098                 if (fb->handle && fb->handle->parent->generic_container) {
5099                         MonoClass *klass = fb->handle->parent;
5100                         MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
5101                         return_val_if_nok (error, NULL);
5102
5103                         MonoClass *inflated = mono_class_from_mono_type (type);
5104
5105                         result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
5106                         g_assert (result);
5107                         mono_metadata_free_type (type);
5108                 }
5109                 *handle_class = mono_defaults.fieldhandle_class;
5110         } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
5111                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
5112                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
5113                 return_val_if_nok (error, NULL);
5114                 MonoClass *klass;
5115
5116                 klass = type->data.klass;
5117                 if (klass->wastypebuilder) {
5118                         /* Already created */
5119                         result = klass;
5120                 }
5121                 else {
5122                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5123                         return_val_if_nok (error, NULL);
5124                         result = type->data.klass;
5125                         g_assert (result);
5126                 }
5127                 *handle_class = mono_defaults.typehandle_class;
5128         } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
5129                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
5130                 MonoMethodSignature *sig;
5131                 int nargs, i;
5132
5133                 if (helper->arguments)
5134                         nargs = mono_array_length (helper->arguments);
5135                 else
5136                         nargs = 0;
5137
5138                 sig = mono_metadata_signature_alloc (image, nargs);
5139                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
5140                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
5141
5142                 if (helper->unmanaged_call_conv) { /* unmanaged */
5143                         sig->call_convention = helper->unmanaged_call_conv - 1;
5144                         sig->pinvoke = TRUE;
5145                 } else if (helper->call_conv & 0x02) {
5146                         sig->call_convention = MONO_CALL_VARARG;
5147                 } else {
5148                         sig->call_convention = MONO_CALL_DEFAULT;
5149                 }
5150
5151                 sig->param_count = nargs;
5152                 /* TODO: Copy type ? */
5153                 sig->ret = helper->return_type->type;
5154                 for (i = 0; i < nargs; ++i) {
5155                         sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
5156                         if (!is_ok (error)) {
5157                                 image_g_free (image, sig);
5158                                 return NULL;
5159                         }
5160                 }
5161
5162                 result = sig;
5163                 *handle_class = NULL;
5164         } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
5165                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
5166                 /* Already created by the managed code */
5167                 g_assert (method->mhandle);
5168                 result = method->mhandle;
5169                 *handle_class = mono_defaults.methodhandle_class;
5170         } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
5171                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
5172                 return_val_if_nok (error, NULL);
5173                 type = mono_class_inflate_generic_type_checked (type, context, error);
5174                 return_val_if_nok (error, NULL);
5175
5176                 result = mono_class_from_mono_type (type);
5177                 *handle_class = mono_defaults.typehandle_class;
5178                 g_assert (result);
5179                 mono_metadata_free_type (type);
5180         } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
5181                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
5182                 return_val_if_nok (error, NULL);
5183                 type = mono_class_inflate_generic_type_checked (type, context, error);
5184                 return_val_if_nok (error, NULL);
5185
5186                 result = mono_class_from_mono_type (type);
5187                 *handle_class = mono_defaults.typehandle_class;
5188                 g_assert (result);
5189                 mono_metadata_free_type (type);
5190         } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
5191                 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
5192                 MonoClass *inflated;
5193                 MonoType *type;
5194                 MonoClassField *field;
5195
5196                 if (is_sre_field_builder (mono_object_class (f->fb)))
5197                         field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
5198                 else if (is_sr_mono_field (mono_object_class (f->fb)))
5199                         field = ((MonoReflectionField*)f->fb)->field;
5200                 else
5201                         g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
5202
5203                 MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
5204                 return_val_if_nok (error, NULL);
5205                 type = mono_class_inflate_generic_type_checked (finst, context, error);
5206                 return_val_if_nok (error, NULL);
5207
5208                 inflated = mono_class_from_mono_type (type);
5209
5210                 result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
5211                 ensure_complete_type (field->parent, error);
5212                 if (!is_ok (error)) {
5213                         mono_metadata_free_type (type);
5214                         return NULL;
5215                 }
5216
5217                 g_assert (result);
5218                 mono_metadata_free_type (type);
5219                 *handle_class = mono_defaults.fieldhandle_class;
5220         } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
5221                 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
5222                 MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
5223                 return_val_if_nok (error, NULL);
5224                 MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
5225                 return_val_if_nok (error, NULL);
5226
5227                 MonoClass *inflated_klass = mono_class_from_mono_type (type);
5228                 MonoMethod *method;
5229
5230                 if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
5231                         method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
5232                 else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
5233                         method = ((MonoReflectionMethod *)c->cb)->method;
5234                 else
5235                         g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
5236
5237                 result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
5238                 *handle_class = mono_defaults.methodhandle_class;
5239                 mono_metadata_free_type (type);
5240         } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
5241                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
5242                 if (m->method_args) {
5243                         result = mono_reflection_method_on_tb_inst_get_handle (m, error);
5244                         return_val_if_nok (error, NULL);
5245                         if (context) {
5246                                 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5247                                 mono_error_assert_ok (error);
5248                         }
5249                 } else {
5250                         MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
5251                         return_val_if_nok (error, NULL);
5252                         MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
5253                         return_val_if_nok (error, NULL);
5254
5255                         MonoClass *inflated_klass = mono_class_from_mono_type (type);
5256                         MonoMethod *method;
5257
5258                         if (is_sre_method_builder (mono_object_class (m->mb)))
5259                                 method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
5260                         else if (is_sr_mono_method (mono_object_class (m->mb)))
5261                                 method = ((MonoReflectionMethod *)m->mb)->method;
5262                         else
5263                                 g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
5264
5265                         result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
5266                         mono_metadata_free_type (type);
5267                 }
5268                 *handle_class = mono_defaults.methodhandle_class;
5269         } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
5270                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
5271                 MonoType *mtype;
5272                 MonoClass *klass;
5273                 MonoMethod *method;
5274                 gpointer iter;
5275                 char *name;
5276
5277                 mtype = mono_reflection_type_get_handle (m->parent, error);
5278                 return_val_if_nok (error, NULL);
5279                 klass = mono_class_from_mono_type (mtype);
5280
5281                 /* Find the method */
5282
5283                 name = mono_string_to_utf8_checked (m->name, error);
5284                 return_val_if_nok (error, NULL);
5285                 iter = NULL;
5286                 while ((method = mono_class_get_methods (klass, &iter))) {
5287                         if (!strcmp (method->name, name))
5288                                 break;
5289                 }
5290                 g_free (name);
5291
5292                 // FIXME:
5293                 g_assert (method);
5294                 // FIXME: Check parameters/return value etc. match
5295
5296                 result = method;
5297                 *handle_class = mono_defaults.methodhandle_class;
5298         } else if (is_sre_array (mono_object_get_class(obj)) ||
5299                                 is_sre_byref (mono_object_get_class(obj)) ||
5300                                 is_sre_pointer (mono_object_get_class(obj))) {
5301                 MonoReflectionType *ref_type = (MonoReflectionType *)obj;
5302                 MonoType *type = mono_reflection_type_get_handle (ref_type, error);
5303                 return_val_if_nok (error, NULL);
5304
5305                 if (context) {
5306                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
5307                         return_val_if_nok (error, NULL);
5308
5309                         result = mono_class_from_mono_type (inflated);
5310                         mono_metadata_free_type (inflated);
5311                 } else {
5312                         result = mono_class_from_mono_type (type);
5313                 }
5314                 *handle_class = mono_defaults.typehandle_class;
5315         } else {
5316                 g_print ("%s\n", obj->vtable->klass->name);
5317                 g_assert_not_reached ();
5318         }
5319         return result;
5320 }
5321
5322 #else /* DISABLE_REFLECTION_EMIT */
5323
5324 MonoArray*
5325 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
5326 {
5327         g_assert_not_reached ();
5328         return NULL;
5329 }
5330
5331 void
5332 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
5333 {
5334         g_assert_not_reached ();
5335 }
5336
5337 void
5338 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
5339 {
5340         g_assert_not_reached ();
5341 }
5342
5343 gboolean
5344 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
5345 {
5346         g_assert_not_reached ();
5347         return FALSE;
5348 }
5349
5350 void
5351 ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
5352 {
5353         g_assert_not_reached ();
5354 }
5355
5356 void
5357 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5358 {
5359         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
5360 }
5361
5362 static void
5363 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
5364 {
5365         g_assert_not_reached ();
5366 }
5367
5368 MonoReflectionModule *
5369 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
5370 {
5371         g_assert_not_reached ();
5372         return NULL;
5373 }
5374
5375 guint32
5376 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
5377 {
5378         g_assert_not_reached ();
5379         return 0;
5380 }
5381
5382 guint32
5383 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
5384 {
5385         g_assert_not_reached ();
5386         return 0;
5387 }
5388
5389 guint32
5390 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
5391                          gboolean create_open_instance, gboolean register_token, MonoError *error)
5392 {
5393         g_assert_not_reached ();
5394         return 0;
5395 }
5396
5397 void
5398 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
5399 {
5400         g_assert_not_reached ();
5401 }
5402
5403 void
5404 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
5405 {
5406         mono_error_init (error);
5407         *overrides = NULL;
5408         *num_overrides = 0;
5409 }
5410
5411 MonoReflectionEvent *
5412 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
5413 {
5414         g_assert_not_reached ();
5415         return NULL;
5416 }
5417
5418 MonoReflectionType*
5419 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
5420 {
5421         g_assert_not_reached ();
5422         return NULL;
5423 }
5424
5425 void
5426 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
5427 {
5428         g_assert_not_reached ();
5429 }
5430
5431 void 
5432 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
5433 {
5434 }
5435
5436 MonoType*
5437 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
5438 {
5439         mono_error_init (error);
5440         if (!ref)
5441                 return NULL;
5442         return ref->type;
5443 }
5444
5445 #endif /* DISABLE_REFLECTION_EMIT */
5446
5447 #ifndef DISABLE_REFLECTION_EMIT
5448 MonoMethod*
5449 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5450 {
5451         MonoType *tb;
5452         MonoClass *klass;
5453
5454         tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
5455         return_val_if_nok (error, NULL);
5456         klass = mono_class_from_mono_type (tb);
5457
5458         return methodbuilder_to_mono_method (klass, mb, error);
5459 }
5460 #else /* DISABLE_REFLECTION_EMIT */
5461 MonoMethod*
5462 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5463 {
5464         g_assert_not_reached ();
5465         return NULL;
5466 }
5467 #endif /* DISABLE_REFLECTION_EMIT */
5468
5469 gint32
5470 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
5471 {
5472         MONO_CHECK_ARG_NULL (obj, 0);
5473
5474         MonoError error;
5475         gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
5476         mono_error_set_pending_exception (&error);
5477         return result;
5478 }
5479
5480 gint32
5481 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
5482                                         MonoReflectionMethod *method,
5483                                         MonoArray *opt_param_types)
5484 {
5485         MONO_CHECK_ARG_NULL (method, 0);
5486
5487         MonoError error;
5488         gint32 result = mono_image_create_method_token (
5489                 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
5490         mono_error_set_pending_exception (&error);
5491         return result;
5492 }
5493
5494 void
5495 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
5496 {
5497         MonoError error;
5498         mono_image_create_pefile (mb, file, &error);
5499         mono_error_set_pending_exception (&error);
5500 }
5501
5502 void
5503 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
5504 {
5505         MonoError error;
5506         mono_image_build_metadata (mb, &error);
5507         mono_error_set_pending_exception (&error);
5508 }
5509
5510 void
5511 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
5512 {
5513         mono_image_register_token (mb->dynamic_image, token, obj);
5514 }
5515
5516 MonoObject*
5517 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
5518 {
5519         MonoObject *obj;
5520
5521         mono_loader_lock ();
5522         obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
5523         mono_loader_unlock ();
5524
5525         return obj;
5526 }
5527
5528 MonoReflectionModule*
5529 ves_icall_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
5530 {
5531         MonoError error;
5532         MonoReflectionModule *result = mono_image_load_module_dynamic (ab, fileName, &error);
5533         mono_error_set_pending_exception (&error);
5534         return result;
5535 }
5536
5537 /**
5538  * ves_icall_TypeBuilder_create_generic_class:
5539  * @tb: a TypeBuilder object
5540  *
5541  * (icall)
5542  * Creates the generic class after all generic parameters have been added.
5543  */
5544 void
5545 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
5546 {
5547         MonoError error;
5548         (void) mono_reflection_create_generic_class (tb, &error);
5549         mono_error_set_pending_exception (&error);
5550 }
5551
5552 #ifndef DISABLE_REFLECTION_EMIT
5553 MonoArray*
5554 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5555 {
5556         MonoError error;
5557         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
5558         mono_error_set_pending_exception (&error);
5559         return result;
5560 }
5561 #endif
5562
5563 void
5564 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5565 {
5566         mono_reflection_dynimage_basic_init (assemblyb);
5567 }
5568
5569 MonoBoolean
5570 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
5571 {
5572         return mono_type_is_generic_parameter (tb->type.type);
5573 }
5574
5575 void
5576 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
5577                                                                            MonoReflectionType *t)
5578 {
5579         enumtype->type = t->type;
5580 }
5581
5582 MonoReflectionType*
5583 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5584 {
5585         MonoError error;
5586         MonoReflectionType *ret;
5587         MonoClass *klass;
5588         int isbyref = 0, rank;
5589         char *p;
5590         char *str = mono_string_to_utf8_checked (smodifiers, &error);
5591         if (mono_error_set_pending_exception (&error))
5592                 return NULL;
5593
5594         klass = mono_class_from_mono_type (tb->type.type);
5595         p = str;
5596         /* logic taken from mono_reflection_parse_type(): keep in sync */
5597         while (*p) {
5598                 switch (*p) {
5599                 case '&':
5600                         if (isbyref) { /* only one level allowed by the spec */
5601                                 g_free (str);
5602                                 return NULL;
5603                         }
5604                         isbyref = 1;
5605                         p++;
5606
5607                         g_free (str);
5608
5609                         ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
5610                         mono_error_set_pending_exception (&error);
5611
5612                         return ret;
5613                 case '*':
5614                         klass = mono_ptr_class_get (&klass->byval_arg);
5615                         mono_class_init (klass);
5616                         p++;
5617                         break;
5618                 case '[':
5619                         rank = 1;
5620                         p++;
5621                         while (*p) {
5622                                 if (*p == ']')
5623                                         break;
5624                                 if (*p == ',')
5625                                         rank++;
5626                                 else if (*p != '*') { /* '*' means unknown lower bound */
5627                                         g_free (str);
5628                                         return NULL;
5629                                 }
5630                                 ++p;
5631                         }
5632                         if (*p != ']') {
5633                                 g_free (str);
5634                                 return NULL;
5635                         }
5636                         p++;
5637                         klass = mono_array_class_get (klass, rank);
5638                         mono_class_init (klass);
5639                         break;
5640                 default:
5641                         break;
5642                 }
5643         }
5644
5645         g_free (str);
5646
5647         ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
5648         mono_error_set_pending_exception (&error);
5649
5650         return ret;
5651 }
5652
5653 void
5654 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
5655 {
5656         mono_image_module_basic_init (moduleb);
5657 }
5658
5659 guint32
5660 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
5661 {
5662         return mono_image_insert_string (module, str);
5663 }
5664
5665 void
5666 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
5667 {
5668         MonoDynamicImage *image = moduleb->dynamic_image;
5669
5670         g_assert (type->type);
5671         image->wrappers_type = mono_class_from_mono_type (type->type);
5672 }