[runtime] ves_icall_AssemblyBuilder_InternalAddModule is dead code (#3461)
[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 static gpointer
1972 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1973 {
1974         CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
1975 }
1976
1977 static gpointer
1978 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
1979 {
1980         CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
1981 }
1982
1983 static gboolean
1984 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
1985 {
1986         MonoDynamicImage *image = moduleb->dynamic_image;
1987         MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
1988         mono_error_init (error);
1989         if (!image) {
1990                 int module_count;
1991                 MonoImage **new_modules;
1992                 MonoImage *ass;
1993                 char *name, *fqname;
1994                 /*
1995                  * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1996                  * we don't know which module it belongs to, since that is only 
1997                  * determined at assembly save time.
1998                  */
1999                 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
2000                 name = mono_string_to_utf8_checked (ab->name, error);
2001                 return_val_if_nok (error, FALSE);
2002                 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
2003                 if (!is_ok (error)) {
2004                         g_free (name);
2005                         return FALSE;
2006                 }
2007                 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
2008
2009                 moduleb->module.image = &image->image;
2010                 moduleb->dynamic_image = image;
2011                 register_module (mono_object_domain (moduleb), moduleb, image);
2012
2013                 /* register the module with the assembly */
2014                 ass = ab->dynamic_assembly->assembly.image;
2015                 module_count = ass->module_count;
2016                 new_modules = g_new0 (MonoImage *, module_count + 1);
2017
2018                 if (ass->modules)
2019                         memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
2020                 new_modules [module_count] = &image->image;
2021                 mono_image_addref (&image->image);
2022
2023                 g_free (ass->modules);
2024                 ass->modules = new_modules;
2025                 ass->module_count ++;
2026         }
2027         return TRUE;
2028 }
2029
2030 static void
2031 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
2032 {
2033         MonoError error;
2034         (void) image_module_basic_init (moduleb, &error);
2035         mono_error_set_pending_exception (&error);
2036 }
2037
2038 #endif
2039
2040 static gboolean
2041 is_corlib_type (MonoClass *klass)
2042 {
2043         return klass->image == mono_defaults.corlib;
2044 }
2045
2046 #define check_corlib_type_cached(_class, _namespace, _name) do { \
2047         static MonoClass *cached_class; \
2048         if (cached_class) \
2049                 return cached_class == _class; \
2050         if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
2051                 cached_class = _class; \
2052                 return TRUE; \
2053         } \
2054         return FALSE; \
2055 } while (0) \
2056
2057
2058
2059 #ifndef DISABLE_REFLECTION_EMIT
2060 static gboolean
2061 is_sre_array (MonoClass *klass)
2062 {
2063         check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
2064 }
2065
2066 static gboolean
2067 is_sre_byref (MonoClass *klass)
2068 {
2069         check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
2070 }
2071
2072 static gboolean
2073 is_sre_pointer (MonoClass *klass)
2074 {
2075         check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
2076 }
2077
2078 static gboolean
2079 is_sre_generic_instance (MonoClass *klass)
2080 {
2081         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
2082 }
2083
2084 static gboolean
2085 is_sre_type_builder (MonoClass *klass)
2086 {
2087         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
2088 }
2089
2090 static gboolean
2091 is_sre_method_builder (MonoClass *klass)
2092 {
2093         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
2094 }
2095
2096 gboolean
2097 mono_is_sre_ctor_builder (MonoClass *klass)
2098 {
2099         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
2100 }
2101
2102 static gboolean
2103 is_sre_field_builder (MonoClass *klass)
2104 {
2105         check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
2106 }
2107
2108 gboolean
2109 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2110 {
2111         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
2112 }
2113
2114 gboolean
2115 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2116 {
2117         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
2118 }
2119
2120 static MonoReflectionType*
2121 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
2122 {
2123         static MonoMethod *method_get_underlying_system_type = NULL;
2124         MonoReflectionType *rt;
2125         MonoMethod *usertype_method;
2126
2127         mono_error_init (error);
2128
2129         if (!method_get_underlying_system_type)
2130                 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
2131
2132         usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
2133
2134         rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
2135
2136         return rt;
2137 }
2138
2139 MonoReflectionType*
2140 mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error)
2141 {
2142         mono_error_init (error);
2143         if (!type || type->type)
2144                 return type;
2145
2146         if (mono_reflection_is_usertype (type)) {
2147                 type = mono_reflection_type_get_underlying_system_type (type, error);
2148                 return_val_if_nok (error, NULL);
2149                 if (mono_reflection_is_usertype (type)) {
2150                         mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
2151                         return NULL;
2152                 }
2153         }
2154
2155         return type;
2156 }
2157
2158
2159 MonoType*
2160 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
2161 {
2162         MonoClass *klass;
2163         mono_error_init (error);
2164
2165         if (!ref)
2166                 return NULL;
2167         if (ref->type)
2168                 return ref->type;
2169
2170         if (mono_reflection_is_usertype (ref)) {
2171                 ref = mono_reflection_type_get_underlying_system_type (ref, error);
2172                 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
2173                         return NULL;
2174                 if (ref->type)
2175                         return ref->type;
2176         }
2177
2178         klass = mono_object_class (ref);
2179
2180         if (is_sre_array (klass)) {
2181                 MonoType *res;
2182                 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
2183                 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
2184                 return_val_if_nok (error, NULL);
2185                 g_assert (base);
2186                 if (sre_array->rank == 0) //single dimentional array
2187                         res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
2188                 else
2189                         res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
2190                 sre_array->type.type = res;
2191                 return res;
2192         } else if (is_sre_byref (klass)) {
2193                 MonoType *res;
2194                 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
2195                 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
2196                 return_val_if_nok (error, NULL);
2197                 g_assert (base);
2198                 res = &mono_class_from_mono_type (base)->this_arg;
2199                 sre_byref->type.type = res;
2200                 return res;
2201         } else if (is_sre_pointer (klass)) {
2202                 MonoType *res;
2203                 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
2204                 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
2205                 return_val_if_nok (error, NULL);
2206                 g_assert (base);
2207                 res = &mono_ptr_class_get (base)->byval_arg;
2208                 sre_pointer->type.type = res;
2209                 return res;
2210         } else if (is_sre_generic_instance (klass)) {
2211                 MonoType *res, **types;
2212                 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
2213                 int i, count;
2214
2215                 count = mono_array_length (gclass->type_arguments);
2216                 types = g_new0 (MonoType*, count);
2217                 for (i = 0; i < count; ++i) {
2218                         MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
2219                         types [i] = mono_reflection_type_get_handle (t, error);
2220                         if (!types[i] || !is_ok (error)) {
2221                                 g_free (types);
2222                                 return NULL;
2223                         }
2224                 }
2225
2226                 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
2227                 g_free (types);
2228                 g_assert (res);
2229                 gclass->type.type = res;
2230                 return res;
2231         }
2232
2233         g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
2234         return NULL;
2235 }
2236
2237 void
2238 ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
2239 {
2240         MonoError error;
2241         mono_reflection_type_get_handle (type, &error);
2242         mono_error_set_pending_exception (&error);
2243 }
2244
2245 static gboolean
2246 reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
2247 {
2248         MonoDomain *domain = mono_object_domain ((MonoObject*)type);
2249         MonoClass *klass;
2250
2251         mono_error_init (error);
2252
2253         MonoType *res = mono_reflection_type_get_handle (type, error);
2254
2255         if (!res && is_ok (error)) {
2256                 mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
2257         }
2258         return_val_if_nok (error, FALSE);
2259
2260         klass = mono_class_from_mono_type (res);
2261
2262         mono_loader_lock (); /*same locking as mono_type_get_object_checked */
2263         mono_domain_lock (domain);
2264
2265         if (!image_is_dynamic (klass->image)) {
2266                 mono_class_setup_supertypes (klass);
2267         } else {
2268                 if (!domain->type_hash)
2269                         domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
2270                                         (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
2271                 mono_g_hash_table_insert (domain->type_hash, res, type);
2272         }
2273         mono_domain_unlock (domain);
2274         mono_loader_unlock ();
2275
2276         return TRUE;
2277 }
2278
2279 void
2280 mono_reflection_register_with_runtime (MonoReflectionType *type)
2281 {
2282         MonoError error;
2283         (void) reflection_register_with_runtime (type, &error);
2284         mono_error_set_pending_exception (&error);
2285 }
2286
2287 /**
2288  * LOCKING: Assumes the loader lock is held.
2289  */
2290 static MonoMethodSignature*
2291 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
2292         MonoMethodSignature *sig;
2293         int count, i;
2294
2295         mono_error_init (error);
2296
2297         count = parameters? mono_array_length (parameters): 0;
2298
2299         sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
2300         sig->param_count = count;
2301         sig->sentinelpos = -1; /* FIXME */
2302         for (i = 0; i < count; ++i) {
2303                 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
2304                 if (!is_ok (error)) {
2305                         image_g_free (image, sig);
2306                         return NULL;
2307                 }
2308         }
2309         return sig;
2310 }
2311
2312 /**
2313  * LOCKING: Assumes the loader lock is held.
2314  */
2315 static MonoMethodSignature*
2316 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
2317         MonoMethodSignature *sig;
2318
2319         mono_error_init (error);
2320
2321         sig = parameters_to_signature (image, ctor->parameters, error);
2322         return_val_if_nok (error, NULL);
2323         sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2324         sig->ret = &mono_defaults.void_class->byval_arg;
2325         return sig;
2326 }
2327
2328 /**
2329  * LOCKING: Assumes the loader lock is held.
2330  */
2331 static MonoMethodSignature*
2332 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
2333         MonoMethodSignature *sig;
2334
2335         mono_error_init (error);
2336
2337         sig = parameters_to_signature (image, method->parameters, error);
2338         return_val_if_nok (error, NULL);
2339         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2340         if (method->rtype) {
2341                 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
2342                 if (!is_ok (error)) {
2343                         image_g_free (image, sig);
2344                         return NULL;
2345                 }
2346         } else {
2347                 sig->ret = &mono_defaults.void_class->byval_arg;
2348         }
2349         sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
2350         return sig;
2351 }
2352
2353 static MonoMethodSignature*
2354 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
2355         MonoMethodSignature *sig;
2356
2357         mono_error_init (error);
2358
2359         sig = parameters_to_signature (NULL, method->parameters, error);
2360         return_val_if_nok (error, NULL);
2361         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
2362         if (method->rtype) {
2363                 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
2364                 if (!is_ok (error)) {
2365                         g_free (sig);
2366                         return NULL;
2367                 }
2368         } else {
2369                 sig->ret = &mono_defaults.void_class->byval_arg;
2370         }
2371         sig->generic_param_count = 0;
2372         return sig;
2373 }
2374
2375 static void
2376 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
2377 {
2378         mono_error_init (error);
2379         MonoClass *klass = mono_object_class (prop);
2380         if (strcmp (klass->name, "PropertyBuilder") == 0) {
2381                 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
2382                 *name = mono_string_to_utf8_checked (pb->name, error);
2383                 return_if_nok (error);
2384                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
2385         } else {
2386                 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
2387                 *name = g_strdup (p->property->name);
2388                 if (p->property->get)
2389                         *type = mono_method_signature (p->property->get)->ret;
2390                 else
2391                         *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
2392         }
2393 }
2394
2395 static void
2396 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
2397 {
2398         mono_error_init (error);
2399         MonoClass *klass = mono_object_class (field);
2400         if (strcmp (klass->name, "FieldBuilder") == 0) {
2401                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
2402                 *name = mono_string_to_utf8_checked (fb->name, error);
2403                 return_if_nok (error);
2404                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
2405         } else {
2406                 MonoReflectionField *f = (MonoReflectionField *)field;
2407                 *name = g_strdup (mono_field_get_name (f->field));
2408                 *type = f->field->type;
2409         }
2410 }
2411
2412 #else /* DISABLE_REFLECTION_EMIT */
2413
2414 void
2415 mono_reflection_register_with_runtime (MonoReflectionType *type)
2416 {
2417         /* This is empty */
2418 }
2419
2420 static gboolean
2421 is_sre_type_builder (MonoClass *klass)
2422 {
2423         return FALSE;
2424 }
2425
2426 static gboolean
2427 is_sre_generic_instance (MonoClass *klass)
2428 {
2429         return FALSE;
2430 }
2431
2432 gboolean
2433 mono_is_sre_ctor_builder (MonoClass *klass)
2434 {
2435         return FALSE;
2436 }
2437
2438 gboolean
2439 mono_is_sre_method_on_tb_inst (MonoClass *klass)
2440 {
2441         return FALSE;
2442 }
2443
2444 gboolean
2445 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
2446 {
2447         return FALSE;
2448 }
2449
2450 void
2451 mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
2452 {
2453         mono_error_init (error);
2454 }
2455
2456 #endif /* !DISABLE_REFLECTION_EMIT */
2457
2458
2459 static gboolean
2460 is_sr_mono_field (MonoClass *klass)
2461 {
2462         check_corlib_type_cached (klass, "System.Reflection", "MonoField");
2463 }
2464
2465 gboolean
2466 mono_is_sr_mono_property (MonoClass *klass)
2467 {
2468         check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
2469 }
2470
2471 static gboolean
2472 is_sr_mono_method (MonoClass *klass)
2473 {
2474         check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
2475 }
2476
2477 gboolean
2478 mono_is_sr_mono_cmethod (MonoClass *klass)
2479 {
2480         check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
2481 }
2482
2483 static gboolean
2484 is_sr_mono_generic_method (MonoClass *klass)
2485 {
2486         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
2487 }
2488
2489 static gboolean
2490 is_sr_mono_generic_cmethod (MonoClass *klass)
2491 {
2492         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
2493 }
2494
2495 gboolean
2496 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
2497 {
2498         return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
2499 }
2500
2501 gboolean
2502 mono_is_sre_type_builder (MonoClass *klass)
2503 {
2504         return is_sre_type_builder (klass);
2505 }
2506
2507 gboolean
2508 mono_is_sre_generic_instance (MonoClass *klass)
2509 {
2510         return is_sre_generic_instance (klass);
2511 }
2512
2513
2514
2515 /**
2516  * encode_cattr_value:
2517  * Encode a value in a custom attribute stream of bytes.
2518  * The value to encode is either supplied as an object in argument val
2519  * (valuetypes are boxed), or as a pointer to the data in the
2520  * argument argval.
2521  * @type represents the type of the value
2522  * @buffer is the start of the buffer
2523  * @p the current position in the buffer
2524  * @buflen contains the size of the buffer and is used to return the new buffer size
2525  * if this needs to be realloced.
2526  * @retbuffer and @retp return the start and the position of the buffer
2527  * @error set on error.
2528  */
2529 static void
2530 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2531 {
2532         MonoTypeEnum simple_type;
2533         
2534         mono_error_init (error);
2535         if ((p-buffer) + 10 >= *buflen) {
2536                 char *newbuf;
2537                 *buflen *= 2;
2538                 newbuf = (char *)g_realloc (buffer, *buflen);
2539                 p = newbuf + (p-buffer);
2540                 buffer = newbuf;
2541         }
2542         if (!argval)
2543                 argval = ((char*)arg + sizeof (MonoObject));
2544         simple_type = type->type;
2545 handle_enum:
2546         switch (simple_type) {
2547         case MONO_TYPE_BOOLEAN:
2548         case MONO_TYPE_U1:
2549         case MONO_TYPE_I1:
2550                 *p++ = *argval;
2551                 break;
2552         case MONO_TYPE_CHAR:
2553         case MONO_TYPE_U2:
2554         case MONO_TYPE_I2:
2555                 swap_with_size (p, argval, 2, 1);
2556                 p += 2;
2557                 break;
2558         case MONO_TYPE_U4:
2559         case MONO_TYPE_I4:
2560         case MONO_TYPE_R4:
2561                 swap_with_size (p, argval, 4, 1);
2562                 p += 4;
2563                 break;
2564         case MONO_TYPE_R8:
2565                 swap_with_size (p, argval, 8, 1);
2566                 p += 8;
2567                 break;
2568         case MONO_TYPE_U8:
2569         case MONO_TYPE_I8:
2570                 swap_with_size (p, argval, 8, 1);
2571                 p += 8;
2572                 break;
2573         case MONO_TYPE_VALUETYPE:
2574                 if (type->data.klass->enumtype) {
2575                         simple_type = mono_class_enum_basetype (type->data.klass)->type;
2576                         goto handle_enum;
2577                 } else {
2578                         g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2579                 }
2580                 break;
2581         case MONO_TYPE_STRING: {
2582                 char *str;
2583                 guint32 slen;
2584                 if (!arg) {
2585                         *p++ = 0xFF;
2586                         break;
2587                 }
2588                 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2589                 return_if_nok (error);
2590                 slen = strlen (str);
2591                 if ((p-buffer) + 10 + slen >= *buflen) {
2592                         char *newbuf;
2593                         *buflen *= 2;
2594                         *buflen += slen;
2595                         newbuf = (char *)g_realloc (buffer, *buflen);
2596                         p = newbuf + (p-buffer);
2597                         buffer = newbuf;
2598                 }
2599                 mono_metadata_encode_value (slen, p, &p);
2600                 memcpy (p, str, slen);
2601                 p += slen;
2602                 g_free (str);
2603                 break;
2604         }
2605         case MONO_TYPE_CLASS: {
2606                 char *str;
2607                 guint32 slen;
2608                 MonoType *arg_type;
2609                 if (!arg) {
2610                         *p++ = 0xFF;
2611                         break;
2612                 }
2613 handle_type:
2614                 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2615                 return_if_nok (error);
2616
2617                 str = type_get_qualified_name (arg_type, NULL);
2618                 slen = strlen (str);
2619                 if ((p-buffer) + 10 + slen >= *buflen) {
2620                         char *newbuf;
2621                         *buflen *= 2;
2622                         *buflen += slen;
2623                         newbuf = (char *)g_realloc (buffer, *buflen);
2624                         p = newbuf + (p-buffer);
2625                         buffer = newbuf;
2626                 }
2627                 mono_metadata_encode_value (slen, p, &p);
2628                 memcpy (p, str, slen);
2629                 p += slen;
2630                 g_free (str);
2631                 break;
2632         }
2633         case MONO_TYPE_SZARRAY: {
2634                 int len, i;
2635                 MonoClass *eclass, *arg_eclass;
2636
2637                 if (!arg) {
2638                         *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2639                         break;
2640                 }
2641                 len = mono_array_length ((MonoArray*)arg);
2642                 *p++ = len & 0xff;
2643                 *p++ = (len >> 8) & 0xff;
2644                 *p++ = (len >> 16) & 0xff;
2645                 *p++ = (len >> 24) & 0xff;
2646                 *retp = p;
2647                 *retbuffer = buffer;
2648                 eclass = type->data.klass;
2649                 arg_eclass = mono_object_class (arg)->element_class;
2650
2651                 if (!eclass) {
2652                         /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2653                         eclass = mono_defaults.object_class;
2654                 }
2655                 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2656                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2657                         int elsize = mono_class_array_element_size (arg_eclass);
2658                         for (i = 0; i < len; ++i) {
2659                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2660                                 return_if_nok (error);
2661                                 elptr += elsize;
2662                         }
2663                 } else if (eclass->valuetype && arg_eclass->valuetype) {
2664                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2665                         int elsize = mono_class_array_element_size (eclass);
2666                         for (i = 0; i < len; ++i) {
2667                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2668                                 return_if_nok (error);
2669                                 elptr += elsize;
2670                         }
2671                 } else {
2672                         for (i = 0; i < len; ++i) {
2673                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2674                                 return_if_nok (error);
2675                         }
2676                 }
2677                 break;
2678         }
2679         case MONO_TYPE_OBJECT: {
2680                 MonoClass *klass;
2681                 char *str;
2682                 guint32 slen;
2683
2684                 /*
2685                  * The parameter type is 'object' but the type of the actual
2686                  * argument is not. So we have to add type information to the blob
2687                  * too. This is completely undocumented in the spec.
2688                  */
2689
2690                 if (arg == NULL) {
2691                         *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
2692                         *p++ = 0xFF;
2693                         break;
2694                 }
2695                 
2696                 klass = mono_object_class (arg);
2697
2698                 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2699                         *p++ = 0x50;
2700                         goto handle_type;
2701                 } else {
2702                         return_if_nok (error);
2703                 }
2704
2705                 if (klass->enumtype) {
2706                         *p++ = 0x55;
2707                 } else if (klass == mono_defaults.string_class) {
2708                         simple_type = MONO_TYPE_STRING;
2709                         *p++ = 0x0E;
2710                         goto handle_enum;
2711                 } else if (klass->rank == 1) {
2712                         *p++ = 0x1D;
2713                         if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2714                                 /* See Partition II, Appendix B3 */
2715                                 *p++ = 0x51;
2716                         else
2717                                 *p++ = klass->element_class->byval_arg.type;
2718                         encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2719                         return_if_nok (error);
2720                         break;
2721                 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2722                         *p++ = simple_type = klass->byval_arg.type;
2723                         goto handle_enum;
2724                 } else {
2725                         g_error ("unhandled type in custom attr");
2726                 }
2727                 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2728                 slen = strlen (str);
2729                 if ((p-buffer) + 10 + slen >= *buflen) {
2730                         char *newbuf;
2731                         *buflen *= 2;
2732                         *buflen += slen;
2733                         newbuf = (char *)g_realloc (buffer, *buflen);
2734                         p = newbuf + (p-buffer);
2735                         buffer = newbuf;
2736                 }
2737                 mono_metadata_encode_value (slen, p, &p);
2738                 memcpy (p, str, slen);
2739                 p += slen;
2740                 g_free (str);
2741                 simple_type = mono_class_enum_basetype (klass)->type;
2742                 goto handle_enum;
2743         }
2744         default:
2745                 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2746         }
2747         *retp = p;
2748         *retbuffer = buffer;
2749 }
2750
2751 static void
2752 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2753 {
2754         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2755                 char *str = type_get_qualified_name (type, NULL);
2756                 int slen = strlen (str);
2757
2758                 *p++ = 0x55;
2759                 /*
2760                  * This seems to be optional...
2761                  * *p++ = 0x80;
2762                  */
2763                 mono_metadata_encode_value (slen, p, &p);
2764                 memcpy (p, str, slen);
2765                 p += slen;
2766                 g_free (str);
2767         } else if (type->type == MONO_TYPE_OBJECT) {
2768                 *p++ = 0x51;
2769         } else if (type->type == MONO_TYPE_CLASS) {
2770                 /* it should be a type: encode_cattr_value () has the check */
2771                 *p++ = 0x50;
2772         } else {
2773                 mono_metadata_encode_value (type->type, p, &p);
2774                 if (type->type == MONO_TYPE_SZARRAY)
2775                         /* See the examples in Partition VI, Annex B */
2776                         encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2777         }
2778
2779         *retp = p;
2780 }
2781
2782 #ifndef DISABLE_REFLECTION_EMIT
2783 static void
2784 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2785 {
2786         int len;
2787
2788         mono_error_init (error);
2789
2790         /* Preallocate a large enough buffer */
2791         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2792                 char *str = type_get_qualified_name (type, NULL);
2793                 len = strlen (str);
2794                 g_free (str);
2795         } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2796                 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2797                 len = strlen (str);
2798                 g_free (str);
2799         } else {
2800                 len = 0;
2801         }
2802         len += strlen (name);
2803
2804         if ((p-buffer) + 20 + len >= *buflen) {
2805                 char *newbuf;
2806                 *buflen *= 2;
2807                 *buflen += len;
2808                 newbuf = (char *)g_realloc (buffer, *buflen);
2809                 p = newbuf + (p-buffer);
2810                 buffer = newbuf;
2811         }
2812
2813         encode_field_or_prop_type (type, p, &p);
2814
2815         len = strlen (name);
2816         mono_metadata_encode_value (len, p, &p);
2817         memcpy (p, name, len);
2818         p += len;
2819         encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2820         return_if_nok (error);
2821         *retp = p;
2822         *retbuffer = buffer;
2823 }
2824
2825 /**
2826  * mono_reflection_get_custom_attrs_blob:
2827  * @ctor: custom attribute constructor
2828  * @ctorArgs: arguments o the constructor
2829  * @properties:
2830  * @propValues:
2831  * @fields:
2832  * @fieldValues:
2833  * 
2834  * Creates the blob of data that needs to be saved in the metadata and that represents
2835  * the custom attributed described by @ctor, @ctorArgs etc.
2836  * Returns: a Byte array representing the blob of data.
2837  */
2838 MonoArray*
2839 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
2840 {
2841         MonoError error;
2842         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2843         mono_error_cleanup (&error);
2844         return result;
2845 }
2846
2847 /**
2848  * mono_reflection_get_custom_attrs_blob_checked:
2849  * @ctor: custom attribute constructor
2850  * @ctorArgs: arguments o the constructor
2851  * @properties:
2852  * @propValues:
2853  * @fields:
2854  * @fieldValues:
2855  * @error: set on error
2856  * 
2857  * Creates the blob of data that needs to be saved in the metadata and that represents
2858  * the custom attributed described by @ctor, @ctorArgs etc.
2859  * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
2860  */
2861 MonoArray*
2862 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
2863 {
2864         MonoArray *result = NULL;
2865         MonoMethodSignature *sig;
2866         MonoObject *arg;
2867         char *buffer, *p;
2868         guint32 buflen, i;
2869
2870         mono_error_init (error);
2871
2872         if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2873                 /* sig is freed later so allocate it in the heap */
2874                 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2875                 if (!is_ok (error)) {
2876                         g_free (sig);
2877                         return NULL;
2878                 }
2879         } else {
2880                 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2881         }
2882
2883         g_assert (mono_array_length (ctorArgs) == sig->param_count);
2884         buflen = 256;
2885         p = buffer = (char *)g_malloc (buflen);
2886         /* write the prolog */
2887         *p++ = 1;
2888         *p++ = 0;
2889         for (i = 0; i < sig->param_count; ++i) {
2890                 arg = mono_array_get (ctorArgs, MonoObject*, i);
2891                 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2892                 if (!is_ok (error)) goto leave;
2893         }
2894         i = 0;
2895         if (properties)
2896                 i += mono_array_length (properties);
2897         if (fields)
2898                 i += mono_array_length (fields);
2899         *p++ = i & 0xff;
2900         *p++ = (i >> 8) & 0xff;
2901         if (properties) {
2902                 MonoObject *prop;
2903                 for (i = 0; i < mono_array_length (properties); ++i) {
2904                         MonoType *ptype;
2905                         char *pname;
2906
2907                         prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2908                         get_prop_name_and_type (prop, &pname, &ptype, error);
2909                         if (!is_ok (error)) goto leave;
2910                         *p++ = 0x54; /* PROPERTY signature */
2911                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2912                         g_free (pname);
2913                         if (!is_ok (error)) goto leave;
2914                 }
2915         }
2916
2917         if (fields) {
2918                 MonoObject *field;
2919                 for (i = 0; i < mono_array_length (fields); ++i) {
2920                         MonoType *ftype;
2921                         char *fname;
2922
2923                         field = (MonoObject *)mono_array_get (fields, gpointer, i);
2924                         get_field_name_and_type (field, &fname, &ftype, error);
2925                         if (!is_ok (error)) goto leave;
2926                         *p++ = 0x53; /* FIELD signature */
2927                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2928                         g_free (fname);
2929                         if (!is_ok (error)) goto leave;
2930                 }
2931         }
2932
2933         g_assert (p - buffer <= buflen);
2934         buflen = p - buffer;
2935         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2936         if (!is_ok (error))
2937                 goto leave;
2938         p = mono_array_addr (result, char, 0);
2939         memcpy (p, buffer, buflen);
2940 leave:
2941         g_free (buffer);
2942         if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2943                 g_free (sig);
2944         return result;
2945 }
2946
2947 /**
2948  * reflection_setup_internal_class:
2949  * @tb: a TypeBuilder object
2950  * @error: set on error
2951  *
2952  * Creates a MonoClass that represents the TypeBuilder.
2953  * This is a trick that lets us simplify a lot of reflection code
2954  * (and will allow us to support Build and Run assemblies easier).
2955  *
2956  * Returns TRUE on success. On failure, returns FALSE and sets @error.
2957  */
2958 static gboolean
2959 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2960 {
2961         MonoClass *klass, *parent;
2962
2963         mono_error_init (error);
2964         RESOLVE_TYPE (tb->parent, error);
2965         return_val_if_nok (error, FALSE);
2966
2967         mono_loader_lock ();
2968
2969         if (tb->parent) {
2970                 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
2971                 if (!is_ok (error)) {
2972                         mono_loader_unlock ();
2973                         return FALSE;
2974                 }
2975                 /* check so we can compile corlib correctly */
2976                 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
2977                         /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2978                         parent = parent_type->data.klass;
2979                 } else {
2980                         parent = mono_class_from_mono_type (parent_type);
2981                 }
2982         } else {
2983                 parent = NULL;
2984         }
2985         
2986         /* the type has already being created: it means we just have to change the parent */
2987         if (tb->type.type) {
2988                 klass = mono_class_from_mono_type (tb->type.type);
2989                 klass->parent = NULL;
2990                 /* fool mono_class_setup_parent */
2991                 klass->supertypes = NULL;
2992                 mono_class_setup_parent (klass, parent);
2993                 mono_class_setup_mono_type (klass);
2994                 mono_loader_unlock ();
2995                 return TRUE;
2996         }
2997
2998         klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
2999
3000         klass->image = &tb->module->dynamic_image->image;
3001
3002         klass->inited = 1; /* we lie to the runtime */
3003         klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
3004         if (!is_ok (error))
3005                 goto failure;
3006         klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
3007         if (!is_ok (error))
3008                 goto failure;
3009         klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
3010         klass->flags = tb->attrs;
3011         
3012         mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
3013
3014         klass->element_class = klass;
3015
3016         if (mono_class_get_ref_info (klass) == NULL) {
3017
3018                 mono_class_set_ref_info (klass, tb);
3019
3020                 /* Put into cache so mono_class_get_checked () will find it.
3021                 Skip nested types as those should not be available on the global scope. */
3022                 if (!tb->nesting_type)
3023                         mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
3024
3025                 /*
3026                 We must register all types as we cannot rely on the name_cache hashtable since we find the class
3027                 by performing a mono_class_get which does the full resolution.
3028
3029                 Working around this semantics would require us to write a lot of code for no clear advantage.
3030                 */
3031                 mono_image_append_class_to_reflection_info_set (klass);
3032         } else {
3033                 g_assert (mono_class_get_ref_info (klass) == tb);
3034         }
3035
3036         mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
3037
3038         if (parent != NULL) {
3039                 mono_class_setup_parent (klass, parent);
3040         } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
3041                 const char *old_n = klass->name;
3042                 /* trick to get relative numbering right when compiling corlib */
3043                 klass->name = "BuildingObject";
3044                 mono_class_setup_parent (klass, mono_defaults.object_class);
3045                 klass->name = old_n;
3046         }
3047
3048         if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
3049                         (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
3050                         (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
3051                 klass->instance_size = sizeof (MonoObject);
3052                 klass->size_inited = 1;
3053                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
3054         }
3055
3056         mono_class_setup_mono_type (klass);
3057
3058         mono_class_setup_supertypes (klass);
3059
3060         /*
3061          * FIXME: handle interfaces.
3062          */
3063
3064         tb->type.type = &klass->byval_arg;
3065
3066         if (tb->nesting_type) {
3067                 g_assert (tb->nesting_type->type);
3068                 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
3069                 if (!is_ok (error)) goto failure;
3070                 klass->nested_in = mono_class_from_mono_type (nesting_type);
3071         }
3072
3073         /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
3074
3075         mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
3076         
3077         mono_loader_unlock ();
3078         return TRUE;
3079
3080 failure:
3081         mono_loader_unlock ();
3082         return FALSE;
3083 }
3084
3085 /**
3086  * ves_icall_TypeBuilder_setup_internal_class:
3087  * @tb: a TypeBuilder object
3088  *
3089  * (icall)
3090  * Creates a MonoClass that represents the TypeBuilder.
3091  * This is a trick that lets us simplify a lot of reflection code
3092  * (and will allow us to support Build and Run assemblies easier).
3093  *
3094  */
3095 void
3096 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
3097 {
3098         MonoError error;
3099         (void) reflection_setup_internal_class (tb, &error);
3100         mono_error_set_pending_exception (&error);
3101 }
3102
3103 /*
3104  * ves_icall_TypeBuilder_setup_generic_class:
3105  * @tb: a TypeBuilder object
3106  *
3107  * Setup the generic class before adding the first generic parameter.
3108  */
3109 void
3110 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
3111 {
3112 }
3113
3114 /**
3115  * mono_reflection_create_generic_class:
3116  * @tb: a TypeBuilder object
3117  * @error: set on error
3118  *
3119  * Creates the generic class after all generic parameters have been added.
3120  * On success returns TRUE, on failure returns FALSE and sets @error.
3121  * 
3122  */
3123 gboolean
3124 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
3125 {
3126
3127         MonoClass *klass;
3128         int count, i;
3129
3130         mono_error_init (error);
3131
3132         klass = mono_class_from_mono_type (tb->type.type);
3133
3134         count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
3135
3136         if (klass->generic_container || (count == 0))
3137                 return TRUE;
3138
3139         g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
3140
3141         klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
3142
3143         klass->generic_container->owner.klass = klass;
3144         klass->generic_container->type_argc = count;
3145         klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
3146
3147         klass->is_generic = 1;
3148
3149         for (i = 0; i < count; i++) {
3150                 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3151                 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
3152                 return_val_if_nok (error, FALSE);
3153                 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
3154                 klass->generic_container->type_params [i] = *param;
3155                 /*Make sure we are a diferent type instance */
3156                 klass->generic_container->type_params [i].param.owner = klass->generic_container;
3157                 klass->generic_container->type_params [i].info.pklass = NULL;
3158                 klass->generic_container->type_params [i].info.flags = gparam->attrs;
3159
3160                 g_assert (klass->generic_container->type_params [i].param.owner);
3161         }
3162
3163         klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
3164         return TRUE;
3165 }
3166
3167 static MonoMarshalSpec*
3168 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
3169                                 MonoReflectionMarshal *minfo, MonoError *error)
3170 {
3171         MonoMarshalSpec *res;
3172
3173         mono_error_init (error);
3174
3175         res = image_g_new0 (image, MonoMarshalSpec, 1);
3176         res->native = (MonoMarshalNative)minfo->type;
3177
3178         switch (minfo->type) {
3179         case MONO_NATIVE_LPARRAY:
3180                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
3181                 if (minfo->has_size) {
3182                         res->data.array_data.param_num = minfo->param_num;
3183                         res->data.array_data.num_elem = minfo->count;
3184                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
3185                 }
3186                 else {
3187                         res->data.array_data.param_num = -1;
3188                         res->data.array_data.num_elem = -1;
3189                         res->data.array_data.elem_mult = -1;
3190                 }
3191                 break;
3192
3193         case MONO_NATIVE_BYVALTSTR:
3194         case MONO_NATIVE_BYVALARRAY:
3195                 res->data.array_data.num_elem = minfo->count;
3196                 break;
3197
3198         case MONO_NATIVE_CUSTOM:
3199                 if (minfo->marshaltyperef) {
3200                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
3201                         if (!is_ok (error)) {
3202                                 image_g_free (image, res);
3203                                 return NULL;
3204                         }
3205                         res->data.custom_data.custom_name =
3206                                 type_get_fully_qualified_name (marshaltyperef);
3207                 }
3208                 if (minfo->mcookie) {
3209                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
3210                         if (!is_ok (error)) {
3211                                 image_g_free (image, res);
3212                                 return NULL;
3213                         }
3214                 }
3215                 break;
3216
3217         default:
3218                 break;
3219         }
3220
3221         return res;
3222 }
3223 #endif /* !DISABLE_REFLECTION_EMIT */
3224
3225 MonoReflectionMarshalAsAttribute*
3226 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
3227                                                         MonoMarshalSpec *spec, MonoError *error)
3228 {
3229         MonoReflectionType *rt;
3230         MonoReflectionMarshalAsAttribute *minfo;
3231         MonoType *mtype;
3232
3233         mono_error_init (error);
3234         
3235         minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
3236         if (!minfo)
3237                 return NULL;
3238         minfo->utype = spec->native;
3239
3240         switch (minfo->utype) {
3241         case MONO_NATIVE_LPARRAY:
3242                 minfo->array_subtype = spec->data.array_data.elem_type;
3243                 minfo->size_const = spec->data.array_data.num_elem;
3244                 if (spec->data.array_data.param_num != -1)
3245                         minfo->size_param_index = spec->data.array_data.param_num;
3246                 break;
3247
3248         case MONO_NATIVE_BYVALTSTR:
3249         case MONO_NATIVE_BYVALARRAY:
3250                 minfo->size_const = spec->data.array_data.num_elem;
3251                 break;
3252
3253         case MONO_NATIVE_CUSTOM:
3254                 if (spec->data.custom_data.custom_name) {
3255                         mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
3256                         return_val_if_nok  (error, NULL);
3257
3258                         if (mtype) {
3259                                 rt = mono_type_get_object_checked (domain, mtype, error);
3260                                 if (!rt)
3261                                         return NULL;
3262
3263                                 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
3264                         }
3265
3266                         MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
3267                 }
3268                 if (spec->data.custom_data.cookie)
3269                         MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
3270                 break;
3271
3272         default:
3273                 break;
3274         }
3275
3276         return minfo;
3277 }
3278
3279 #ifndef DISABLE_REFLECTION_EMIT
3280 static MonoMethod*
3281 reflection_methodbuilder_to_mono_method (MonoClass *klass,
3282                                          ReflectionMethodBuilder *rmb,
3283                                          MonoMethodSignature *sig,
3284                                          MonoError *error)
3285 {
3286         MonoMethod *m;
3287         MonoMethodWrapper *wrapperm;
3288         MonoMarshalSpec **specs;
3289         MonoReflectionMethodAux *method_aux;
3290         MonoImage *image;
3291         gboolean dynamic;
3292         int i;
3293
3294         mono_error_init (error);
3295         /*
3296          * Methods created using a MethodBuilder should have their memory allocated
3297          * inside the image mempool, while dynamic methods should have their memory
3298          * malloc'd.
3299          */
3300         dynamic = rmb->refs != NULL;
3301         image = dynamic ? NULL : klass->image;
3302
3303         if (!dynamic)
3304                 g_assert (!klass->generic_class);
3305
3306         mono_loader_lock ();
3307
3308         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
3309                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
3310                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
3311         else
3312                 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
3313
3314         wrapperm = (MonoMethodWrapper*)m;
3315
3316         m->dynamic = dynamic;
3317         m->slot = -1;
3318         m->flags = rmb->attrs;
3319         m->iflags = rmb->iattrs;
3320         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
3321         m->klass = klass;
3322         m->signature = sig;
3323         m->sre_method = TRUE;
3324         m->skip_visibility = rmb->skip_visibility;
3325         if (rmb->table_idx)
3326                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
3327
3328         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
3329                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
3330                         m->string_ctor = 1;
3331
3332                 m->signature->pinvoke = 1;
3333         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
3334                 m->signature->pinvoke = 1;
3335
3336                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3337
3338                 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
3339                 mono_error_assert_ok (error);
3340                 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
3341                 mono_error_assert_ok (error);
3342                 
3343                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
3344
3345                 if (image_is_dynamic (klass->image))
3346                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3347
3348                 mono_loader_unlock ();
3349
3350                 return m;
3351         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
3352                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
3353                 MonoMethodHeader *header;
3354                 guint32 code_size;
3355                 gint32 max_stack, i;
3356                 gint32 num_locals = 0;
3357                 gint32 num_clauses = 0;
3358                 guint8 *code;
3359
3360                 if (rmb->ilgen) {
3361                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
3362                         code_size = rmb->ilgen->code_len;
3363                         max_stack = rmb->ilgen->max_stack;
3364                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
3365                         if (rmb->ilgen->ex_handlers)
3366                                 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
3367                 } else {
3368                         if (rmb->code) {
3369                                 code = mono_array_addr (rmb->code, guint8, 0);
3370                                 code_size = mono_array_length (rmb->code);
3371                                 /* we probably need to run a verifier on the code... */
3372                                 max_stack = 8; 
3373                         }
3374                         else {
3375                                 code = NULL;
3376                                 code_size = 0;
3377                                 max_stack = 8;
3378                         }
3379                 }
3380
3381                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
3382                 header->code_size = code_size;
3383                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
3384                 memcpy ((char*)header->code, code, code_size);
3385                 header->max_stack = max_stack;
3386                 header->init_locals = rmb->init_locals;
3387                 header->num_locals = num_locals;
3388
3389                 for (i = 0; i < num_locals; ++i) {
3390                         MonoReflectionLocalBuilder *lb = 
3391                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
3392
3393                         header->locals [i] = image_g_new0 (image, MonoType, 1);
3394                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
3395                         mono_error_assert_ok (error);
3396                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
3397                 }
3398
3399                 header->num_clauses = num_clauses;
3400                 if (num_clauses) {
3401                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
3402                                                                  rmb->ilgen, num_clauses, error);
3403                         mono_error_assert_ok (error);
3404                 }
3405
3406                 wrapperm->header = header;
3407         }
3408
3409         if (rmb->generic_params) {
3410                 int count = mono_array_length (rmb->generic_params);
3411                 MonoGenericContainer *container = rmb->generic_container;
3412
3413                 g_assert (container);
3414
3415                 container->type_argc = count;
3416                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
3417                 container->owner.method = m;
3418                 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
3419
3420                 m->is_generic = TRUE;
3421                 mono_method_set_generic_container (m, container);
3422
3423                 for (i = 0; i < count; i++) {
3424                         MonoReflectionGenericParam *gp =
3425                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
3426                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
3427                         mono_error_assert_ok (error);
3428                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
3429                         container->type_params [i] = *param;
3430                 }
3431
3432                 /*
3433                  * The method signature might have pointers to generic parameters that belong to other methods.
3434                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3435                  * generic parameters.
3436                  */
3437                 for (i = 0; i < m->signature->param_count; ++i) {
3438                         MonoType *t = m->signature->params [i];
3439                         if (t->type == MONO_TYPE_MVAR) {
3440                                 MonoGenericParam *gparam =  t->data.generic_param;
3441                                 if (gparam->num < count) {
3442                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
3443                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
3444                                 }
3445
3446                         }
3447                 }
3448
3449                 if (klass->generic_container) {
3450                         container->parent = klass->generic_container;
3451                         container->context.class_inst = klass->generic_container->context.class_inst;
3452                 }
3453                 container->context.method_inst = mono_get_shared_generic_inst (container);
3454         }
3455
3456         if (rmb->refs) {
3457                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
3458                 int i;
3459                 void **data;
3460
3461                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
3462
3463                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
3464                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
3465                 for (i = 0; i < rmb->nrefs; ++i)
3466                         data [i + 1] = rmb->refs [i];
3467         }
3468
3469         method_aux = NULL;
3470
3471         /* Parameter info */
3472         if (rmb->pinfo) {
3473                 if (!method_aux)
3474                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3475                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
3476                 for (i = 0; i <= m->signature->param_count; ++i) {
3477                         MonoReflectionParamBuilder *pb;
3478                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3479                                 if ((i > 0) && (pb->attrs)) {
3480                                         /* Make a copy since it might point to a shared type structure */
3481                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
3482                                         m->signature->params [i - 1]->attrs = pb->attrs;
3483                                 }
3484
3485                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
3486                                         MonoDynamicImage *assembly;
3487                                         guint32 idx, len;
3488                                         MonoTypeEnum def_type;
3489                                         char *p;
3490                                         const char *p2;
3491
3492                                         if (!method_aux->param_defaults) {
3493                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
3494                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
3495                                         }
3496                                         assembly = (MonoDynamicImage*)klass->image;
3497                                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3498                                         /* Copy the data from the blob since it might get realloc-ed */
3499                                         p = assembly->blob.data + idx;
3500                                         len = mono_metadata_decode_blob_size (p, &p2);
3501                                         len += p2 - p;
3502                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3503                                         method_aux->param_default_types [i] = def_type;
3504                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3505                                 }
3506
3507                                 if (pb->name) {
3508                                         method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
3509                                         mono_error_assert_ok (error);
3510                                 }
3511                                 if (pb->cattrs) {
3512                                         if (!method_aux->param_cattr)
3513                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3514                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3515                                 }
3516                         }
3517                 }
3518         }
3519
3520         /* Parameter marshalling */
3521         specs = NULL;
3522         if (rmb->pinfo)         
3523                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3524                         MonoReflectionParamBuilder *pb;
3525                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3526                                 if (pb->marshal_info) {
3527                                         if (specs == NULL)
3528                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3529                                         specs [pb->position] = 
3530                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3531                                         if (!is_ok (error)) {
3532                                                 mono_loader_unlock ();
3533                                                 image_g_free (image, specs);
3534                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3535                                                 return NULL;
3536                                         }
3537                                 }
3538                         }
3539                 }
3540         if (specs != NULL) {
3541                 if (!method_aux)
3542                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3543                 method_aux->param_marshall = specs;
3544         }
3545
3546         if (image_is_dynamic (klass->image) && method_aux)
3547                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3548
3549         mono_loader_unlock ();
3550
3551         return m;
3552 }       
3553
3554 static MonoMethod*
3555 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3556 {
3557         ReflectionMethodBuilder rmb;
3558         MonoMethodSignature *sig;
3559
3560         mono_loader_lock ();
3561         g_assert (klass->image != NULL);
3562         sig = ctor_builder_to_signature (klass->image, mb, error);
3563         mono_loader_unlock ();
3564         return_val_if_nok (error, NULL);
3565
3566         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3567                 return NULL;
3568
3569         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3570         return_val_if_nok (error, NULL);
3571         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3572
3573         /* If we are in a generic class, we might be called multiple times from inflate_method */
3574         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3575                 /* ilgen is no longer needed */
3576                 mb->ilgen = NULL;
3577         }
3578
3579         return mb->mhandle;
3580 }
3581
3582 static MonoMethod*
3583 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
3584 {
3585         ReflectionMethodBuilder rmb;
3586         MonoMethodSignature *sig;
3587
3588         mono_error_init (error);
3589
3590         mono_loader_lock ();
3591         g_assert (klass->image != NULL);
3592         sig = method_builder_to_signature (klass->image, mb, error);
3593         mono_loader_unlock ();
3594         return_val_if_nok (error, NULL);
3595
3596         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3597                 return NULL;
3598
3599         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3600         return_val_if_nok (error, NULL);
3601         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3602
3603         /* If we are in a generic class, we might be called multiple times from inflate_method */
3604         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
3605                 /* ilgen is no longer needed */
3606                 mb->ilgen = NULL;
3607         }
3608         return mb->mhandle;
3609 }
3610
3611 static MonoClassField*
3612 fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
3613 {
3614         MonoClassField *field;
3615         MonoType *custom;
3616
3617         mono_error_init (error);
3618
3619         field = g_new0 (MonoClassField, 1);
3620
3621         field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
3622         mono_error_assert_ok (error);
3623         if (fb->attrs || fb->modreq || fb->modopt) {
3624                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3625                 if (!is_ok (error)) {
3626                         g_free (field);
3627                         return NULL;
3628                 }
3629                 field->type = mono_metadata_type_dup (NULL, type);
3630                 field->type->attrs = fb->attrs;
3631
3632                 g_assert (image_is_dynamic (klass->image));
3633                 custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
3634                 g_free (field->type);
3635                 if (!is_ok (error)) {
3636                         g_free (field);
3637                         return NULL;
3638                 }
3639                 field->type = mono_metadata_type_dup (klass->image, custom);
3640                 g_free (custom);
3641         } else {
3642                 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3643                 if (!is_ok (error)) {
3644                         g_free (field);
3645                         return NULL;
3646                 }
3647         }
3648         if (fb->offset != -1)
3649                 field->offset = fb->offset;
3650         field->parent = klass;
3651         mono_save_custom_attrs (klass->image, field, fb->cattrs);
3652
3653         // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
3654
3655         return field;
3656 }
3657 #endif
3658
3659 #ifndef DISABLE_REFLECTION_EMIT
3660
3661 static MonoMethod *
3662 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
3663 {
3664         MonoMethodInflated *imethod;
3665         MonoGenericContext *context;
3666         int i;
3667
3668         /*
3669          * With generic code sharing the klass might not be inflated.
3670          * This can happen because classes inflated with their own
3671          * type arguments are "normalized" to the uninflated class.
3672          */
3673         if (!klass->generic_class)
3674                 return method;
3675
3676         context = mono_class_get_context (klass);
3677
3678         if (klass->method.count && klass->methods) {
3679                 /* Find the already created inflated method */
3680                 for (i = 0; i < klass->method.count; ++i) {
3681                         g_assert (klass->methods [i]->is_inflated);
3682                         if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
3683                                 break;
3684                 }
3685                 g_assert (i < klass->method.count);
3686                 imethod = (MonoMethodInflated*)klass->methods [i];
3687         } else {
3688                 MonoError error;
3689                 imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
3690                 mono_error_assert_ok (&error);
3691         }
3692
3693         if (method->is_generic && image_is_dynamic (method->klass->image)) {
3694                 MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
3695
3696                 mono_image_lock ((MonoImage*)image);
3697                 mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
3698                 mono_image_unlock ((MonoImage*)image);
3699         }
3700         return (MonoMethod *) imethod;
3701 }
3702
3703 static MonoMethod *
3704 inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
3705 {
3706         MonoMethod *method;
3707         MonoClass *gklass;
3708
3709         mono_error_init (error);
3710
3711         MonoClass *type_class = mono_object_class (type);
3712
3713         if (is_sre_generic_instance (type_class)) {
3714                 MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
3715                 MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
3716                 return_val_if_nok (error, NULL);
3717                 gklass = mono_class_from_mono_type (generic_type);
3718         } else if (is_sre_type_builder (type_class)) {
3719                 MonoType *t = mono_reflection_type_get_handle (type, error);
3720                 return_val_if_nok (error, NULL);
3721                 gklass = mono_class_from_mono_type (t);
3722         } else if (type->type) {
3723                 gklass = mono_class_from_mono_type (type->type);
3724                 gklass = mono_class_get_generic_type_definition (gklass);
3725         } else {
3726                 g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
3727         }
3728
3729         if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
3730                 if (((MonoReflectionMethodBuilder*)obj)->mhandle)
3731                         method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
3732                 else {
3733                         method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
3734                         if (!method)
3735                                 return NULL;
3736                 }
3737         else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
3738                 method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
3739                 if (!method)
3740                         return NULL;
3741         } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
3742                 method = ((MonoReflectionMethod *) obj)->method;
3743         else {
3744                 method = NULL; /* prevent compiler warning */
3745                 g_error ("can't handle type %s", obj->vtable->klass->name);
3746         }
3747
3748         MonoType *t = mono_reflection_type_get_handle (type, error);
3749         return_val_if_nok (error, NULL);
3750         return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
3751 }
3752
3753 static void
3754 reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoError *error)
3755 {
3756         MonoGenericClass *gclass;
3757         MonoClass *klass, *gklass;
3758         MonoType *gtype;
3759
3760         mono_error_init (error);
3761
3762         gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
3763         return_if_nok (error);
3764         klass = mono_class_from_mono_type (gtype);
3765         g_assert (gtype->type == MONO_TYPE_GENERICINST);
3766         gclass = gtype->data.generic_class;
3767
3768         if (!gclass->is_dynamic)
3769                 return;
3770
3771         gklass = gclass->container_class;
3772         mono_class_init (gklass);
3773
3774         /* Mark this as needing synchronization with its generic container */
3775         gclass->need_sync = TRUE;
3776 }
3777
3778 void
3779 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
3780 {
3781         MonoError error;
3782         reflection_generic_class_initialize (type, &error);
3783         mono_error_set_pending_exception (&error);
3784 }
3785
3786 /**
3787  * fix_partial_generic_class:
3788  * @klass: a generic instantiation MonoClass
3789  * @error: set on error
3790  *
3791  * Assumes that the generic container of @klass has its vtable
3792  * initialized, and updates the parent class, interfaces, methods and
3793  * fields of @klass by inflating the types using the generic context.
3794  *
3795  * On success returns TRUE, on failure returns FALSE and sets @error.
3796  *
3797  */
3798 static gboolean
3799 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3800 {
3801         MonoClass *gklass = klass->generic_class->container_class;
3802         int i;
3803
3804         mono_error_init (error);
3805
3806         if (klass->wastypebuilder)
3807                 return TRUE;
3808
3809         if (klass->parent != gklass->parent) {
3810                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
3811                 if (mono_error_ok (error)) {
3812                         MonoClass *parent = mono_class_from_mono_type (parent_type);
3813                         mono_metadata_free_type (parent_type);
3814                         if (parent != klass->parent) {
3815                                 /*fool mono_class_setup_parent*/
3816                                 klass->supertypes = NULL;
3817                                 mono_class_setup_parent (klass, parent);
3818                         }
3819                 } else {
3820                         if (gklass->wastypebuilder)
3821                                 klass->wastypebuilder = TRUE;
3822                         return FALSE;
3823                 }
3824         }
3825
3826         if (!klass->generic_class->need_sync)
3827                 return TRUE;
3828
3829         if (klass->method.count != gklass->method.count) {
3830                 klass->method.count = gklass->method.count;
3831                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
3832
3833                 for (i = 0; i < klass->method.count; i++) {
3834                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3835                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
3836                         mono_error_assert_ok (error);
3837                 }
3838         }
3839
3840         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3841                 klass->interface_count = gklass->interface_count;
3842                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3843                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3844
3845                 for (i = 0; i < gklass->interface_count; ++i) {
3846                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3847                         return_val_if_nok (error, FALSE);
3848
3849                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3850                         mono_metadata_free_type (iface_type);
3851
3852                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
3853                                 return FALSE;
3854                 }
3855                 klass->interfaces_inited = 1;
3856         }
3857
3858         if (klass->field.count != gklass->field.count) {
3859                 klass->field.count = gklass->field.count;
3860                 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
3861
3862                 for (i = 0; i < klass->field.count; i++) {
3863                         klass->fields [i] = gklass->fields [i];
3864                         klass->fields [i].parent = klass;
3865                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3866                         return_val_if_nok (error, FALSE);
3867                 }
3868         }
3869
3870         /*We can only finish with this klass once it's parent has as well*/
3871         if (gklass->wastypebuilder)
3872                 klass->wastypebuilder = TRUE;
3873         return TRUE;
3874 }
3875
3876 /**
3877  * ensure_generic_class_runtime_vtable:
3878  * @klass a generic class
3879  * @error set on error
3880  *
3881  * Ensures that the generic container of @klass has a vtable and
3882  * returns TRUE on success.  On error returns FALSE and sets @error.
3883  */
3884 static gboolean
3885 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3886 {
3887         MonoClass *gklass = klass->generic_class->container_class;
3888
3889         mono_error_init (error);
3890
3891         if (!ensure_runtime_vtable (gklass, error))
3892                 return FALSE;
3893
3894         return fix_partial_generic_class (klass, error);
3895 }
3896
3897 /**
3898  * ensure_runtime_vtable:
3899  * @klass the class
3900  * @error set on error
3901  *
3902  * Ensures that @klass has a vtable and returns TRUE on success. On
3903  * error returns FALSE and sets @error.
3904  */
3905 static gboolean
3906 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3907 {
3908         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3909         int i, num, j;
3910
3911         mono_error_init (error);
3912
3913         if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
3914                 return TRUE;
3915         if (klass->parent)
3916                 if (!ensure_runtime_vtable (klass->parent, error))
3917                         return FALSE;
3918
3919         if (tb) {
3920                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3921                 num += tb->num_methods;
3922                 klass->method.count = num;
3923                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3924                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3925                 for (i = 0; i < num; ++i) {
3926                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3927                         if (!ctor)
3928                                 return FALSE;
3929                         klass->methods [i] = ctor;
3930                 }
3931                 num = tb->num_methods;
3932                 j = i;
3933                 for (i = 0; i < num; ++i) {
3934                         MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3935                         if (!meth)
3936                                 return FALSE;
3937                         klass->methods [j++] = meth;
3938                 }
3939         
3940                 if (tb->interfaces) {
3941                         klass->interface_count = mono_array_length (tb->interfaces);
3942                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3943                         for (i = 0; i < klass->interface_count; ++i) {
3944                                 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3945                                 return_val_if_nok (error, FALSE);
3946                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
3947                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3948                                         return FALSE;
3949                         }
3950                         klass->interfaces_inited = 1;
3951                 }
3952         } else if (klass->generic_class){
3953                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3954                         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
3955                         return FALSE;
3956                 }
3957         }
3958
3959         if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
3960                 int slot_num = 0;
3961                 for (i = 0; i < klass->method.count; ++i) {
3962                         MonoMethod *im = klass->methods [i];
3963                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3964                                 im->slot = slot_num++;
3965                 }
3966                 
3967                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3968                 mono_class_setup_interface_offsets (klass);
3969                 mono_class_setup_interface_id (klass);
3970         }
3971
3972         /*
3973          * The generic vtable is needed even if image->run is not set since some
3974          * runtime code like ves_icall_Type_GetMethodsByName depends on 
3975          * method->slot being defined.
3976          */
3977
3978         /* 
3979          * tb->methods could not be freed since it is used for determining 
3980          * overrides during dynamic vtable construction.
3981          */
3982
3983         return TRUE;
3984 }
3985
3986 static MonoMethod*
3987 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3988 {
3989         mono_error_init (error);
3990         MonoClass *klass = mono_object_class (method);
3991         if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
3992                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3993                 return sr_method->method;
3994         }
3995         if (is_sre_method_builder (klass)) {
3996                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3997                 return mb->mhandle;
3998         }
3999         if (mono_is_sre_method_on_tb_inst (klass)) {
4000                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
4001                 MonoMethod *result;
4002                 /*FIXME move this to a proper method and unify with resolve_object*/
4003                 if (m->method_args) {
4004                         result = mono_reflection_method_on_tb_inst_get_handle (m, error);
4005                 } else {
4006                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
4007                         return_val_if_nok (error, NULL);
4008                         MonoClass *inflated_klass = mono_class_from_mono_type (type);
4009                         MonoMethod *mono_method;
4010
4011                         if (is_sre_method_builder (mono_object_class (m->mb)))
4012                                 mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
4013                         else if (is_sr_mono_method (mono_object_class (m->mb)))
4014                                 mono_method = ((MonoReflectionMethod *)m->mb)->method;
4015                         else
4016                                 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)));
4017
4018                         result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
4019                 }
4020                 return result;
4021         }
4022
4023         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
4024         return NULL;
4025 }
4026
4027 void
4028 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4029 {
4030         MonoReflectionTypeBuilder *tb;
4031         int i, j, onum;
4032         MonoReflectionMethod *m;
4033
4034         mono_error_init (error);
4035         *overrides = NULL;
4036         *num_overrides = 0;
4037
4038         g_assert (image_is_dynamic (klass->image));
4039
4040         if (!mono_class_get_ref_info (klass))
4041                 return;
4042
4043         g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
4044
4045         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
4046
4047         onum = 0;
4048         if (tb->methods) {
4049                 for (i = 0; i < tb->num_methods; ++i) {
4050                         MonoReflectionMethodBuilder *mb = 
4051                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4052                         if (mb->override_methods)
4053                                 onum += mono_array_length (mb->override_methods);
4054                 }
4055         }
4056
4057         if (onum) {
4058                 *overrides = g_new0 (MonoMethod*, onum * 2);
4059
4060                 onum = 0;
4061                 for (i = 0; i < tb->num_methods; ++i) {
4062                         MonoReflectionMethodBuilder *mb = 
4063                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
4064                         if (mb->override_methods) {
4065                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
4066                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
4067
4068                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
4069                                         return_if_nok (error);
4070                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
4071
4072                                         g_assert (mb->mhandle);
4073
4074                                         onum ++;
4075                                 }
4076                         }
4077                 }
4078         }
4079
4080         *num_overrides = onum;
4081 }
4082
4083 static void
4084 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
4085 {
4086         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4087         MonoReflectionFieldBuilder *fb;
4088         MonoClassField *field;
4089         MonoImage *image = klass->image;
4090         const char *p, *p2;
4091         int i;
4092         guint32 len, idx, real_size = 0;
4093
4094         klass->field.count = tb->num_fields;
4095         klass->field.first = 0;
4096
4097         mono_error_init (error);
4098
4099         if (tb->class_size) {
4100                 if ((tb->packing_size & 0xffffff00) != 0) {
4101                         char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
4102                         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
4103                         return;
4104                 }
4105                 klass->packing_size = tb->packing_size;
4106                 real_size = klass->instance_size + tb->class_size;
4107         }
4108
4109         if (!klass->field.count) {
4110                 klass->instance_size = MAX (klass->instance_size, real_size);
4111                 return;
4112         }
4113         
4114         klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
4115         mono_class_alloc_ext (klass);
4116         klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
4117         /*
4118         This is, guess what, a hack.
4119         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
4120         On the static path no field class is resolved, only types are built. This is the right thing to do
4121         but we suck.
4122         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
4123         */
4124         klass->size_inited = 1;
4125
4126         for (i = 0; i < klass->field.count; ++i) {
4127                 MonoArray *rva_data;
4128                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4129                 field = &klass->fields [i];
4130                 field->name = mono_string_to_utf8_image (image, fb->name, error);
4131                 if (!mono_error_ok (error))
4132                         return;
4133                 if (fb->attrs) {
4134                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4135                         return_if_nok (error);
4136                         field->type = mono_metadata_type_dup (klass->image, type);
4137                         field->type->attrs = fb->attrs;
4138                 } else {
4139                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
4140                         return_if_nok (error);
4141                 }
4142
4143                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
4144                         char *base = mono_array_addr (rva_data, char, 0);
4145                         size_t size = mono_array_length (rva_data);
4146                         char *data = (char *)mono_image_alloc (klass->image, size);
4147                         memcpy (data, base, size);
4148                         klass->ext->field_def_values [i].data = data;
4149                 }
4150                 if (fb->offset != -1)
4151                         field->offset = fb->offset;
4152                 field->parent = klass;
4153                 fb->handle = field;
4154                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
4155
4156                 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
4157                         klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
4158                 }
4159                 if (fb->def_value) {
4160                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4161                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
4162                         idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
4163                         /* Copy the data from the blob since it might get realloc-ed */
4164                         p = assembly->blob.data + idx;
4165                         len = mono_metadata_decode_blob_size (p, &p2);
4166                         len += p2 - p;
4167                         klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
4168                         memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
4169                 }
4170         }
4171
4172         klass->instance_size = MAX (klass->instance_size, real_size);
4173         mono_class_layout_fields (klass, klass->instance_size);
4174 }
4175
4176 static void
4177 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
4178 {
4179         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4180         MonoReflectionPropertyBuilder *pb;
4181         MonoImage *image = klass->image;
4182         MonoProperty *properties;
4183         int i;
4184
4185         mono_error_init (error);
4186
4187         if (!klass->ext)
4188                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4189
4190         klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
4191         klass->ext->property.first = 0;
4192
4193         properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
4194         klass->ext->properties = properties;
4195         for (i = 0; i < klass->ext->property.count; ++i) {
4196                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
4197                 properties [i].parent = klass;
4198                 properties [i].attrs = pb->attrs;
4199                 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
4200                 if (!mono_error_ok (error))
4201                         return;
4202                 if (pb->get_method)
4203                         properties [i].get = pb->get_method->mhandle;
4204                 if (pb->set_method)
4205                         properties [i].set = pb->set_method->mhandle;
4206
4207                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
4208                 if (pb->def_value) {
4209                         guint32 len, idx;
4210                         const char *p, *p2;
4211                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
4212                         if (!klass->ext->prop_def_values)
4213                                 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
4214                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
4215                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
4216                         /* Copy the data from the blob since it might get realloc-ed */
4217                         p = assembly->blob.data + idx;
4218                         len = mono_metadata_decode_blob_size (p, &p2);
4219                         len += p2 - p;
4220                         klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
4221                         memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
4222                 }
4223         }
4224 }
4225
4226 static MonoReflectionEvent *
4227 reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
4228 {
4229         mono_error_init (error);
4230
4231         MonoEvent *event = g_new0 (MonoEvent, 1);
4232         MonoClass *klass;
4233
4234         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4235         if (!is_ok (error)) {
4236                 g_free (event);
4237                 return NULL;
4238         }
4239         klass = mono_class_from_mono_type (type);
4240
4241         event->parent = klass;
4242         event->attrs = eb->attrs;
4243         event->name = mono_string_to_utf8_checked (eb->name, error);
4244         if (!is_ok (error)) {
4245                 g_free (event);
4246                 return NULL;
4247         }
4248         if (eb->add_method)
4249                 event->add = eb->add_method->mhandle;
4250         if (eb->remove_method)
4251                 event->remove = eb->remove_method->mhandle;
4252         if (eb->raise_method)
4253                 event->raise = eb->raise_method->mhandle;
4254
4255 #ifndef MONO_SMALL_CONFIG
4256         if (eb->other_methods) {
4257                 int j;
4258                 event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
4259                 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4260                         MonoReflectionMethodBuilder *mb = 
4261                                 mono_array_get (eb->other_methods,
4262                                                 MonoReflectionMethodBuilder*, j);
4263                         event->other [j] = mb->mhandle;
4264                 }
4265         }
4266 #endif
4267
4268         MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
4269         if (!is_ok (error)) {
4270 #ifndef MONO_SMALL_CONFIG
4271                 g_free (event->other);
4272 #endif
4273                 g_free (event);
4274                 return NULL;
4275         }
4276         return ev_obj;
4277 }
4278
4279 MonoReflectionEvent *
4280 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
4281 {
4282         MonoError error;
4283         MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
4284         mono_error_set_pending_exception (&error);
4285         return result;
4286 }
4287
4288 static void
4289 typebuilder_setup_events (MonoClass *klass, MonoError *error)
4290 {
4291         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4292         MonoReflectionEventBuilder *eb;
4293         MonoImage *image = klass->image;
4294         MonoEvent *events;
4295         int i;
4296
4297         mono_error_init (error);
4298
4299         if (!klass->ext)
4300                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
4301
4302         klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
4303         klass->ext->event.first = 0;
4304
4305         events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
4306         klass->ext->events = events;
4307         for (i = 0; i < klass->ext->event.count; ++i) {
4308                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
4309                 events [i].parent = klass;
4310                 events [i].attrs = eb->attrs;
4311                 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
4312                 if (!mono_error_ok (error))
4313                         return;
4314                 if (eb->add_method)
4315                         events [i].add = eb->add_method->mhandle;
4316                 if (eb->remove_method)
4317                         events [i].remove = eb->remove_method->mhandle;
4318                 if (eb->raise_method)
4319                         events [i].raise = eb->raise_method->mhandle;
4320
4321 #ifndef MONO_SMALL_CONFIG
4322                 if (eb->other_methods) {
4323                         int j;
4324                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
4325                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
4326                                 MonoReflectionMethodBuilder *mb = 
4327                                         mono_array_get (eb->other_methods,
4328                                                                         MonoReflectionMethodBuilder*, j);
4329                                 events [i].other [j] = mb->mhandle;
4330                         }
4331                 }
4332 #endif
4333                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
4334         }
4335 }
4336
4337 struct remove_instantiations_user_data
4338 {
4339         MonoClass *klass;
4340         MonoError *error;
4341 };
4342
4343 static gboolean
4344 remove_instantiations_of_and_ensure_contents (gpointer key,
4345                                                   gpointer value,
4346                                                   gpointer user_data)
4347 {
4348         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
4349         MonoType *type = (MonoType*)key;
4350         MonoClass *klass = data->klass;
4351         gboolean already_failed = !is_ok (data->error);
4352         MonoError lerror;
4353         MonoError *error = already_failed ? &lerror : data->error;
4354
4355         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
4356                 MonoClass *inst_klass = mono_class_from_mono_type (type);
4357                 //Ensure it's safe to use it.
4358                 if (!fix_partial_generic_class (inst_klass, error)) {
4359                         mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4360                         // Marked the class with failure, but since some other instantiation already failed,
4361                         // just report that one, and swallow the error from this one.
4362                         if (already_failed)
4363                                 mono_error_cleanup (error);
4364                 }
4365                 return TRUE;
4366         } else
4367                 return FALSE;
4368 }
4369
4370 static void
4371 check_array_for_usertypes (MonoArray *arr, MonoError *error)
4372 {
4373         mono_error_init (error);
4374         int i;
4375
4376         if (!arr)
4377                 return;
4378
4379         for (i = 0; i < mono_array_length (arr); ++i) {
4380                 RESOLVE_ARRAY_TYPE_ELEMENT (arr, i, error);
4381                 if (!mono_error_ok (error))
4382                         break;
4383         }
4384 }
4385
4386 void
4387 mono_reflection_check_array_for_usertypes (MonoArray *arr, MonoError *error)
4388 {
4389         check_array_for_usertypes (arr, error);
4390 }
4391
4392 MonoReflectionType*
4393 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4394 {
4395         MonoError error;
4396         MonoClass *klass;
4397         MonoDomain* domain;
4398         MonoReflectionType* res;
4399         int i, j;
4400
4401         mono_error_init (&error);
4402
4403         domain = mono_object_domain (tb);
4404         klass = mono_class_from_mono_type (tb->type.type);
4405
4406         /*
4407          * Check for user defined Type subclasses.
4408          */
4409         RESOLVE_TYPE (tb->parent, &error);
4410         if (!is_ok (&error))
4411                 goto failure_unlocked;
4412         check_array_for_usertypes (tb->interfaces, &error);
4413         if (!is_ok (&error))
4414                 goto failure_unlocked;
4415         if (tb->fields) {
4416                 for (i = 0; i < mono_array_length (tb->fields); ++i) {
4417                         MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
4418                         if (fb) {
4419                                 RESOLVE_TYPE (fb->type, &error);
4420                                 if (!is_ok (&error))
4421                                         goto failure_unlocked;
4422                                 check_array_for_usertypes (fb->modreq, &error);
4423                                 if (!is_ok (&error))
4424                                         goto failure_unlocked;
4425                                 check_array_for_usertypes (fb->modopt, &error);
4426                                 if (!is_ok (&error))
4427                                         goto failure_unlocked;
4428                                 if (fb->marshal_info && fb->marshal_info->marshaltyperef) {
4429                                         RESOLVE_TYPE (fb->marshal_info->marshaltyperef, &error);
4430                                         if (!is_ok (&error))
4431                                                 goto failure_unlocked;
4432                                 }
4433                         }
4434                 }
4435         }
4436         if (tb->methods) {
4437                 for (i = 0; i < mono_array_length (tb->methods); ++i) {
4438                         MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)mono_array_get (tb->methods, gpointer, i);
4439                         if (mb) {
4440                                 RESOLVE_TYPE (mb->rtype, &error);
4441                                 if (!is_ok (&error))
4442                                         goto failure_unlocked;
4443                                 check_array_for_usertypes (mb->return_modreq, &error);
4444                                 if (!is_ok (&error))
4445                                         goto failure_unlocked;
4446                                 check_array_for_usertypes (mb->return_modopt, &error);
4447                                 if (!is_ok (&error))
4448                                         goto failure_unlocked;
4449                                 check_array_for_usertypes (mb->parameters, &error);
4450                                 if (!is_ok (&error))
4451                                         goto failure_unlocked;
4452                                 if (mb->param_modreq)
4453                                         for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
4454                                                 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
4455                                                 if (!is_ok (&error))
4456                                                         goto failure_unlocked;
4457                                         }
4458                                 if (mb->param_modopt)
4459                                         for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
4460                                                 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
4461                                                 if (!is_ok (&error))
4462                                                         goto failure_unlocked;
4463                                         }
4464                         }
4465                 }
4466         }
4467         if (tb->ctors) {
4468                 for (i = 0; i < mono_array_length (tb->ctors); ++i) {
4469                         MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)mono_array_get (tb->ctors, gpointer, i);
4470                         if (mb) {
4471                                 check_array_for_usertypes (mb->parameters, &error);
4472                                 if (!is_ok (&error))
4473                                         goto failure_unlocked;
4474                                 if (mb->param_modreq)
4475                                         for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
4476                                                 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
4477                                                 if (!is_ok (&error))
4478                                                         goto failure_unlocked;
4479                                         }
4480                                 if (mb->param_modopt)
4481                                         for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
4482                                                 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
4483                                                 if (!is_ok (&error))
4484                                                         goto failure_unlocked;
4485                                         }
4486                         }
4487                 }
4488         }
4489
4490         mono_save_custom_attrs (klass->image, klass, tb->cattrs);
4491
4492         /* 
4493          * we need to lock the domain because the lock will be taken inside
4494          * So, we need to keep the locking order correct.
4495          */
4496         mono_loader_lock ();
4497         mono_domain_lock (domain);
4498         if (klass->wastypebuilder) {
4499                 mono_domain_unlock (domain);
4500                 mono_loader_unlock ();
4501
4502                 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4503                 mono_error_set_pending_exception (&error);
4504
4505                 return res;
4506         }
4507         /*
4508          * Fields to set in klass:
4509          * the various flags: delegate/unicode/contextbound etc.
4510          */
4511         klass->flags = tb->attrs;
4512         klass->has_cctor = 1;
4513
4514         mono_class_setup_parent (klass, klass->parent);
4515         /* fool mono_class_setup_supertypes */
4516         klass->supertypes = NULL;
4517         mono_class_setup_supertypes (klass);
4518         mono_class_setup_mono_type (klass);
4519
4520 #if 0
4521         if (!((MonoDynamicImage*)klass->image)->run) {
4522                 if (klass->generic_container) {
4523                         /* FIXME: The code below can't handle generic classes */
4524                         klass->wastypebuilder = TRUE;
4525                         mono_loader_unlock ();
4526                         mono_domain_unlock (domain);
4527
4528                         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4529                         mono_error_set_pending_exception (&error);
4530
4531                         return res;
4532                 }
4533         }
4534 #endif
4535
4536         /* enums are done right away */
4537         if (!klass->enumtype)
4538                 if (!ensure_runtime_vtable (klass, &error))
4539                         goto failure;
4540
4541         if (tb->subtypes) {
4542                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
4543                         MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
4544                         mono_class_alloc_ext (klass);
4545                         MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
4546                         if (!is_ok (&error)) goto failure;
4547                         klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
4548                 }
4549         }
4550
4551         klass->nested_classes_inited = TRUE;
4552
4553         /* fields and object layout */
4554         if (klass->parent) {
4555                 if (!klass->parent->size_inited)
4556                         mono_class_init (klass->parent);
4557                 klass->instance_size = klass->parent->instance_size;
4558                 klass->sizes.class_size = 0;
4559                 klass->min_align = klass->parent->min_align;
4560                 /* if the type has no fields we won't call the field_setup
4561                  * routine which sets up klass->has_references.
4562                  */
4563                 klass->has_references |= klass->parent->has_references;
4564         } else {
4565                 klass->instance_size = sizeof (MonoObject);
4566                 klass->min_align = 1;
4567         }
4568
4569         /* FIXME: handle packing_size and instance_size */
4570         typebuilder_setup_fields (klass, &error);
4571         if (!mono_error_ok (&error))
4572                 goto failure;
4573         typebuilder_setup_properties (klass, &error);
4574         if (!mono_error_ok (&error))
4575                 goto failure;
4576
4577         typebuilder_setup_events (klass, &error);
4578         if (!mono_error_ok (&error))
4579                 goto failure;
4580
4581         klass->wastypebuilder = TRUE;
4582
4583         /* 
4584          * If we are a generic TypeBuilder, there might be instantiations in the type cache
4585          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
4586          * we want to return normal System.MonoType objects, so clear these out from the cache.
4587          *
4588          * Together with this we must ensure the contents of all instances to match the created type.
4589          */
4590         if (domain->type_hash && klass->generic_container) {
4591                 struct remove_instantiations_user_data data;
4592                 data.klass = klass;
4593                 data.error = &error;
4594                 mono_error_assert_ok (&error);
4595                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
4596                 if (!is_ok (&error))
4597                         goto failure;
4598         }
4599
4600         mono_domain_unlock (domain);
4601         mono_loader_unlock ();
4602
4603         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
4604                 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4605                 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
4606                 goto failure_unlocked;
4607         }
4608
4609         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
4610         if (!is_ok (&error))
4611                 goto failure_unlocked;
4612
4613         g_assert (res != (MonoReflectionType*)tb);
4614
4615         return res;
4616
4617 failure:
4618         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
4619         klass->wastypebuilder = TRUE;
4620         mono_domain_unlock (domain);
4621         mono_loader_unlock ();
4622 failure_unlocked:
4623         mono_error_set_pending_exception (&error);
4624         return NULL;
4625 }
4626
4627 static gboolean
4628 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
4629 {
4630         MonoGenericParamFull *param;
4631         MonoImage *image;
4632         MonoClass *pklass;
4633
4634         mono_error_init (error);
4635
4636         image = &gparam->tbuilder->module->dynamic_image->image;
4637
4638         param = mono_image_new0 (image, MonoGenericParamFull, 1);
4639
4640         param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
4641         mono_error_assert_ok (error);
4642         param->param.num = gparam->index;
4643
4644         if (gparam->mbuilder) {
4645                 if (!gparam->mbuilder->generic_container) {
4646                         MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
4647                         return_val_if_nok (error, FALSE);
4648
4649                         MonoClass *klass = mono_class_from_mono_type (tb);
4650                         gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4651                         gparam->mbuilder->generic_container->is_method = TRUE;
4652                         /* 
4653                          * Cannot set owner.method, since the MonoMethod is not created yet.
4654                          * Set the image field instead, so type_in_image () works.
4655                          */
4656                         gparam->mbuilder->generic_container->is_anonymous = TRUE;
4657                         gparam->mbuilder->generic_container->owner.image = klass->image;
4658                 }
4659                 param->param.owner = gparam->mbuilder->generic_container;
4660         } else if (gparam->tbuilder) {
4661                 if (!gparam->tbuilder->generic_container) {
4662                         MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
4663                         return_val_if_nok (error, FALSE);
4664                         MonoClass *klass = mono_class_from_mono_type (tb);
4665                         gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
4666                         gparam->tbuilder->generic_container->owner.klass = klass;
4667                 }
4668                 param->param.owner = gparam->tbuilder->generic_container;
4669         }
4670
4671         pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
4672
4673         gparam->type.type = &pklass->byval_arg;
4674
4675         mono_class_set_ref_info (pklass, gparam);
4676         mono_image_append_class_to_reflection_info_set (pklass);
4677
4678         return TRUE;
4679 }
4680
4681 void
4682 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
4683 {
4684         MonoError error;
4685         (void) reflection_initialize_generic_parameter (gparam, &error);
4686         mono_error_set_pending_exception (&error);
4687 }
4688
4689
4690 typedef struct {
4691         MonoMethod *handle;
4692         MonoDomain *domain;
4693 } DynamicMethodReleaseData;
4694
4695 /*
4696  * The runtime automatically clean up those after finalization.
4697 */      
4698 static MonoReferenceQueue *dynamic_method_queue;
4699
4700 static void
4701 free_dynamic_method (void *dynamic_method)
4702 {
4703         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
4704         MonoDomain *domain = data->domain;
4705         MonoMethod *method = data->handle;
4706         guint32 dis_link;
4707
4708         mono_domain_lock (domain);
4709         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
4710         g_hash_table_remove (domain->method_to_dyn_method, method);
4711         mono_domain_unlock (domain);
4712         g_assert (dis_link);
4713         mono_gchandle_free (dis_link);
4714
4715         mono_runtime_free_method (domain, method);
4716         g_free (data);
4717 }
4718
4719 static gboolean
4720 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
4721 {
4722         MonoReferenceQueue *queue;
4723         MonoMethod *handle;
4724         DynamicMethodReleaseData *release_data;
4725         ReflectionMethodBuilder rmb;
4726         MonoMethodSignature *sig;
4727         MonoClass *klass;
4728         MonoDomain *domain;
4729         GSList *l;
4730         int i;
4731
4732         mono_error_init (error);
4733
4734         if (mono_runtime_is_shutting_down ()) {
4735                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
4736                 return FALSE;
4737         }
4738
4739         if (!(queue = dynamic_method_queue)) {
4740                 mono_loader_lock ();
4741                 if (!(queue = dynamic_method_queue))
4742                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
4743                 mono_loader_unlock ();
4744         }
4745
4746         sig = dynamic_method_to_signature (mb, error);
4747         return_val_if_nok (error, FALSE);
4748
4749         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
4750
4751         /*
4752          * Resolve references.
4753          */
4754         /* 
4755          * Every second entry in the refs array is reserved for storing handle_class,
4756          * which is needed by the ldtoken implementation in the JIT.
4757          */
4758         rmb.nrefs = mb->nrefs;
4759         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
4760         for (i = 0; i < mb->nrefs; i += 2) {
4761                 MonoClass *handle_class;
4762                 gpointer ref;
4763                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
4764
4765                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
4766                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4767                         /*
4768                          * The referenced DynamicMethod should already be created by the managed
4769                          * code, except in the case of circular references. In that case, we store
4770                          * method in the refs array, and fix it up later when the referenced 
4771                          * DynamicMethod is created.
4772                          */
4773                         if (method->mhandle) {
4774                                 ref = method->mhandle;
4775                         } else {
4776                                 /* FIXME: GC object stored in unmanaged memory */
4777                                 ref = method;
4778
4779                                 /* FIXME: GC object stored in unmanaged memory */
4780                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
4781                         }
4782                         handle_class = mono_defaults.methodhandle_class;
4783                 } else {
4784                         MonoException *ex = NULL;
4785                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
4786                         if (!is_ok  (error)) {
4787                                 g_free (rmb.refs);
4788                                 return FALSE;
4789                         }
4790                         if (!ref)
4791                                 ex = mono_get_exception_type_load (NULL, NULL);
4792                         else if (mono_security_core_clr_enabled ())
4793                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
4794
4795                         if (ex) {
4796                                 g_free (rmb.refs);
4797                                 mono_error_set_exception_instance (error, ex);
4798                                 return FALSE;
4799                         }
4800                 }
4801
4802                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4803                 rmb.refs [i + 1] = handle_class;
4804         }               
4805
4806         if (mb->owner) {
4807                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
4808                 if (!is_ok (error)) {
4809                         g_free (rmb.refs);
4810                         return FALSE;
4811                 }
4812                 klass = mono_class_from_mono_type (owner_type);
4813         } else {
4814                 klass = mono_defaults.object_class;
4815         }
4816
4817         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
4818         g_free (rmb.refs);
4819         return_val_if_nok (error, FALSE);
4820
4821         release_data = g_new (DynamicMethodReleaseData, 1);
4822         release_data->handle = handle;
4823         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
4824         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
4825                 g_free (release_data);
4826
4827         /* Fix up refs entries pointing at us */
4828         for (l = mb->referenced_by; l; l = l->next) {
4829                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
4830                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
4831                 gpointer *data;
4832                 
4833                 g_assert (method->mhandle);
4834
4835                 data = (gpointer*)wrapper->method_data;
4836                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
4837                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
4838                                 data [i + 1] = mb->mhandle;
4839                 }
4840         }
4841         g_slist_free (mb->referenced_by);
4842
4843         /* ilgen is no longer needed */
4844         mb->ilgen = NULL;
4845
4846         domain = mono_domain_get ();
4847         mono_domain_lock (domain);
4848         if (!domain->method_to_dyn_method)
4849                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
4850         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
4851         mono_domain_unlock (domain);
4852
4853         return TRUE;
4854 }
4855
4856 void
4857 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4858 {
4859         MonoError error;
4860         (void) reflection_create_dynamic_method (mb, &error);
4861         mono_error_set_pending_exception (&error);
4862 }
4863
4864 #endif /* DISABLE_REFLECTION_EMIT */
4865
4866 MonoMethodSignature *
4867 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
4868 {
4869         MonoMethodSignature *sig;
4870         g_assert (image_is_dynamic (image));
4871
4872         mono_error_init (error);
4873
4874         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4875         if (sig)
4876                 return sig;
4877
4878         return mono_method_signature_checked (method, error);
4879 }
4880
4881 #ifndef DISABLE_REFLECTION_EMIT
4882
4883 /*
4884  * ensure_complete_type:
4885  *
4886  *   Ensure that KLASS is completed if it is a dynamic type, or references
4887  * dynamic types.
4888  */
4889 static void
4890 ensure_complete_type (MonoClass *klass, MonoError *error)
4891 {
4892         mono_error_init (error);
4893
4894         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
4895                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
4896
4897                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4898                 return_if_nok (error);
4899
4900                 // Asserting here could break a lot of code
4901                 //g_assert (klass->wastypebuilder);
4902         }
4903
4904         if (klass->generic_class) {
4905                 MonoGenericInst *inst = klass->generic_class->context.class_inst;
4906                 int i;
4907
4908                 for (i = 0; i < inst->type_argc; ++i) {
4909                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4910                         return_if_nok (error);
4911                 }
4912         }
4913 }
4914
4915 gpointer
4916 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4917 {
4918         gpointer result = NULL;
4919
4920         mono_error_init (error);
4921
4922         if (strcmp (obj->vtable->klass->name, "String") == 0) {
4923                 result = mono_string_intern_checked ((MonoString*)obj, error);
4924                 return_val_if_nok (error, NULL);
4925                 *handle_class = mono_defaults.string_class;
4926                 g_assert (result);
4927         } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
4928                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4929                 return_val_if_nok (error, NULL);
4930                 MonoClass *mc = mono_class_from_mono_type (type);
4931                 if (!mono_class_init (mc)) {
4932                         mono_error_set_for_class_failure (error, mc);
4933                         return NULL;
4934                 }
4935
4936                 if (context) {
4937                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4938                         return_val_if_nok (error, NULL);
4939
4940                         result = mono_class_from_mono_type (inflated);
4941                         mono_metadata_free_type (inflated);
4942                 } else {
4943                         result = mono_class_from_mono_type (type);
4944                 }
4945                 *handle_class = mono_defaults.typehandle_class;
4946                 g_assert (result);
4947         } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
4948                    strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
4949                    strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
4950                    strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
4951                 result = ((MonoReflectionMethod*)obj)->method;
4952                 if (context) {
4953                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4954                         mono_error_assert_ok (error);
4955                 }
4956                 *handle_class = mono_defaults.methodhandle_class;
4957                 g_assert (result);
4958         } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
4959                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
4960                 result = mb->mhandle;
4961                 if (!result) {
4962                         /* Type is not yet created */
4963                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
4964
4965                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4966                         return_val_if_nok (error, NULL);
4967
4968                         /*
4969                          * Hopefully this has been filled in by calling CreateType() on the
4970                          * TypeBuilder.
4971                          */
4972                         /*
4973                          * TODO: This won't work if the application finishes another 
4974                          * TypeBuilder instance instead of this one.
4975                          */
4976                         result = mb->mhandle;
4977                 }
4978                 if (context) {
4979                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4980                         mono_error_assert_ok (error);
4981                 }
4982                 *handle_class = mono_defaults.methodhandle_class;
4983         } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
4984                 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
4985
4986                 result = cb->mhandle;
4987                 if (!result) {
4988                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
4989
4990                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4991                         return_val_if_nok (error, NULL);
4992                         result = cb->mhandle;
4993                 }
4994                 if (context) {
4995                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4996                         mono_error_assert_ok (error);
4997                 }
4998                 *handle_class = mono_defaults.methodhandle_class;
4999         } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
5000                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
5001
5002                 ensure_complete_type (field->parent, error);
5003                 return_val_if_nok (error, NULL);
5004
5005                 if (context) {
5006                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
5007                         return_val_if_nok (error, NULL);
5008
5009                         MonoClass *klass = mono_class_from_mono_type (inflated);
5010                         MonoClassField *inflated_field;
5011                         gpointer iter = NULL;
5012                         mono_metadata_free_type (inflated);
5013                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
5014                                 if (!strcmp (field->name, inflated_field->name))
5015                                         break;
5016                         }
5017                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
5018                         result = inflated_field;
5019                 } else {
5020                         result = field;
5021                 }
5022                 *handle_class = mono_defaults.fieldhandle_class;
5023                 g_assert (result);
5024         } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
5025                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
5026                 result = fb->handle;
5027
5028                 if (!result) {
5029                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
5030
5031                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5032                         return_val_if_nok (error, NULL);
5033                         result = fb->handle;
5034                 }
5035
5036                 if (fb->handle && fb->handle->parent->generic_container) {
5037                         MonoClass *klass = fb->handle->parent;
5038                         MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
5039                         return_val_if_nok (error, NULL);
5040
5041                         MonoClass *inflated = mono_class_from_mono_type (type);
5042
5043                         result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
5044                         g_assert (result);
5045                         mono_metadata_free_type (type);
5046                 }
5047                 *handle_class = mono_defaults.fieldhandle_class;
5048         } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
5049                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
5050                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
5051                 return_val_if_nok (error, NULL);
5052                 MonoClass *klass;
5053
5054                 klass = type->data.klass;
5055                 if (klass->wastypebuilder) {
5056                         /* Already created */
5057                         result = klass;
5058                 }
5059                 else {
5060                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
5061                         return_val_if_nok (error, NULL);
5062                         result = type->data.klass;
5063                         g_assert (result);
5064                 }
5065                 *handle_class = mono_defaults.typehandle_class;
5066         } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
5067                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
5068                 MonoMethodSignature *sig;
5069                 int nargs, i;
5070
5071                 if (helper->arguments)
5072                         nargs = mono_array_length (helper->arguments);
5073                 else
5074                         nargs = 0;
5075
5076                 sig = mono_metadata_signature_alloc (image, nargs);
5077                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
5078                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
5079
5080                 if (helper->unmanaged_call_conv) { /* unmanaged */
5081                         sig->call_convention = helper->unmanaged_call_conv - 1;
5082                         sig->pinvoke = TRUE;
5083                 } else if (helper->call_conv & 0x02) {
5084                         sig->call_convention = MONO_CALL_VARARG;
5085                 } else {
5086                         sig->call_convention = MONO_CALL_DEFAULT;
5087                 }
5088
5089                 sig->param_count = nargs;
5090                 /* TODO: Copy type ? */
5091                 sig->ret = helper->return_type->type;
5092                 for (i = 0; i < nargs; ++i) {
5093                         sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
5094                         if (!is_ok (error)) {
5095                                 image_g_free (image, sig);
5096                                 return NULL;
5097                         }
5098                 }
5099
5100                 result = sig;
5101                 *handle_class = NULL;
5102         } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
5103                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
5104                 /* Already created by the managed code */
5105                 g_assert (method->mhandle);
5106                 result = method->mhandle;
5107                 *handle_class = mono_defaults.methodhandle_class;
5108         } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
5109                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
5110                 return_val_if_nok (error, NULL);
5111                 type = mono_class_inflate_generic_type_checked (type, context, error);
5112                 return_val_if_nok (error, NULL);
5113
5114                 result = mono_class_from_mono_type (type);
5115                 *handle_class = mono_defaults.typehandle_class;
5116                 g_assert (result);
5117                 mono_metadata_free_type (type);
5118         } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
5119                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
5120                 return_val_if_nok (error, NULL);
5121                 type = mono_class_inflate_generic_type_checked (type, context, error);
5122                 return_val_if_nok (error, NULL);
5123
5124                 result = mono_class_from_mono_type (type);
5125                 *handle_class = mono_defaults.typehandle_class;
5126                 g_assert (result);
5127                 mono_metadata_free_type (type);
5128         } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
5129                 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
5130                 MonoClass *inflated;
5131                 MonoType *type;
5132                 MonoClassField *field;
5133
5134                 if (is_sre_field_builder (mono_object_class (f->fb)))
5135                         field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
5136                 else if (is_sr_mono_field (mono_object_class (f->fb)))
5137                         field = ((MonoReflectionField*)f->fb)->field;
5138                 else
5139                         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)));
5140
5141                 MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
5142                 return_val_if_nok (error, NULL);
5143                 type = mono_class_inflate_generic_type_checked (finst, context, error);
5144                 return_val_if_nok (error, NULL);
5145
5146                 inflated = mono_class_from_mono_type (type);
5147
5148                 result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
5149                 ensure_complete_type (field->parent, error);
5150                 if (!is_ok (error)) {
5151                         mono_metadata_free_type (type);
5152                         return NULL;
5153                 }
5154
5155                 g_assert (result);
5156                 mono_metadata_free_type (type);
5157                 *handle_class = mono_defaults.fieldhandle_class;
5158         } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
5159                 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
5160                 MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
5161                 return_val_if_nok (error, NULL);
5162                 MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
5163                 return_val_if_nok (error, NULL);
5164
5165                 MonoClass *inflated_klass = mono_class_from_mono_type (type);
5166                 MonoMethod *method;
5167
5168                 if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
5169                         method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
5170                 else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
5171                         method = ((MonoReflectionMethod *)c->cb)->method;
5172                 else
5173                         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)));
5174
5175                 result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
5176                 *handle_class = mono_defaults.methodhandle_class;
5177                 mono_metadata_free_type (type);
5178         } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
5179                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
5180                 if (m->method_args) {
5181                         result = mono_reflection_method_on_tb_inst_get_handle (m, error);
5182                         return_val_if_nok (error, NULL);
5183                         if (context) {
5184                                 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
5185                                 mono_error_assert_ok (error);
5186                         }
5187                 } else {
5188                         MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
5189                         return_val_if_nok (error, NULL);
5190                         MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
5191                         return_val_if_nok (error, NULL);
5192
5193                         MonoClass *inflated_klass = mono_class_from_mono_type (type);
5194                         MonoMethod *method;
5195
5196                         if (is_sre_method_builder (mono_object_class (m->mb)))
5197                                 method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
5198                         else if (is_sr_mono_method (mono_object_class (m->mb)))
5199                                 method = ((MonoReflectionMethod *)m->mb)->method;
5200                         else
5201                                 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)));
5202
5203                         result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
5204                         mono_metadata_free_type (type);
5205                 }
5206                 *handle_class = mono_defaults.methodhandle_class;
5207         } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
5208                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
5209                 MonoType *mtype;
5210                 MonoClass *klass;
5211                 MonoMethod *method;
5212                 gpointer iter;
5213                 char *name;
5214
5215                 mtype = mono_reflection_type_get_handle (m->parent, error);
5216                 return_val_if_nok (error, NULL);
5217                 klass = mono_class_from_mono_type (mtype);
5218
5219                 /* Find the method */
5220
5221                 name = mono_string_to_utf8_checked (m->name, error);
5222                 return_val_if_nok (error, NULL);
5223                 iter = NULL;
5224                 while ((method = mono_class_get_methods (klass, &iter))) {
5225                         if (!strcmp (method->name, name))
5226                                 break;
5227                 }
5228                 g_free (name);
5229
5230                 // FIXME:
5231                 g_assert (method);
5232                 // FIXME: Check parameters/return value etc. match
5233
5234                 result = method;
5235                 *handle_class = mono_defaults.methodhandle_class;
5236         } else if (is_sre_array (mono_object_get_class(obj)) ||
5237                                 is_sre_byref (mono_object_get_class(obj)) ||
5238                                 is_sre_pointer (mono_object_get_class(obj))) {
5239                 MonoReflectionType *ref_type = (MonoReflectionType *)obj;
5240                 MonoType *type = mono_reflection_type_get_handle (ref_type, error);
5241                 return_val_if_nok (error, NULL);
5242
5243                 if (context) {
5244                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
5245                         return_val_if_nok (error, NULL);
5246
5247                         result = mono_class_from_mono_type (inflated);
5248                         mono_metadata_free_type (inflated);
5249                 } else {
5250                         result = mono_class_from_mono_type (type);
5251                 }
5252                 *handle_class = mono_defaults.typehandle_class;
5253         } else {
5254                 g_print ("%s\n", obj->vtable->klass->name);
5255                 g_assert_not_reached ();
5256         }
5257         return result;
5258 }
5259
5260 #else /* DISABLE_REFLECTION_EMIT */
5261
5262 MonoArray*
5263 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
5264 {
5265         g_assert_not_reached ();
5266         return NULL;
5267 }
5268
5269 void
5270 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
5271 {
5272         g_assert_not_reached ();
5273 }
5274
5275 void
5276 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
5277 {
5278         g_assert_not_reached ();
5279 }
5280
5281 gboolean
5282 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
5283 {
5284         g_assert_not_reached ();
5285         return FALSE;
5286 }
5287
5288 void
5289 ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
5290 {
5291         g_assert_not_reached ();
5292 }
5293
5294 void
5295 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5296 {
5297         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
5298 }
5299
5300 static void
5301 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
5302 {
5303         g_assert_not_reached ();
5304 }
5305
5306 guint32
5307 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
5308 {
5309         g_assert_not_reached ();
5310         return 0;
5311 }
5312
5313 guint32
5314 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
5315 {
5316         g_assert_not_reached ();
5317         return 0;
5318 }
5319
5320 guint32
5321 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
5322                          gboolean create_open_instance, gboolean register_token, MonoError *error)
5323 {
5324         g_assert_not_reached ();
5325         return 0;
5326 }
5327
5328 void
5329 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
5330 {
5331         g_assert_not_reached ();
5332 }
5333
5334 void
5335 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
5336 {
5337         mono_error_init (error);
5338         *overrides = NULL;
5339         *num_overrides = 0;
5340 }
5341
5342 MonoReflectionEvent *
5343 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
5344 {
5345         g_assert_not_reached ();
5346         return NULL;
5347 }
5348
5349 MonoReflectionType*
5350 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
5351 {
5352         g_assert_not_reached ();
5353         return NULL;
5354 }
5355
5356 void
5357 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
5358 {
5359         g_assert_not_reached ();
5360 }
5361
5362 void 
5363 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
5364 {
5365 }
5366
5367 MonoType*
5368 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
5369 {
5370         mono_error_init (error);
5371         if (!ref)
5372                 return NULL;
5373         return ref->type;
5374 }
5375
5376 #endif /* DISABLE_REFLECTION_EMIT */
5377
5378 #ifndef DISABLE_REFLECTION_EMIT
5379 MonoMethod*
5380 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5381 {
5382         MonoType *tb;
5383         MonoClass *klass;
5384
5385         tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
5386         return_val_if_nok (error, NULL);
5387         klass = mono_class_from_mono_type (tb);
5388
5389         return methodbuilder_to_mono_method (klass, mb, error);
5390 }
5391 #else /* DISABLE_REFLECTION_EMIT */
5392 MonoMethod*
5393 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
5394 {
5395         g_assert_not_reached ();
5396         return NULL;
5397 }
5398 #endif /* DISABLE_REFLECTION_EMIT */
5399
5400 gint32
5401 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
5402 {
5403         MONO_CHECK_ARG_NULL (obj, 0);
5404
5405         MonoError error;
5406         gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
5407         mono_error_set_pending_exception (&error);
5408         return result;
5409 }
5410
5411 gint32
5412 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
5413                                         MonoReflectionMethod *method,
5414                                         MonoArray *opt_param_types)
5415 {
5416         MONO_CHECK_ARG_NULL (method, 0);
5417
5418         MonoError error;
5419         gint32 result = mono_image_create_method_token (
5420                 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
5421         mono_error_set_pending_exception (&error);
5422         return result;
5423 }
5424
5425 void
5426 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
5427 {
5428         MonoError error;
5429         mono_image_create_pefile (mb, file, &error);
5430         mono_error_set_pending_exception (&error);
5431 }
5432
5433 void
5434 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
5435 {
5436         MonoError error;
5437         mono_image_build_metadata (mb, &error);
5438         mono_error_set_pending_exception (&error);
5439 }
5440
5441 void
5442 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
5443 {
5444         mono_image_register_token (mb->dynamic_image, token, obj);
5445 }
5446
5447 MonoObject*
5448 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
5449 {
5450         MonoObject *obj;
5451
5452         mono_loader_lock ();
5453         obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
5454         mono_loader_unlock ();
5455
5456         return obj;
5457 }
5458
5459 /**
5460  * ves_icall_TypeBuilder_create_generic_class:
5461  * @tb: a TypeBuilder object
5462  *
5463  * (icall)
5464  * Creates the generic class after all generic parameters have been added.
5465  */
5466 void
5467 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
5468 {
5469         MonoError error;
5470         (void) mono_reflection_create_generic_class (tb, &error);
5471         mono_error_set_pending_exception (&error);
5472 }
5473
5474 #ifndef DISABLE_REFLECTION_EMIT
5475 MonoArray*
5476 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
5477 {
5478         MonoError error;
5479         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
5480         mono_error_set_pending_exception (&error);
5481         return result;
5482 }
5483 #endif
5484
5485 void
5486 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5487 {
5488         mono_reflection_dynimage_basic_init (assemblyb);
5489 }
5490
5491 MonoBoolean
5492 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
5493 {
5494         return mono_type_is_generic_parameter (tb->type.type);
5495 }
5496
5497 void
5498 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
5499                                                                            MonoReflectionType *t)
5500 {
5501         enumtype->type = t->type;
5502 }
5503
5504 MonoReflectionType*
5505 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5506 {
5507         MonoError error;
5508         MonoReflectionType *ret;
5509         MonoClass *klass;
5510         int isbyref = 0, rank;
5511         char *p;
5512         char *str = mono_string_to_utf8_checked (smodifiers, &error);
5513         if (mono_error_set_pending_exception (&error))
5514                 return NULL;
5515
5516         klass = mono_class_from_mono_type (tb->type.type);
5517         p = str;
5518         /* logic taken from mono_reflection_parse_type(): keep in sync */
5519         while (*p) {
5520                 switch (*p) {
5521                 case '&':
5522                         if (isbyref) { /* only one level allowed by the spec */
5523                                 g_free (str);
5524                                 return NULL;
5525                         }
5526                         isbyref = 1;
5527                         p++;
5528
5529                         g_free (str);
5530
5531                         ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
5532                         mono_error_set_pending_exception (&error);
5533
5534                         return ret;
5535                 case '*':
5536                         klass = mono_ptr_class_get (&klass->byval_arg);
5537                         mono_class_init (klass);
5538                         p++;
5539                         break;
5540                 case '[':
5541                         rank = 1;
5542                         p++;
5543                         while (*p) {
5544                                 if (*p == ']')
5545                                         break;
5546                                 if (*p == ',')
5547                                         rank++;
5548                                 else if (*p != '*') { /* '*' means unknown lower bound */
5549                                         g_free (str);
5550                                         return NULL;
5551                                 }
5552                                 ++p;
5553                         }
5554                         if (*p != ']') {
5555                                 g_free (str);
5556                                 return NULL;
5557                         }
5558                         p++;
5559                         klass = mono_array_class_get (klass, rank);
5560                         mono_class_init (klass);
5561                         break;
5562                 default:
5563                         break;
5564                 }
5565         }
5566
5567         g_free (str);
5568
5569         ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
5570         mono_error_set_pending_exception (&error);
5571
5572         return ret;
5573 }
5574
5575 void
5576 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
5577 {
5578         mono_image_module_basic_init (moduleb);
5579 }
5580
5581 guint32
5582 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
5583 {
5584         return mono_image_insert_string (module, str);
5585 }
5586
5587 void
5588 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
5589 {
5590         MonoDynamicImage *image = moduleb->dynamic_image;
5591
5592         g_assert (type->type);
5593         image->wrappers_type = mono_class_from_mono_type (type->type);
5594 }