[sre] Split out MonoDynamicImage and MonoDynamicStream functions
[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
36 #include "mono/utils/checked-build.h"
37 #include "mono/utils/mono-digest.h"
38
39
40 typedef struct {
41         char *p;
42         char *buf;
43         char *end;
44 } SigBuffer;
45
46 typedef struct {
47         MonoReflectionILGen *ilgen;
48         MonoReflectionType *rtype;
49         MonoArray *parameters;
50         MonoArray *generic_params;
51         MonoGenericContainer *generic_container;
52         MonoArray *pinfo;
53         MonoArray *opt_types;
54         guint32 attrs;
55         guint32 iattrs;
56         guint32 call_conv;
57         guint32 *table_idx; /* note: it's a pointer */
58         MonoArray *code;
59         MonoObject *type;
60         MonoString *name;
61         MonoBoolean init_locals;
62         MonoBoolean skip_visibility;
63         MonoArray *return_modreq;
64         MonoArray *return_modopt;
65         MonoArray *param_modreq;
66         MonoArray *param_modopt;
67         MonoArray *permissions;
68         MonoMethod *mhandle;
69         guint32 nrefs;
70         gpointer *refs;
71         /* for PInvoke */
72         int charset, extra_flags, native_cc;
73         MonoString *dll, *dllentry;
74 } ReflectionMethodBuilder;
75
76 struct _GenericParamTableEntry {
77         guint32 owner;
78         MonoReflectionGenericParam *gparam;
79 };
80
81 void
82 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
83 {
84         mono_gc_deregister_root ((char*) &entry->gparam);
85         g_free (entry);
86 }
87
88
89
90 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
91
92 #ifndef DISABLE_REFLECTION_EMIT
93 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
94 static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance, MonoError *error);
95 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb, MonoError *error);
96 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
97 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
98 static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
99 static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
100 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
101 static gboolean reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error);
102 static gboolean reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error);
103 static guint32 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error);
104 #endif
105
106 static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
107 static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
108 static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
109 static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error);
110 static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type);
111 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
112 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
113 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
114 static gboolean is_sre_array (MonoClass *klass);
115 static gboolean is_sre_byref (MonoClass *klass);
116 static gboolean is_sre_pointer (MonoClass *klass);
117 static gboolean is_sre_type_builder (MonoClass *klass);
118 static gboolean is_sre_method_builder (MonoClass *klass);
119 static gboolean is_sre_field_builder (MonoClass *klass);
120 static gboolean is_sr_mono_method (MonoClass *klass);
121 static gboolean is_sr_mono_generic_method (MonoClass *klass);
122 static gboolean is_sr_mono_generic_cmethod (MonoClass *klass);
123 static gboolean is_sr_mono_field (MonoClass *klass);
124
125 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
126 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
127 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error);
128
129 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
130 static void init_type_builder_generics (MonoObject *type, MonoError *error);
131
132 #define TEXT_OFFSET 512
133 #define CLI_H_SIZE 136
134 #define FILE_ALIGN 512
135 #define VIRT_ALIGN 8192
136 #define START_TEXT_RVA  0x00002000
137
138 #define RESOLVE_TYPE(type, error) do {                                  \
139         type = (MonoObject *)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type, error); \
140 } while (0)
141 #define RESOLVE_ARRAY_TYPE_ELEMENT(array, index, error) do {            \
142         MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
143         __type = mono_reflection_type_resolve_user_types (__type, error); \
144         if (mono_error_ok (error))                                      \
145                 mono_array_set (arr, MonoReflectionType*, index, __type); \
146 } while (0)
147
148 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
149
150 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
151
152 void
153 mono_reflection_emit_init (void)
154 {
155         mono_dynamic_images_init ();
156 }
157
158 static void
159 sigbuffer_init (SigBuffer *buf, int size)
160 {
161         MONO_REQ_GC_NEUTRAL_MODE;
162
163         buf->buf = (char *)g_malloc (size);
164         buf->p = buf->buf;
165         buf->end = buf->buf + size;
166 }
167
168 static void
169 sigbuffer_make_room (SigBuffer *buf, int size)
170 {
171         MONO_REQ_GC_NEUTRAL_MODE;
172
173         if (buf->end - buf->p < size) {
174                 int new_size = buf->end - buf->buf + size + 32;
175                 char *p = (char *)g_realloc (buf->buf, new_size);
176                 size = buf->p - buf->buf;
177                 buf->buf = p;
178                 buf->p = p + size;
179                 buf->end = buf->buf + new_size;
180         }
181 }
182
183 static void
184 sigbuffer_add_value (SigBuffer *buf, guint32 val)
185 {
186         MONO_REQ_GC_NEUTRAL_MODE;
187
188         sigbuffer_make_room (buf, 6);
189         mono_metadata_encode_value (val, buf->p, &buf->p);
190 }
191
192 static void
193 sigbuffer_add_byte (SigBuffer *buf, guint8 val)
194 {
195         MONO_REQ_GC_NEUTRAL_MODE;
196
197         sigbuffer_make_room (buf, 1);
198         buf->p [0] = val;
199         buf->p++;
200 }
201
202 static void
203 sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
204 {
205         MONO_REQ_GC_NEUTRAL_MODE;
206
207         sigbuffer_make_room (buf, size);
208         memcpy (buf->p, p, size);
209         buf->p += size;
210 }
211
212 static void
213 sigbuffer_free (SigBuffer *buf)
214 {
215         MONO_REQ_GC_NEUTRAL_MODE;
216
217         g_free (buf->buf);
218 }
219
220 #ifndef DISABLE_REFLECTION_EMIT
221 /**
222  * mp_g_alloc:
223  *
224  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
225  * from the C heap.
226  */
227 static gpointer
228 image_g_malloc (MonoImage *image, guint size)
229 {
230         MONO_REQ_GC_NEUTRAL_MODE;
231
232         if (image)
233                 return mono_image_alloc (image, size);
234         else
235                 return g_malloc (size);
236 }
237 #endif /* !DISABLE_REFLECTION_EMIT */
238
239 /**
240  * image_g_alloc0:
241  *
242  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
243  * from the C heap.
244  */
245 gpointer
246 mono_image_g_malloc0 (MonoImage *image, guint size)
247 {
248         MONO_REQ_GC_NEUTRAL_MODE;
249
250         if (image)
251                 return mono_image_alloc0 (image, size);
252         else
253                 return g_malloc0 (size);
254 }
255
256 /**
257  * image_g_free:
258  * @image: a MonoImage
259  * @ptr: pointer
260  *
261  * If @image is NULL, free @ptr, otherwise do nothing.
262  */
263 static void
264 image_g_free (MonoImage *image, gpointer ptr)
265 {
266         if (image == NULL)
267                 g_free (ptr);
268 }
269
270 #ifndef DISABLE_REFLECTION_EMIT
271 static char*
272 image_strdup (MonoImage *image, const char *s)
273 {
274         MONO_REQ_GC_NEUTRAL_MODE;
275
276         if (image)
277                 return mono_image_strdup (image, s);
278         else
279                 return g_strdup (s);
280 }
281 #endif
282
283 #define image_g_new(image,struct_type, n_structs)               \
284     ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
285
286 #define image_g_new0(image,struct_type, n_structs)              \
287     ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
288
289
290 static void
291 alloc_table (MonoDynamicTable *table, guint nrows)
292 {
293         MONO_REQ_GC_NEUTRAL_MODE;
294
295         table->rows = nrows;
296         g_assert (table->columns);
297         if (nrows + 1 >= table->alloc_rows) {
298                 while (nrows + 1 >= table->alloc_rows) {
299                         if (table->alloc_rows == 0)
300                                 table->alloc_rows = 16;
301                         else
302                                 table->alloc_rows *= 2;
303                 }
304
305                 table->values = (guint32 *)g_renew (guint32, table->values, (table->alloc_rows) * table->columns);
306         }
307 }
308
309 static guint32
310 string_heap_insert (MonoDynamicStream *sh, const char *str)
311 {
312         return mono_dynstream_insert_string (sh, str);
313 }
314
315 static guint32
316 string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str, MonoError *error)
317 {
318         return mono_dynstream_insert_mstring (sh, str, error);
319 }
320
321 static guint32
322 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
323 {
324         return mono_dynstream_add_data (stream, data, len);
325 }
326
327 static guint32
328 mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
329 {
330         return mono_dynstream_add_zero (stream, len);
331 }
332
333 static void
334 stream_data_align (MonoDynamicStream *stream)
335 {
336         mono_dynstream_data_align (stream);
337 }
338
339
340 static guint32
341 sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
342 {
343         MONO_REQ_GC_NEUTRAL_MODE;
344
345         char blob_size [8];
346         char *b = blob_size;
347         guint32 size = buf->p - buf->buf;
348         /* store length */
349         g_assert (size <= (buf->end - buf->buf));
350         mono_metadata_encode_value (size, b, &b);
351         return mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
352 }
353
354
355 /*
356  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
357  * dest may be misaligned.
358  */
359 static void
360 swap_with_size (char *dest, const char* val, int len, int nelem) {
361         MONO_REQ_GC_NEUTRAL_MODE;
362 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
363         int elem;
364
365         for (elem = 0; elem < nelem; ++elem) {
366                 switch (len) {
367                 case 1:
368                         *dest = *val;
369                         break;
370                 case 2:
371                         dest [0] = val [1];
372                         dest [1] = val [0];
373                         break;
374                 case 4:
375                         dest [0] = val [3];
376                         dest [1] = val [2];
377                         dest [2] = val [1];
378                         dest [3] = val [0];
379                         break;
380                 case 8:
381                         dest [0] = val [7];
382                         dest [1] = val [6];
383                         dest [2] = val [5];
384                         dest [3] = val [4];
385                         dest [4] = val [3];
386                         dest [5] = val [2];
387                         dest [6] = val [1];
388                         dest [7] = val [0];
389                         break;
390                 default:
391                         g_assert_not_reached ();
392                 }
393                 dest += len;
394                 val += len;
395         }
396 #else
397         memcpy (dest, val, len * nelem);
398 #endif
399 }
400
401 static guint32
402 add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
403 {
404         MONO_REQ_GC_UNSAFE_MODE;
405         
406         char blob_size [64];
407         char *b = blob_size;
408         guint32 idx = 0, len;
409
410         len = str->length * 2;
411         mono_metadata_encode_value (len, b, &b);
412 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
413         {
414                 char *swapped = g_malloc (2 * mono_string_length (str));
415                 const char *p = (const char*)mono_string_chars (str);
416
417                 swap_with_size (swapped, p, 2, mono_string_length (str));
418                 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
419                 g_free (swapped);
420         }
421 #else
422         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
423 #endif
424         return idx;
425 }
426
427 #ifndef DISABLE_REFLECTION_EMIT
428 static MonoClass *
429 default_class_from_mono_type (MonoType *type)
430 {
431         MONO_REQ_GC_NEUTRAL_MODE;
432
433         switch (type->type) {
434         case MONO_TYPE_OBJECT:
435                 return mono_defaults.object_class;
436         case MONO_TYPE_VOID:
437                 return mono_defaults.void_class;
438         case MONO_TYPE_BOOLEAN:
439                 return mono_defaults.boolean_class;
440         case MONO_TYPE_CHAR:
441                 return mono_defaults.char_class;
442         case MONO_TYPE_I1:
443                 return mono_defaults.sbyte_class;
444         case MONO_TYPE_U1:
445                 return mono_defaults.byte_class;
446         case MONO_TYPE_I2:
447                 return mono_defaults.int16_class;
448         case MONO_TYPE_U2:
449                 return mono_defaults.uint16_class;
450         case MONO_TYPE_I4:
451                 return mono_defaults.int32_class;
452         case MONO_TYPE_U4:
453                 return mono_defaults.uint32_class;
454         case MONO_TYPE_I:
455                 return mono_defaults.int_class;
456         case MONO_TYPE_U:
457                 return mono_defaults.uint_class;
458         case MONO_TYPE_I8:
459                 return mono_defaults.int64_class;
460         case MONO_TYPE_U8:
461                 return mono_defaults.uint64_class;
462         case MONO_TYPE_R4:
463                 return mono_defaults.single_class;
464         case MONO_TYPE_R8:
465                 return mono_defaults.double_class;
466         case MONO_TYPE_STRING:
467                 return mono_defaults.string_class;
468         default:
469                 g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
470                 g_assert_not_reached ();
471         }
472         
473         return NULL;
474 }
475 #endif
476
477 static void
478 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
479 {
480         MONO_REQ_GC_NEUTRAL_MODE;
481
482         int i;
483         MonoGenericInst *class_inst;
484         MonoClass *klass;
485
486         g_assert (gclass);
487
488         class_inst = gclass->context.class_inst;
489
490         sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
491         klass = gclass->container_class;
492         sigbuffer_add_value (buf, klass->byval_arg.type);
493         sigbuffer_add_value (buf, mono_image_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
494
495         sigbuffer_add_value (buf, class_inst->type_argc);
496         for (i = 0; i < class_inst->type_argc; ++i)
497                 encode_type (assembly, class_inst->type_argv [i], buf);
498
499 }
500
501 static void
502 encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
503 {
504         MONO_REQ_GC_NEUTRAL_MODE;
505
506         if (!type) {
507                 g_assert_not_reached ();
508                 return;
509         }
510                 
511         if (type->byref)
512                 sigbuffer_add_value (buf, MONO_TYPE_BYREF);
513
514         switch (type->type){
515         case MONO_TYPE_VOID:
516         case MONO_TYPE_BOOLEAN:
517         case MONO_TYPE_CHAR:
518         case MONO_TYPE_I1:
519         case MONO_TYPE_U1:
520         case MONO_TYPE_I2:
521         case MONO_TYPE_U2:
522         case MONO_TYPE_I4:
523         case MONO_TYPE_U4:
524         case MONO_TYPE_I8:
525         case MONO_TYPE_U8:
526         case MONO_TYPE_R4:
527         case MONO_TYPE_R8:
528         case MONO_TYPE_I:
529         case MONO_TYPE_U:
530         case MONO_TYPE_STRING:
531         case MONO_TYPE_OBJECT:
532         case MONO_TYPE_TYPEDBYREF:
533                 sigbuffer_add_value (buf, type->type);
534                 break;
535         case MONO_TYPE_PTR:
536                 sigbuffer_add_value (buf, type->type);
537                 encode_type (assembly, type->data.type, buf);
538                 break;
539         case MONO_TYPE_SZARRAY:
540                 sigbuffer_add_value (buf, type->type);
541                 encode_type (assembly, &type->data.klass->byval_arg, buf);
542                 break;
543         case MONO_TYPE_VALUETYPE:
544         case MONO_TYPE_CLASS: {
545                 MonoClass *k = mono_class_from_mono_type (type);
546
547                 if (k->generic_container) {
548                         MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, k->generic_container->context.class_inst, TRUE);
549                         encode_generic_class (assembly, gclass, buf);
550                 } else {
551                         /*
552                          * Make sure we use the correct type.
553                          */
554                         sigbuffer_add_value (buf, k->byval_arg.type);
555                         /*
556                          * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
557                          * otherwise two typerefs could point to the same type, leading to
558                          * verification errors.
559                          */
560                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
561                 }
562                 break;
563         }
564         case MONO_TYPE_ARRAY:
565                 sigbuffer_add_value (buf, type->type);
566                 encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
567                 sigbuffer_add_value (buf, type->data.array->rank);
568                 sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
569                 sigbuffer_add_value (buf, 0);
570                 break;
571         case MONO_TYPE_GENERICINST:
572                 encode_generic_class (assembly, type->data.generic_class, buf);
573                 break;
574         case MONO_TYPE_VAR:
575         case MONO_TYPE_MVAR:
576                 sigbuffer_add_value (buf, type->type);
577                 sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
578                 break;
579         default:
580                 g_error ("need to encode type %x", type->type);
581         }
582 }
583
584 static void
585 encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, SigBuffer *buf, MonoError *error)
586 {
587         MONO_REQ_GC_UNSAFE_MODE;
588
589         mono_error_init (error);
590
591         if (!type) {
592                 sigbuffer_add_value (buf, MONO_TYPE_VOID);
593                 return;
594         }
595
596         MonoType *t = mono_reflection_type_get_handle (type, error);
597         return_if_nok (error);
598         encode_type (assembly, t, buf);
599 }
600
601 static void
602 encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf, MonoError *error)
603 {
604         MONO_REQ_GC_UNSAFE_MODE;
605
606         int i;
607
608         mono_error_init (error);
609
610         if (modreq) {
611                 for (i = 0; i < mono_array_length (modreq); ++i) {
612                         MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
613                         return_if_nok (error);
614                         sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
615                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
616                 }
617         }
618         if (modopt) {
619                 for (i = 0; i < mono_array_length (modopt); ++i) {
620                         MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
621                         return_if_nok (error);
622                         sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
623                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
624                 }
625         }
626 }
627
628 #ifndef DISABLE_REFLECTION_EMIT
629 static guint32
630 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
631 {
632         MONO_REQ_GC_UNSAFE_MODE;
633
634         SigBuffer buf;
635         int i;
636         guint32 nparams =  sig->param_count;
637         guint32 idx;
638
639         if (!assembly->save)
640                 return 0;
641
642         sigbuffer_init (&buf, 32);
643         /*
644          * FIXME: vararg, explicit_this, differenc call_conv values...
645          */
646         idx = sig->call_convention;
647         if (sig->hasthis)
648                 idx |= 0x20; /* hasthis */
649         if (sig->generic_param_count)
650                 idx |= 0x10; /* generic */
651         sigbuffer_add_byte (&buf, idx);
652         if (sig->generic_param_count)
653                 sigbuffer_add_value (&buf, sig->generic_param_count);
654         sigbuffer_add_value (&buf, nparams);
655         encode_type (assembly, sig->ret, &buf);
656         for (i = 0; i < nparams; ++i) {
657                 if (i == sig->sentinelpos)
658                         sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
659                 encode_type (assembly, sig->params [i], &buf);
660         }
661         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
662         sigbuffer_free (&buf);
663         return idx;
664 }
665 #endif
666
667 static guint32
668 method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
669 {
670         MONO_REQ_GC_UNSAFE_MODE;
671
672         mono_error_init (error);
673
674         /*
675          * FIXME: reuse code from method_encode_signature().
676          */
677         SigBuffer buf;
678         int i;
679         guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
680         guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
681         guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
682         guint32 idx;
683
684         sigbuffer_init (&buf, 32);
685         /* LAMESPEC: all the call conv spec is foobared */
686         idx = mb->call_conv & 0x60; /* has-this, explicit-this */
687         if (mb->call_conv & 2)
688                 idx |= 0x5; /* vararg */
689         if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
690                 idx |= 0x20; /* hasthis */
691         if (ngparams)
692                 idx |= 0x10; /* generic */
693         sigbuffer_add_byte (&buf, idx);
694         if (ngparams)
695                 sigbuffer_add_value (&buf, ngparams);
696         sigbuffer_add_value (&buf, nparams + notypes);
697         encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
698         if (!is_ok (error))
699                 goto leave;
700         encode_reflection_type (assembly, mb->rtype, &buf, error);
701         if (!is_ok (error))
702                 goto leave;
703         for (i = 0; i < nparams; ++i) {
704                 MonoArray *modreq = NULL;
705                 MonoArray *modopt = NULL;
706                 MonoReflectionType *pt;
707
708                 if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
709                         modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
710                 if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
711                         modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
712                 encode_custom_modifiers (assembly, modreq, modopt, &buf, error);
713                 if (!is_ok (error))
714                         goto leave;
715                 pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
716                 encode_reflection_type (assembly, pt, &buf, error);
717                 if (!is_ok (error))
718                         goto leave;
719         }
720         if (notypes)
721                 sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
722         for (i = 0; i < notypes; ++i) {
723                 MonoReflectionType *pt;
724
725                 pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
726                 encode_reflection_type (assembly, pt, &buf, error);
727                 if (!is_ok (error))
728                         goto leave;
729         }
730
731         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
732 leave:
733         sigbuffer_free (&buf);
734         return idx;
735 }
736
737 static guint32
738 encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
739 {
740         MONO_REQ_GC_UNSAFE_MODE;
741
742         mono_error_init (error);
743
744         MonoDynamicTable *table;
745         guint32 *values;
746         guint32 idx, sig_idx;
747         guint nl = mono_array_length (ilgen->locals);
748         SigBuffer buf;
749         int i;
750
751         sigbuffer_init (&buf, 32);
752         sigbuffer_add_value (&buf, 0x07);
753         sigbuffer_add_value (&buf, nl);
754         for (i = 0; i < nl; ++i) {
755                 MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
756                 
757                 if (lb->is_pinned)
758                         sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
759                 
760                 encode_reflection_type (assembly, (MonoReflectionType*)lb->type, &buf, error);
761                 if (!is_ok (error)) {
762                         sigbuffer_free (&buf);
763                         return 0;
764                 }
765         }
766         sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
767         sigbuffer_free (&buf);
768
769         if (assembly->standalonesig_cache == NULL)
770                 assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
771         idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
772         if (idx)
773                 return idx;
774
775         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
776         idx = table->next_idx ++;
777         table->rows ++;
778         alloc_table (table, table->rows);
779         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
780
781         values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
782
783         g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
784
785         return idx;
786 }
787
788 static guint32
789 method_count_clauses (MonoReflectionILGen *ilgen)
790 {
791         MONO_REQ_GC_UNSAFE_MODE;
792
793         guint32 num_clauses = 0;
794         int i;
795
796         MonoILExceptionInfo *ex_info;
797         for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
798                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
799                 if (ex_info->handlers)
800                         num_clauses += mono_array_length (ex_info->handlers);
801                 else
802                         num_clauses++;
803         }
804
805         return num_clauses;
806 }
807
808 #ifndef DISABLE_REFLECTION_EMIT
809 static MonoExceptionClause*
810 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
811 {
812         MONO_REQ_GC_UNSAFE_MODE;
813
814         mono_error_init (error);
815
816         MonoExceptionClause *clauses;
817         MonoExceptionClause *clause;
818         MonoILExceptionInfo *ex_info;
819         MonoILExceptionBlock *ex_block;
820         guint32 finally_start;
821         int i, j, clause_index;;
822
823         clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
824
825         clause_index = 0;
826         for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
827                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
828                 finally_start = ex_info->start + ex_info->len;
829                 if (!ex_info->handlers)
830                         continue;
831                 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
832                         ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
833                         clause = &(clauses [clause_index]);
834
835                         clause->flags = ex_block->type;
836                         clause->try_offset = ex_info->start;
837
838                         if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
839                                 clause->try_len = finally_start - ex_info->start;
840                         else
841                                 clause->try_len = ex_info->len;
842                         clause->handler_offset = ex_block->start;
843                         clause->handler_len = ex_block->len;
844                         if (ex_block->extype) {
845                                 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
846
847                                 if (!is_ok (error)) {
848                                         image_g_free (image, clauses);
849                                         return NULL;
850                                 }
851                                 clause->data.catch_class = mono_class_from_mono_type (extype);
852                         } else {
853                                 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
854                                         clause->data.filter_offset = ex_block->filter_offset;
855                                 else
856                                         clause->data.filter_offset = 0;
857                         }
858                         finally_start = ex_block->start + ex_block->len;
859
860                         clause_index ++;
861                 }
862         }
863
864         return clauses;
865 }
866 #endif /* !DISABLE_REFLECTION_EMIT */
867
868 /**
869  * method_encode_code:
870  *
871  * @assembly the assembly
872  * @mb the managed MethodBuilder
873  * @error set on error
874  *
875  * Note that the return value is not sensible if @error is set.
876  */
877 static guint32
878 method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
879 {
880         MONO_REQ_GC_UNSAFE_MODE;
881
882         char flags = 0;
883         guint32 idx;
884         guint32 code_size;
885         gint32 max_stack, i;
886         gint32 num_locals = 0;
887         gint32 num_exception = 0;
888         gint maybe_small;
889         guint32 fat_flags;
890         char fat_header [12];
891         guint32 int_value;
892         guint16 short_value;
893         guint32 local_sig = 0;
894         guint32 header_size = 12;
895         MonoArray *code;
896
897         mono_error_init (error);
898
899         if ((mb->attrs & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT)) ||
900                         (mb->iattrs & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)))
901                 return 0;
902
903         /*if (mb->name)
904                 g_print ("Encode method %s\n", mono_string_to_utf8 (mb->name));*/
905         if (mb->ilgen) {
906                 code = mb->ilgen->code;
907                 code_size = mb->ilgen->code_len;
908                 max_stack = mb->ilgen->max_stack;
909                 num_locals = mb->ilgen->locals ? mono_array_length (mb->ilgen->locals) : 0;
910                 if (mb->ilgen->ex_handlers)
911                         num_exception = method_count_clauses (mb->ilgen);
912         } else {
913                 code = mb->code;
914                 if (code == NULL){
915                         MonoError inner_error;
916                         char *name = mono_string_to_utf8_checked (mb->name, &inner_error);
917                         if (!is_ok (&inner_error)) {
918                                 name = g_strdup ("");
919                                 mono_error_cleanup (&inner_error);
920                         }
921                         char *str = g_strdup_printf ("Method %s does not have any IL associated", name);
922                         mono_error_set_argument (error, NULL, "a method does not have any IL associated");
923                         g_free (str);
924                         g_free (name);
925                         return 0;
926                 }
927
928                 code_size = mono_array_length (code);
929                 max_stack = 8; /* we probably need to run a verifier on the code... */
930         }
931
932         stream_data_align (&assembly->code);
933
934         /* check for exceptions, maxstack, locals */
935         maybe_small = (max_stack <= 8) && (!num_locals) && (!num_exception);
936         if (maybe_small) {
937                 if (code_size < 64 && !(code_size & 1)) {
938                         flags = (code_size << 2) | 0x2;
939                 } else if (code_size < 32 && (code_size & 1)) {
940                         flags = (code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
941                 } else {
942                         goto fat_header;
943                 }
944                 idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
945                 /* add to the fixup todo list */
946                 if (mb->ilgen && mb->ilgen->num_token_fixups)
947                         mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 1));
948                 mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
949                 return assembly->text_rva + idx;
950         } 
951 fat_header:
952         if (num_locals) {
953                 local_sig = MONO_TOKEN_SIGNATURE | encode_locals (assembly, mb->ilgen, error);
954                 return_val_if_nok (error, 0);
955         }
956         /* 
957          * FIXME: need to set also the header size in fat_flags.
958          * (and more sects and init locals flags)
959          */
960         fat_flags =  0x03;
961         if (num_exception)
962                 fat_flags |= METHOD_HEADER_MORE_SECTS;
963         if (mb->init_locals)
964                 fat_flags |= METHOD_HEADER_INIT_LOCALS;
965         fat_header [0] = fat_flags;
966         fat_header [1] = (header_size / 4 ) << 4;
967         short_value = GUINT16_TO_LE (max_stack);
968         memcpy (fat_header + 2, &short_value, 2);
969         int_value = GUINT32_TO_LE (code_size);
970         memcpy (fat_header + 4, &int_value, 4);
971         int_value = GUINT32_TO_LE (local_sig);
972         memcpy (fat_header + 8, &int_value, 4);
973         idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
974         /* add to the fixup todo list */
975         if (mb->ilgen && mb->ilgen->num_token_fixups)
976                 mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 12));
977         
978         mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
979         if (num_exception) {
980                 unsigned char sheader [4];
981                 MonoILExceptionInfo * ex_info;
982                 MonoILExceptionBlock * ex_block;
983                 int j;
984
985                 stream_data_align (&assembly->code);
986                 /* always use fat format for now */
987                 sheader [0] = METHOD_HEADER_SECTION_FAT_FORMAT | METHOD_HEADER_SECTION_EHTABLE;
988                 num_exception *= 6 * sizeof (guint32);
989                 num_exception += 4; /* include the size of the header */
990                 sheader [1] = num_exception & 0xff;
991                 sheader [2] = (num_exception >> 8) & 0xff;
992                 sheader [3] = (num_exception >> 16) & 0xff;
993                 mono_image_add_stream_data (&assembly->code, (char*)sheader, 4);
994                 /* fat header, so we are already aligned */
995                 /* reverse order */
996                 for (i = mono_array_length (mb->ilgen->ex_handlers) - 1; i >= 0; --i) {
997                         ex_info = (MonoILExceptionInfo *)mono_array_addr (mb->ilgen->ex_handlers, MonoILExceptionInfo, i);
998                         if (ex_info->handlers) {
999                                 int finally_start = ex_info->start + ex_info->len;
1000                                 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
1001                                         guint32 val;
1002                                         ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
1003                                         /* the flags */
1004                                         val = GUINT32_TO_LE (ex_block->type);
1005                                         mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
1006                                         /* try offset */
1007                                         val = GUINT32_TO_LE (ex_info->start);
1008                                         mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
1009                                         /* need fault, too, probably */
1010                                         if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
1011                                                 val = GUINT32_TO_LE (finally_start - ex_info->start);
1012                                         else
1013                                                 val = GUINT32_TO_LE (ex_info->len);
1014                                         mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
1015                                         /* handler offset */
1016                                         val = GUINT32_TO_LE (ex_block->start);
1017                                         mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
1018                                         /* handler len */
1019                                         val = GUINT32_TO_LE (ex_block->len);
1020                                         mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
1021                                         finally_start = ex_block->start + ex_block->len;
1022                                         if (ex_block->extype) {
1023                                                 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
1024                                                 return_val_if_nok (error, 0);
1025
1026                                                 val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, extype));
1027                                         } else {
1028                                                 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
1029                                                         val = ex_block->filter_offset;
1030                                                 else
1031                                                         val = 0;
1032                                         }
1033                                         val = GUINT32_TO_LE (val);
1034                                         mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
1035                                         /*g_print ("out clause %d: from %d len=%d, handler at %d, %d, finally_start=%d, ex_info->start=%d, ex_info->len=%d, ex_block->type=%d, j=%d, i=%d\n", 
1036                                                         clause.flags, clause.try_offset, clause.try_len, clause.handler_offset, clause.handler_len, finally_start, ex_info->start, ex_info->len, ex_block->type, j, i);*/
1037                                 }
1038                         } else {
1039                                 g_error ("No clauses for ex info block %d", i);
1040                         }
1041                 }
1042         }
1043         return assembly->text_rva + idx;
1044 }
1045
1046 static guint32
1047 find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32 token)
1048 {
1049         MONO_REQ_GC_NEUTRAL_MODE;
1050
1051         int i;
1052         MonoDynamicTable *table;
1053         guint32 *values;
1054         
1055         table = &assembly->tables [table_idx];
1056
1057         g_assert (col < table->columns);
1058
1059         values = table->values + table->columns;
1060         for (i = 1; i <= table->rows; ++i) {
1061                 if (values [col] == token)
1062                         return i;
1063                 values += table->columns;
1064         }
1065         return 0;
1066 }
1067
1068 #ifndef DISABLE_REFLECTION_EMIT
1069 /*
1070  * LOCKING: Acquires the loader lock. 
1071  */
1072 static void
1073 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
1074 {
1075         MONO_REQ_GC_UNSAFE_MODE;
1076
1077         MonoCustomAttrInfo *ainfo, *tmp;
1078
1079         if (!cattrs || !mono_array_length (cattrs))
1080                 return;
1081
1082         ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
1083
1084         mono_loader_lock ();
1085         tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
1086         if (tmp)
1087                 mono_custom_attrs_free (tmp);
1088         mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
1089         mono_loader_unlock ();
1090
1091 }
1092 #endif
1093
1094 /*
1095  * idx is the table index of the object
1096  * type is one of MONO_CUSTOM_ATTR_*
1097  */
1098 static gboolean
1099 mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs, MonoError *error)
1100 {
1101         MONO_REQ_GC_UNSAFE_MODE;
1102
1103         MonoDynamicTable *table;
1104         MonoReflectionCustomAttr *cattr;
1105         guint32 *values;
1106         guint32 count, i, token;
1107         char blob_size [6];
1108         char *p = blob_size;
1109         
1110         mono_error_init (error);
1111
1112         /* it is legal to pass a NULL cattrs: we avoid to use the if in a lot of places */
1113         if (!cattrs)
1114                 return TRUE;
1115         count = mono_array_length (cattrs);
1116         table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
1117         table->rows += count;
1118         alloc_table (table, table->rows);
1119         values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
1120         idx <<= MONO_CUSTOM_ATTR_BITS;
1121         idx |= type;
1122         for (i = 0; i < count; ++i) {
1123                 cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
1124                 values [MONO_CUSTOM_ATTR_PARENT] = idx;
1125                 token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE, error);
1126                 if (!mono_error_ok (error)) goto fail;
1127                 type = mono_metadata_token_index (token);
1128                 type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
1129                 switch (mono_metadata_token_table (token)) {
1130                 case MONO_TABLE_METHOD:
1131                         type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
1132                         /*
1133                          * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the
1134                          * method, not the one returned by mono_image_create_token ().
1135                          */
1136                         mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor);
1137                         break;
1138                 case MONO_TABLE_MEMBERREF:
1139                         type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
1140                         break;
1141                 default:
1142                         g_warning ("got wrong token in custom attr");
1143                         continue;
1144                 }
1145                 values [MONO_CUSTOM_ATTR_TYPE] = type;
1146                 p = blob_size;
1147                 mono_metadata_encode_value (mono_array_length (cattr->data), p, &p);
1148                 values [MONO_CUSTOM_ATTR_VALUE] = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, p - blob_size,
1149                         mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
1150                 values += MONO_CUSTOM_ATTR_SIZE;
1151                 ++table->next_idx;
1152         }
1153
1154         return TRUE;
1155
1156 fail:
1157         return FALSE;
1158 }
1159
1160 static void
1161 mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
1162 {
1163         MONO_REQ_GC_UNSAFE_MODE;
1164
1165         MonoDynamicTable *table;
1166         guint32 *values;
1167         guint32 count, i, idx;
1168         MonoReflectionPermissionSet *perm;
1169
1170         if (!permissions)
1171                 return;
1172
1173         count = mono_array_length (permissions);
1174         table = &assembly->tables [MONO_TABLE_DECLSECURITY];
1175         table->rows += count;
1176         alloc_table (table, table->rows);
1177
1178         for (i = 0; i < mono_array_length (permissions); ++i) {
1179                 perm = (MonoReflectionPermissionSet*)mono_array_addr (permissions, MonoReflectionPermissionSet, i);
1180
1181                 values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE;
1182
1183                 idx = mono_metadata_token_index (parent_token);
1184                 idx <<= MONO_HAS_DECL_SECURITY_BITS;
1185                 switch (mono_metadata_token_table (parent_token)) {
1186                 case MONO_TABLE_TYPEDEF:
1187                         idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
1188                         break;
1189                 case MONO_TABLE_METHOD:
1190                         idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
1191                         break;
1192                 case MONO_TABLE_ASSEMBLY:
1193                         idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
1194                         break;
1195                 default:
1196                         g_assert_not_reached ();
1197                 }
1198
1199                 values [MONO_DECL_SECURITY_ACTION] = perm->action;
1200                 values [MONO_DECL_SECURITY_PARENT] = idx;
1201                 values [MONO_DECL_SECURITY_PERMISSIONSET] = add_mono_string_to_blob_cached (assembly, perm->pset);
1202
1203                 ++table->next_idx;
1204         }
1205 }
1206
1207 /*
1208  * Fill in the MethodDef and ParamDef tables for a method.
1209  * This is used for both normal methods and constructors.
1210  */
1211 static gboolean
1212 mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
1213 {
1214         MONO_REQ_GC_UNSAFE_MODE;
1215
1216         MonoDynamicTable *table;
1217         guint32 *values;
1218         guint i, count;
1219
1220         mono_error_init (error);
1221
1222         /* room in this table is already allocated */
1223         table = &assembly->tables [MONO_TABLE_METHOD];
1224         *mb->table_idx = table->next_idx ++;
1225         g_hash_table_insert (assembly->method_to_table_idx, mb->mhandle, GUINT_TO_POINTER ((*mb->table_idx)));
1226         values = table->values + *mb->table_idx * MONO_METHOD_SIZE;
1227         values [MONO_METHOD_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name, error);
1228         return_val_if_nok (error, FALSE);
1229         values [MONO_METHOD_FLAGS] = mb->attrs;
1230         values [MONO_METHOD_IMPLFLAGS] = mb->iattrs;
1231         values [MONO_METHOD_SIGNATURE] = method_builder_encode_signature (assembly, mb, error);
1232         return_val_if_nok (error, FALSE);
1233         values [MONO_METHOD_RVA] = method_encode_code (assembly, mb, error);
1234         return_val_if_nok (error, FALSE);
1235
1236         table = &assembly->tables [MONO_TABLE_PARAM];
1237         values [MONO_METHOD_PARAMLIST] = table->next_idx;
1238
1239         mono_image_add_decl_security (assembly, 
1240                 mono_metadata_make_token (MONO_TABLE_METHOD, *mb->table_idx), mb->permissions);
1241
1242         if (mb->pinfo) {
1243                 MonoDynamicTable *mtable;
1244                 guint32 *mvalues;
1245                 
1246                 mtable = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
1247                 mvalues = mtable->values + mtable->next_idx * MONO_FIELD_MARSHAL_SIZE;
1248                 
1249                 count = 0;
1250                 for (i = 0; i < mono_array_length (mb->pinfo); ++i) {
1251                         if (mono_array_get (mb->pinfo, gpointer, i))
1252                                 count++;
1253                 }
1254                 table->rows += count;
1255                 alloc_table (table, table->rows);
1256                 values = table->values + table->next_idx * MONO_PARAM_SIZE;
1257                 for (i = 0; i < mono_array_length (mb->pinfo); ++i) {
1258                         MonoReflectionParamBuilder *pb;
1259                         if ((pb = mono_array_get (mb->pinfo, MonoReflectionParamBuilder*, i))) {
1260                                 values [MONO_PARAM_FLAGS] = pb->attrs;
1261                                 values [MONO_PARAM_SEQUENCE] = i;
1262                                 if (pb->name != NULL) {
1263                                         values [MONO_PARAM_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name, error);
1264                                         return_val_if_nok (error, FALSE);
1265                                 } else {
1266                                         values [MONO_PARAM_NAME] = 0;
1267                                 }
1268                                 values += MONO_PARAM_SIZE;
1269                                 if (pb->marshal_info) {
1270                                         mtable->rows++;
1271                                         alloc_table (mtable, mtable->rows);
1272                                         mvalues = mtable->values + mtable->rows * MONO_FIELD_MARSHAL_SIZE;
1273                                         mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_PARAMDEF;
1274                                         mvalues [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, pb->marshal_info, error);
1275                                         return_val_if_nok (error, FALSE);
1276                                 }
1277                                 pb->table_idx = table->next_idx++;
1278                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
1279                                         guint32 field_type = 0;
1280                                         mtable = &assembly->tables [MONO_TABLE_CONSTANT];
1281                                         mtable->rows ++;
1282                                         alloc_table (mtable, mtable->rows);
1283                                         mvalues = mtable->values + mtable->rows * MONO_CONSTANT_SIZE;
1284                                         mvalues [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PARAM | (pb->table_idx << MONO_HASCONSTANT_BITS);
1285                                         mvalues [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
1286                                         mvalues [MONO_CONSTANT_TYPE] = field_type;
1287                                         mvalues [MONO_CONSTANT_PADDING] = 0;
1288                                 }
1289                         }
1290                 }
1291         }
1292
1293         return TRUE;
1294 }
1295
1296 #ifndef DISABLE_REFLECTION_EMIT
1297 static gboolean
1298 reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
1299 {
1300         MONO_REQ_GC_UNSAFE_MODE;
1301
1302         mono_error_init (error);
1303         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
1304
1305         rmb->ilgen = mb->ilgen;
1306         rmb->rtype = mono_reflection_type_resolve_user_types ((MonoReflectionType*)mb->rtype, error);
1307         return_val_if_nok (error, FALSE);
1308         rmb->parameters = mb->parameters;
1309         rmb->generic_params = mb->generic_params;
1310         rmb->generic_container = mb->generic_container;
1311         rmb->opt_types = NULL;
1312         rmb->pinfo = mb->pinfo;
1313         rmb->attrs = mb->attrs;
1314         rmb->iattrs = mb->iattrs;
1315         rmb->call_conv = mb->call_conv;
1316         rmb->code = mb->code;
1317         rmb->type = mb->type;
1318         rmb->name = mb->name;
1319         rmb->table_idx = &mb->table_idx;
1320         rmb->init_locals = mb->init_locals;
1321         rmb->skip_visibility = FALSE;
1322         rmb->return_modreq = mb->return_modreq;
1323         rmb->return_modopt = mb->return_modopt;
1324         rmb->param_modreq = mb->param_modreq;
1325         rmb->param_modopt = mb->param_modopt;
1326         rmb->permissions = mb->permissions;
1327         rmb->mhandle = mb->mhandle;
1328         rmb->nrefs = 0;
1329         rmb->refs = NULL;
1330
1331         if (mb->dll) {
1332                 rmb->charset = mb->charset;
1333                 rmb->extra_flags = mb->extra_flags;
1334                 rmb->native_cc = mb->native_cc;
1335                 rmb->dllentry = mb->dllentry;
1336                 rmb->dll = mb->dll;
1337         }
1338
1339         return TRUE;
1340 }
1341
1342 static gboolean
1343 reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
1344 {
1345         MONO_REQ_GC_UNSAFE_MODE;
1346
1347         const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
1348
1349         mono_error_init (error);
1350
1351         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
1352
1353         rmb->ilgen = mb->ilgen;
1354         rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
1355         return_val_if_nok (error, FALSE);
1356         rmb->parameters = mb->parameters;
1357         rmb->generic_params = NULL;
1358         rmb->generic_container = NULL;
1359         rmb->opt_types = NULL;
1360         rmb->pinfo = mb->pinfo;
1361         rmb->attrs = mb->attrs;
1362         rmb->iattrs = mb->iattrs;
1363         rmb->call_conv = mb->call_conv;
1364         rmb->code = NULL;
1365         rmb->type = mb->type;
1366         rmb->name = mono_string_new (mono_domain_get (), name);
1367         rmb->table_idx = &mb->table_idx;
1368         rmb->init_locals = mb->init_locals;
1369         rmb->skip_visibility = FALSE;
1370         rmb->return_modreq = NULL;
1371         rmb->return_modopt = NULL;
1372         rmb->param_modreq = mb->param_modreq;
1373         rmb->param_modopt = mb->param_modopt;
1374         rmb->permissions = mb->permissions;
1375         rmb->mhandle = mb->mhandle;
1376         rmb->nrefs = 0;
1377         rmb->refs = NULL;
1378
1379         return TRUE;
1380 }
1381
1382 static void
1383 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
1384 {
1385         MONO_REQ_GC_UNSAFE_MODE;
1386
1387         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
1388
1389         rmb->ilgen = mb->ilgen;
1390         rmb->rtype = mb->rtype;
1391         rmb->parameters = mb->parameters;
1392         rmb->generic_params = NULL;
1393         rmb->generic_container = NULL;
1394         rmb->opt_types = NULL;
1395         rmb->pinfo = NULL;
1396         rmb->attrs = mb->attrs;
1397         rmb->iattrs = 0;
1398         rmb->call_conv = mb->call_conv;
1399         rmb->code = NULL;
1400         rmb->type = (MonoObject *) mb->owner;
1401         rmb->name = mb->name;
1402         rmb->table_idx = NULL;
1403         rmb->init_locals = mb->init_locals;
1404         rmb->skip_visibility = mb->skip_visibility;
1405         rmb->return_modreq = NULL;
1406         rmb->return_modopt = NULL;
1407         rmb->param_modreq = NULL;
1408         rmb->param_modopt = NULL;
1409         rmb->permissions = NULL;
1410         rmb->mhandle = mb->mhandle;
1411         rmb->nrefs = 0;
1412         rmb->refs = NULL;
1413 }       
1414 #endif
1415
1416 static gboolean
1417 mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
1418 {
1419         MONO_REQ_GC_UNSAFE_MODE;
1420
1421         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
1422         MonoDynamicTable *table;
1423         guint32 *values;
1424         guint32 tok;
1425         MonoReflectionMethod *m;
1426         int i;
1427
1428         mono_error_init (error);
1429
1430         if (!mb->override_methods)
1431                 return TRUE;
1432
1433         for (i = 0; i < mono_array_length (mb->override_methods); ++i) {
1434                 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i);
1435
1436                 table = &assembly->tables [MONO_TABLE_METHODIMPL];
1437                 table->rows ++;
1438                 alloc_table (table, table->rows);
1439                 values = table->values + table->rows * MONO_METHODIMPL_SIZE;
1440                 values [MONO_METHODIMPL_CLASS] = tb->table_idx;
1441                 values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
1442
1443                 tok = mono_image_create_token (assembly, (MonoObject*)m, FALSE, FALSE, error);
1444                 return_val_if_nok (error, FALSE);
1445
1446                 switch (mono_metadata_token_table (tok)) {
1447                 case MONO_TABLE_MEMBERREF:
1448                         tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
1449                         break;
1450                 case MONO_TABLE_METHOD:
1451                         tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
1452                         break;
1453                 default:
1454                         g_assert_not_reached ();
1455                 }
1456                 values [MONO_METHODIMPL_DECLARATION] = tok;
1457         }
1458
1459         return TRUE;
1460 }
1461
1462 #ifndef DISABLE_REFLECTION_EMIT
1463 static gboolean
1464 mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
1465 {
1466         MONO_REQ_GC_UNSAFE_MODE;
1467
1468         MonoDynamicTable *table;
1469         guint32 *values;
1470         ReflectionMethodBuilder rmb;
1471         int i;
1472
1473         mono_error_init (error);
1474
1475         if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error) ||
1476             !mono_image_basic_method (&rmb, assembly, error))
1477                 return FALSE;
1478
1479         mb->table_idx = *rmb.table_idx;
1480
1481         if (mb->dll) { /* It's a P/Invoke method */
1482                 guint32 moduleref;
1483                 /* map CharSet values to on-disk values */
1484                 int ncharset = (mb->charset ? (mb->charset - 1) * 2 : 0);
1485                 int extra_flags = mb->extra_flags;
1486                 table = &assembly->tables [MONO_TABLE_IMPLMAP];
1487                 table->rows ++;
1488                 alloc_table (table, table->rows);
1489                 values = table->values + table->rows * MONO_IMPLMAP_SIZE;
1490                 
1491                 values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | ncharset | extra_flags;
1492                 values [MONO_IMPLMAP_MEMBER] = (mb->table_idx << 1) | 1; /* memberforwarded: method */
1493                 if (mb->dllentry) {
1494                         values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->dllentry, error);
1495                         return_val_if_nok (error, FALSE);
1496                 } else {
1497                         values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name, error);
1498                         return_val_if_nok (error, FALSE);
1499                 }
1500                 moduleref = string_heap_insert_mstring (&assembly->sheap, mb->dll, error);
1501                 return_val_if_nok (error, FALSE);
1502                 if (!(values [MONO_IMPLMAP_SCOPE] = find_index_in_table (assembly, MONO_TABLE_MODULEREF, MONO_MODULEREF_NAME, moduleref))) {
1503                         table = &assembly->tables [MONO_TABLE_MODULEREF];
1504                         table->rows ++;
1505                         alloc_table (table, table->rows);
1506                         table->values [table->rows * MONO_MODULEREF_SIZE + MONO_MODULEREF_NAME] = moduleref;
1507                         values [MONO_IMPLMAP_SCOPE] = table->rows;
1508                 }
1509         }
1510
1511         if (mb->generic_params) {
1512                 table = &assembly->tables [MONO_TABLE_GENERICPARAM];
1513                 table->rows += mono_array_length (mb->generic_params);
1514                 alloc_table (table, table->rows);
1515                 for (i = 0; i < mono_array_length (mb->generic_params); ++i) {
1516                         guint32 owner = MONO_TYPEORMETHOD_METHOD | (mb->table_idx << MONO_TYPEORMETHOD_BITS);
1517
1518                         mono_image_get_generic_param_info (
1519                                 (MonoReflectionGenericParam *)mono_array_get (mb->generic_params, gpointer, i), owner, assembly);
1520                 }
1521         }
1522
1523         return TRUE;
1524 }
1525
1526 static gboolean
1527 mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
1528 {
1529         MONO_REQ_GC_UNSAFE_MODE;
1530
1531         ReflectionMethodBuilder rmb;
1532
1533         if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
1534                 return FALSE;
1535
1536         if (!mono_image_basic_method (&rmb, assembly, error))
1537                 return FALSE;
1538
1539         mb->table_idx = *rmb.table_idx;
1540
1541         return TRUE;
1542 }
1543 #endif
1544
1545 static char*
1546 type_get_fully_qualified_name (MonoType *type)
1547 {
1548         MONO_REQ_GC_NEUTRAL_MODE;
1549
1550         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1551 }
1552
1553 static char*
1554 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
1555 {
1556         MONO_REQ_GC_UNSAFE_MODE;
1557
1558         MonoClass *klass;
1559         MonoAssembly *ta;
1560
1561         klass = mono_class_from_mono_type (type);
1562         if (!klass) 
1563                 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
1564         ta = klass->image->assembly;
1565         if (assembly_is_dynamic (ta) || (ta == ass)) {
1566                 if (klass->generic_class || klass->generic_container)
1567                         /* For generic type definitions, we want T, while REFLECTION returns T<K> */
1568                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
1569                 else
1570                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
1571         }
1572
1573         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1574 }
1575
1576 #ifndef DISABLE_REFLECTION_EMIT
1577 /*field_image is the image to which the eventual custom mods have been encoded against*/
1578 static guint32
1579 fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
1580 {
1581         MONO_REQ_GC_NEUTRAL_MODE;
1582
1583         SigBuffer buf;
1584         guint32 idx, i, token;
1585
1586         if (!assembly->save)
1587                 return 0;
1588
1589         sigbuffer_init (&buf, 32);
1590         
1591         sigbuffer_add_value (&buf, 0x06);
1592         /* encode custom attributes before the type */
1593         if (type->num_mods) {
1594                 for (i = 0; i < type->num_mods; ++i) {
1595                         if (field_image) {
1596                                 MonoError error;
1597                                 MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
1598                                 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
1599
1600                                 token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
1601                         } else {
1602                                 token = type->modifiers [i].token;
1603                         }
1604
1605                         if (type->modifiers [i].required)
1606                                 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
1607                         else
1608                                 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
1609
1610                         sigbuffer_add_value (&buf, token);
1611                 }
1612         }
1613         encode_type (assembly, type, &buf);
1614         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1615         sigbuffer_free (&buf);
1616         return idx;
1617 }
1618 #endif
1619
1620 static guint32
1621 field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
1622 {
1623         MONO_REQ_GC_UNSAFE_MODE;
1624
1625         mono_error_init (error);
1626
1627         SigBuffer buf;
1628         guint32 idx;
1629         guint32 typespec = 0;
1630         MonoType *type;
1631         MonoClass *klass;
1632
1633         init_type_builder_generics (fb->type, error);
1634         return_val_if_nok (error, 0);
1635
1636         type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1637         return_val_if_nok (error, 0);
1638         klass = mono_class_from_mono_type (type);
1639
1640         sigbuffer_init (&buf, 32);
1641         
1642         sigbuffer_add_value (&buf, 0x06);
1643         encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf, error);
1644         if (!is_ok (error))
1645                 goto fail;
1646         /* encode custom attributes before the type */
1647
1648         if (klass->generic_container)
1649                 typespec = create_typespec (assembly, type);
1650
1651         if (typespec) {
1652                 MonoGenericClass *gclass;
1653                 gclass = mono_metadata_lookup_generic_class (klass, klass->generic_container->context.class_inst, TRUE);
1654                 encode_generic_class (assembly, gclass, &buf);
1655         } else {
1656                 encode_type (assembly, type, &buf);
1657         }
1658         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1659         sigbuffer_free (&buf);
1660         return idx;
1661 fail:
1662         sigbuffer_free (&buf);
1663         return 0;
1664 }
1665
1666 static guint32
1667 encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
1668 {
1669         MONO_REQ_GC_UNSAFE_MODE;
1670
1671         char blob_size [64];
1672         char *b = blob_size;
1673         char *box_val;
1674         char* buf;
1675         guint32 idx = 0, len = 0, dummy = 0;
1676
1677         buf = (char *)g_malloc (64);
1678         if (!val) {
1679                 *ret_type = MONO_TYPE_CLASS;
1680                 len = 4;
1681                 box_val = (char*)&dummy;
1682         } else {
1683                 box_val = ((char*)val) + sizeof (MonoObject);
1684                 *ret_type = val->vtable->klass->byval_arg.type;
1685         }
1686 handle_enum:
1687         switch (*ret_type) {
1688         case MONO_TYPE_BOOLEAN:
1689         case MONO_TYPE_U1:
1690         case MONO_TYPE_I1:
1691                 len = 1;
1692                 break;
1693         case MONO_TYPE_CHAR:
1694         case MONO_TYPE_U2:
1695         case MONO_TYPE_I2:
1696                 len = 2;
1697                 break;
1698         case MONO_TYPE_U4:
1699         case MONO_TYPE_I4:
1700         case MONO_TYPE_R4:
1701                 len = 4;
1702                 break;
1703         case MONO_TYPE_U8:
1704         case MONO_TYPE_I8:
1705                 len = 8;
1706                 break;
1707         case MONO_TYPE_R8:
1708                 len = 8;
1709                 break;
1710         case MONO_TYPE_VALUETYPE: {
1711                 MonoClass *klass = val->vtable->klass;
1712                 
1713                 if (klass->enumtype) {
1714                         *ret_type = mono_class_enum_basetype (klass)->type;
1715                         goto handle_enum;
1716                 } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
1717                         len = 8;
1718                 } else 
1719                         g_error ("we can't encode valuetypes, we should have never reached this line");
1720                 break;
1721         }
1722         case MONO_TYPE_CLASS:
1723                 break;
1724         case MONO_TYPE_STRING: {
1725                 MonoString *str = (MonoString*)val;
1726                 /* there is no signature */
1727                 len = str->length * 2;
1728                 mono_metadata_encode_value (len, b, &b);
1729 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1730                 {
1731                         char *swapped = g_malloc (2 * mono_string_length (str));
1732                         const char *p = (const char*)mono_string_chars (str);
1733
1734                         swap_with_size (swapped, p, 2, mono_string_length (str));
1735                         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
1736                         g_free (swapped);
1737                 }
1738 #else
1739                 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
1740 #endif
1741
1742                 g_free (buf);
1743                 return idx;
1744         }
1745         case MONO_TYPE_GENERICINST:
1746                 *ret_type = val->vtable->klass->generic_class->container_class->byval_arg.type;
1747                 goto handle_enum;
1748         default:
1749                 g_error ("we don't encode constant type 0x%02x yet", *ret_type);
1750         }
1751
1752         /* there is no signature */
1753         mono_metadata_encode_value (len, b, &b);
1754 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1755         idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
1756         swap_with_size (blob_size, box_val, len, 1);
1757         mono_image_add_stream_data (&assembly->blob, blob_size, len);
1758 #else
1759         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
1760 #endif
1761
1762         g_free (buf);
1763         return idx;
1764 }
1765
1766 static guint32
1767 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1768 {
1769         MONO_REQ_GC_UNSAFE_MODE;
1770
1771         mono_error_init (error);
1772
1773         char *str;
1774         SigBuffer buf;
1775         guint32 idx, len;
1776
1777         sigbuffer_init (&buf, 32);
1778
1779         sigbuffer_add_value (&buf, minfo->type);
1780
1781         switch (minfo->type) {
1782         case MONO_NATIVE_BYVALTSTR:
1783         case MONO_NATIVE_BYVALARRAY:
1784                 sigbuffer_add_value (&buf, minfo->count);
1785                 break;
1786         case MONO_NATIVE_LPARRAY:
1787                 if (minfo->eltype || minfo->has_size) {
1788                         sigbuffer_add_value (&buf, minfo->eltype);
1789                         if (minfo->has_size) {
1790                                 sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
1791                                 sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
1792
1793                                 /* LAMESPEC: ElemMult is undocumented */
1794                                 sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
1795                         }
1796                 }
1797                 break;
1798         case MONO_NATIVE_SAFEARRAY:
1799                 if (minfo->eltype)
1800                         sigbuffer_add_value (&buf, minfo->eltype);
1801                 break;
1802         case MONO_NATIVE_CUSTOM:
1803                 if (minfo->guid) {
1804                         str = mono_string_to_utf8_checked (minfo->guid, error);
1805                         if (!is_ok (error)) {
1806                                 sigbuffer_free (&buf);
1807                                 return 0;
1808                         }
1809                         len = strlen (str);
1810                         sigbuffer_add_value (&buf, len);
1811                         sigbuffer_add_mem (&buf, str, len);
1812                         g_free (str);
1813                 } else {
1814                         sigbuffer_add_value (&buf, 0);
1815                 }
1816                 /* native type name */
1817                 sigbuffer_add_value (&buf, 0);
1818                 /* custom marshaler type name */
1819                 if (minfo->marshaltype || minfo->marshaltyperef) {
1820                         if (minfo->marshaltyperef) {
1821                                 MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
1822                                 if (!is_ok (error)) {
1823                                         sigbuffer_free (&buf);
1824                                         return 0;
1825                                 }
1826                                 str = type_get_fully_qualified_name (marshaltype);
1827                         } else {
1828                                 str = mono_string_to_utf8_checked (minfo->marshaltype, error);
1829                                 if (!is_ok (error)) {
1830                                         sigbuffer_free (&buf);
1831                                         return 0;
1832                                 }
1833                         }
1834                         len = strlen (str);
1835                         sigbuffer_add_value (&buf, len);
1836                         sigbuffer_add_mem (&buf, str, len);
1837                         g_free (str);
1838                 } else {
1839                         /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
1840                         sigbuffer_add_value (&buf, 0);
1841                 }
1842                 if (minfo->mcookie) {
1843                         str = mono_string_to_utf8_checked (minfo->mcookie, error);
1844                         if (!is_ok (error)) {
1845                                 sigbuffer_free (&buf);
1846                                 return 0;
1847                         }
1848                         len = strlen (str);
1849                         sigbuffer_add_value (&buf, len);
1850                         sigbuffer_add_mem (&buf, str, len);
1851                         g_free (str);
1852                 } else {
1853                         sigbuffer_add_value (&buf, 0);
1854                 }
1855                 break;
1856         default:
1857                 break;
1858         }
1859         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1860         sigbuffer_free (&buf);
1861         return idx;
1862 }
1863
1864 static void
1865 mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *assembly, MonoError *error)
1866 {
1867         MONO_REQ_GC_UNSAFE_MODE;
1868
1869         mono_error_init (error);
1870
1871         MonoDynamicTable *table;
1872         guint32 *values;
1873
1874         /* maybe this fixup should be done in the C# code */
1875         if (fb->attrs & FIELD_ATTRIBUTE_LITERAL)
1876                 fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
1877         table = &assembly->tables [MONO_TABLE_FIELD];
1878         fb->table_idx = table->next_idx ++;
1879         g_hash_table_insert (assembly->field_to_table_idx, fb->handle, GUINT_TO_POINTER (fb->table_idx));
1880         values = table->values + fb->table_idx * MONO_FIELD_SIZE;
1881         values [MONO_FIELD_NAME] = string_heap_insert_mstring (&assembly->sheap, fb->name, error);
1882         return_if_nok (error);
1883         values [MONO_FIELD_FLAGS] = fb->attrs;
1884         values [MONO_FIELD_SIGNATURE] = field_encode_signature (assembly, fb, error);
1885         return_if_nok (error);
1886
1887
1888         if (fb->offset != -1) {
1889                 table = &assembly->tables [MONO_TABLE_FIELDLAYOUT];
1890                 table->rows ++;
1891                 alloc_table (table, table->rows);
1892                 values = table->values + table->rows * MONO_FIELD_LAYOUT_SIZE;
1893                 values [MONO_FIELD_LAYOUT_FIELD] = fb->table_idx;
1894                 values [MONO_FIELD_LAYOUT_OFFSET] = fb->offset;
1895         }
1896         if (fb->attrs & FIELD_ATTRIBUTE_LITERAL) {
1897                 MonoTypeEnum field_type = (MonoTypeEnum)0;
1898                 table = &assembly->tables [MONO_TABLE_CONSTANT];
1899                 table->rows ++;
1900                 alloc_table (table, table->rows);
1901                 values = table->values + table->rows * MONO_CONSTANT_SIZE;
1902                 values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_FIEDDEF | (fb->table_idx << MONO_HASCONSTANT_BITS);
1903                 values [MONO_CONSTANT_VALUE] = encode_constant (assembly, fb->def_value, &field_type);
1904                 values [MONO_CONSTANT_TYPE] = field_type;
1905                 values [MONO_CONSTANT_PADDING] = 0;
1906         }
1907         if (fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
1908                 guint32 rva_idx;
1909                 table = &assembly->tables [MONO_TABLE_FIELDRVA];
1910                 table->rows ++;
1911                 alloc_table (table, table->rows);
1912                 values = table->values + table->rows * MONO_FIELD_RVA_SIZE;
1913                 values [MONO_FIELD_RVA_FIELD] = fb->table_idx;
1914                 /*
1915                  * We store it in the code section because it's simpler for now.
1916                  */
1917                 if (fb->rva_data) {
1918                         if (mono_array_length (fb->rva_data) >= 10)
1919                                 stream_data_align (&assembly->code);
1920                         rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
1921                 } else
1922                         rva_idx = mono_image_add_stream_zero (&assembly->code, mono_class_value_size (fb->handle->parent, NULL));
1923                 values [MONO_FIELD_RVA_RVA] = rva_idx + assembly->text_rva;
1924         }
1925         if (fb->marshal_info) {
1926                 table = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
1927                 table->rows ++;
1928                 alloc_table (table, table->rows);
1929                 values = table->values + table->rows * MONO_FIELD_MARSHAL_SIZE;
1930                 values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_FIELDSREF;
1931                 values [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, fb->marshal_info, error);
1932                 return_if_nok (error);
1933         }
1934 }
1935
1936 static guint32
1937 property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1938 {
1939         MONO_REQ_GC_UNSAFE_MODE;
1940
1941         mono_error_init (error);
1942
1943         SigBuffer buf;
1944         guint32 nparams = 0;
1945         MonoReflectionMethodBuilder *mb = fb->get_method;
1946         MonoReflectionMethodBuilder *smb = fb->set_method;
1947         guint32 idx, i;
1948
1949         if (mb && mb->parameters)
1950                 nparams = mono_array_length (mb->parameters);
1951         if (!mb && smb && smb->parameters)
1952                 nparams = mono_array_length (smb->parameters) - 1;
1953         sigbuffer_init (&buf, 32);
1954         if (fb->call_conv & 0x20)
1955                 sigbuffer_add_byte (&buf, 0x28);
1956         else
1957                 sigbuffer_add_byte (&buf, 0x08);
1958         sigbuffer_add_value (&buf, nparams);
1959         if (mb) {
1960                 encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
1961                 if (!is_ok (error))
1962                         goto fail;
1963                 for (i = 0; i < nparams; ++i) {
1964                         MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
1965                         encode_reflection_type (assembly, pt, &buf, error);
1966                         if (!is_ok (error))
1967                                 goto fail;
1968                 }
1969         } else if (smb && smb->parameters) {
1970                 /* the property type is the last param */
1971                 encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
1972                 if (!is_ok (error))
1973                         goto fail;
1974
1975                 for (i = 0; i < nparams; ++i) {
1976                         MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
1977                         encode_reflection_type (assembly, pt, &buf, error);
1978                         if (!is_ok (error))
1979                                 goto fail;
1980                 }
1981         } else {
1982                 encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf, error);
1983                 if (!is_ok (error))
1984                         goto fail;
1985         }
1986
1987         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1988         sigbuffer_free (&buf);
1989         return idx;
1990 fail:
1991         sigbuffer_free (&buf);
1992         return 0;
1993 }
1994
1995 static void
1996 mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImage *assembly, MonoError *error)
1997 {
1998         MONO_REQ_GC_UNSAFE_MODE;
1999
2000         mono_error_init (error);
2001
2002         MonoDynamicTable *table;
2003         guint32 *values;
2004         guint num_methods = 0;
2005         guint32 semaidx;
2006
2007         /* 
2008          * we need to set things in the following tables:
2009          * PROPERTYMAP (info already filled in _get_type_info ())
2010          * PROPERTY    (rows already preallocated in _get_type_info ())
2011          * METHOD      (method info already done with the generic method code)
2012          * METHODSEMANTICS
2013          * CONSTANT
2014          */
2015         table = &assembly->tables [MONO_TABLE_PROPERTY];
2016         pb->table_idx = table->next_idx ++;
2017         values = table->values + pb->table_idx * MONO_PROPERTY_SIZE;
2018         values [MONO_PROPERTY_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name, error);
2019         return_if_nok (error);
2020         values [MONO_PROPERTY_FLAGS] = pb->attrs;
2021         values [MONO_PROPERTY_TYPE] = property_encode_signature (assembly, pb, error);
2022         return_if_nok (error);
2023
2024
2025         /* FIXME: we still don't handle 'other' methods */
2026         if (pb->get_method) num_methods ++;
2027         if (pb->set_method) num_methods ++;
2028
2029         table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
2030         table->rows += num_methods;
2031         alloc_table (table, table->rows);
2032
2033         if (pb->get_method) {
2034                 semaidx = table->next_idx ++;
2035                 values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
2036                 values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
2037                 values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
2038                 values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
2039         }
2040         if (pb->set_method) {
2041                 semaidx = table->next_idx ++;
2042                 values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
2043                 values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
2044                 values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
2045                 values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
2046         }
2047         if (pb->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT) {
2048                 MonoTypeEnum field_type = (MonoTypeEnum)0;
2049                 table = &assembly->tables [MONO_TABLE_CONSTANT];
2050                 table->rows ++;
2051                 alloc_table (table, table->rows);
2052                 values = table->values + table->rows * MONO_CONSTANT_SIZE;
2053                 values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PROPERTY | (pb->table_idx << MONO_HASCONSTANT_BITS);
2054                 values [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
2055                 values [MONO_CONSTANT_TYPE] = field_type;
2056                 values [MONO_CONSTANT_PADDING] = 0;
2057         }
2058 }
2059
2060 static void
2061 mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *assembly, MonoError *error)
2062 {
2063         MONO_REQ_GC_UNSAFE_MODE;
2064
2065         MonoDynamicTable *table;
2066         guint32 *values;
2067         guint num_methods = 0;
2068         guint32 semaidx;
2069
2070         /* 
2071          * we need to set things in the following tables:
2072          * EVENTMAP (info already filled in _get_type_info ())
2073          * EVENT    (rows already preallocated in _get_type_info ())
2074          * METHOD      (method info already done with the generic method code)
2075          * METHODSEMANTICS
2076          */
2077         table = &assembly->tables [MONO_TABLE_EVENT];
2078         eb->table_idx = table->next_idx ++;
2079         values = table->values + eb->table_idx * MONO_EVENT_SIZE;
2080         values [MONO_EVENT_NAME] = string_heap_insert_mstring (&assembly->sheap, eb->name, error);
2081         return_if_nok (error);
2082         values [MONO_EVENT_FLAGS] = eb->attrs;
2083         MonoType *ebtype = mono_reflection_type_get_handle (eb->type, error);
2084         return_if_nok (error);
2085         values [MONO_EVENT_TYPE] = mono_image_typedef_or_ref (assembly, ebtype);
2086
2087         /*
2088          * FIXME: we still don't handle 'other' methods 
2089          */
2090         if (eb->add_method) num_methods ++;
2091         if (eb->remove_method) num_methods ++;
2092         if (eb->raise_method) num_methods ++;
2093
2094         table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
2095         table->rows += num_methods;
2096         alloc_table (table, table->rows);
2097
2098         if (eb->add_method) {
2099                 semaidx = table->next_idx ++;
2100                 values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
2101                 values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_ADD_ON;
2102                 values [MONO_METHOD_SEMA_METHOD] = eb->add_method->table_idx;
2103                 values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
2104         }
2105         if (eb->remove_method) {
2106                 semaidx = table->next_idx ++;
2107                 values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
2108                 values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_REMOVE_ON;
2109                 values [MONO_METHOD_SEMA_METHOD] = eb->remove_method->table_idx;
2110                 values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
2111         }
2112         if (eb->raise_method) {
2113                 semaidx = table->next_idx ++;
2114                 values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
2115                 values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_FIRE;
2116                 values [MONO_METHOD_SEMA_METHOD] = eb->raise_method->table_idx;
2117                 values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
2118         }
2119 }
2120
2121 static void
2122 encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly, MonoError *error)
2123 {
2124         MONO_REQ_GC_UNSAFE_MODE;
2125
2126         mono_error_init (error);
2127
2128         MonoDynamicTable *table;
2129         guint32 num_constraints, i;
2130         guint32 *values;
2131         guint32 table_idx;
2132
2133         table = &assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
2134         num_constraints = gparam->iface_constraints ?
2135                 mono_array_length (gparam->iface_constraints) : 0;
2136         table->rows += num_constraints;
2137         if (gparam->base_type)
2138                 table->rows++;
2139         alloc_table (table, table->rows);
2140
2141         if (gparam->base_type) {
2142                 table_idx = table->next_idx ++;
2143                 values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
2144
2145                 MonoType *gpbasetype = mono_reflection_type_get_handle (gparam->base_type, error);
2146                 return_if_nok (error);
2147                 values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
2148                 values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, gpbasetype);
2149         }
2150
2151         for (i = 0; i < num_constraints; i++) {
2152                 MonoReflectionType *constraint = (MonoReflectionType *)mono_array_get (
2153                         gparam->iface_constraints, gpointer, i);
2154
2155                 table_idx = table->next_idx ++;
2156                 values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
2157
2158                 MonoType *constraint_type = mono_reflection_type_get_handle (constraint, error);
2159                 return_if_nok (error);
2160
2161                 values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
2162                 values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, constraint_type);
2163         }
2164 }
2165
2166 static void
2167 mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
2168 {
2169         MONO_REQ_GC_UNSAFE_MODE;
2170
2171         GenericParamTableEntry *entry;
2172
2173         /*
2174          * The GenericParam table must be sorted according to the `owner' field.
2175          * We need to do this sorting prior to writing the GenericParamConstraint
2176          * table, since we have to use the final GenericParam table indices there
2177          * and they must also be sorted.
2178          */
2179
2180         entry = g_new0 (GenericParamTableEntry, 1);
2181         entry->owner = owner;
2182         /* FIXME: track where gen_params should be freed and remove the GC root as well */
2183         MONO_GC_REGISTER_ROOT_IF_MOVING (entry->gparam, MONO_ROOT_SOURCE_REFLECTION, "reflection generic parameter");
2184         entry->gparam = gparam;
2185         
2186         g_ptr_array_add (assembly->gen_params, entry);
2187 }
2188
2189 static gboolean
2190 write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry, MonoError *error)
2191 {
2192         MONO_REQ_GC_UNSAFE_MODE;
2193
2194         MonoDynamicTable *table;
2195         MonoGenericParam *param;
2196         guint32 *values;
2197         guint32 table_idx;
2198
2199         mono_error_init (error);
2200
2201         table = &assembly->tables [MONO_TABLE_GENERICPARAM];
2202         table_idx = table->next_idx ++;
2203         values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
2204
2205         MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)entry->gparam, error);
2206         return_val_if_nok (error, FALSE);
2207
2208         param = gparam_type->data.generic_param;
2209
2210         values [MONO_GENERICPARAM_OWNER] = entry->owner;
2211         values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
2212         values [MONO_GENERICPARAM_NUMBER] = mono_generic_param_num (param);
2213         values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, mono_generic_param_info (param)->name);
2214
2215         if (!mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs, error))
2216                 return FALSE;
2217
2218         encode_constraints (entry->gparam, table_idx, assembly, error);
2219         return_val_if_nok (error, FALSE);
2220
2221         return TRUE;
2222 }
2223
2224 static guint32
2225 resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
2226 {
2227         MONO_REQ_GC_UNSAFE_MODE;
2228
2229         MonoDynamicTable *table;
2230         guint32 token;
2231         guint32 *values;
2232         guint32 cols [MONO_ASSEMBLY_SIZE];
2233         const char *pubkey;
2234         guint32 publen;
2235
2236         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
2237                 return token;
2238
2239         if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
2240                 table = &assembly->tables [MONO_TABLE_MODULEREF];
2241                 token = table->next_idx ++;
2242                 table->rows ++;
2243                 alloc_table (table, table->rows);
2244                 values = table->values + token * MONO_MODULEREF_SIZE;
2245                 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
2246
2247                 token <<= MONO_RESOLUTION_SCOPE_BITS;
2248                 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
2249                 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
2250
2251                 return token;
2252         }
2253         
2254         if (assembly_is_dynamic (image->assembly))
2255                 /* FIXME: */
2256                 memset (cols, 0, sizeof (cols));
2257         else {
2258                 /* image->assembly->image is the manifest module */
2259                 image = image->assembly->image;
2260                 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
2261         }
2262
2263         table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
2264         token = table->next_idx ++;
2265         table->rows ++;
2266         alloc_table (table, table->rows);
2267         values = table->values + token * MONO_ASSEMBLYREF_SIZE;
2268         values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
2269         values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
2270         values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
2271         values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
2272         values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
2273         values [MONO_ASSEMBLYREF_FLAGS] = 0;
2274         values [MONO_ASSEMBLYREF_CULTURE] = 0;
2275         values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
2276
2277         if (strcmp ("", image->assembly->aname.culture)) {
2278                 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
2279                                 image->assembly->aname.culture);
2280         }
2281
2282         if ((pubkey = mono_image_get_public_key (image, &publen))) {
2283                 guchar pubtoken [9];
2284                 pubtoken [0] = 8;
2285                 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
2286                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
2287         } else {
2288                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
2289         }
2290         token <<= MONO_RESOLUTION_SCOPE_BITS;
2291         token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
2292         g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
2293         return token;
2294 }
2295
2296 static guint32
2297 create_typespec (MonoDynamicImage *assembly, MonoType *type)
2298 {
2299         MONO_REQ_GC_NEUTRAL_MODE;
2300
2301         MonoDynamicTable *table;
2302         guint32 *values;
2303         guint32 token;
2304         SigBuffer buf;
2305
2306         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
2307                 return token;
2308
2309         sigbuffer_init (&buf, 32);
2310         switch (type->type) {
2311         case MONO_TYPE_FNPTR:
2312         case MONO_TYPE_PTR:
2313         case MONO_TYPE_SZARRAY:
2314         case MONO_TYPE_ARRAY:
2315         case MONO_TYPE_VAR:
2316         case MONO_TYPE_MVAR:
2317         case MONO_TYPE_GENERICINST:
2318                 encode_type (assembly, type, &buf);
2319                 break;
2320         case MONO_TYPE_CLASS:
2321         case MONO_TYPE_VALUETYPE: {
2322                 MonoClass *k = mono_class_from_mono_type (type);
2323                 if (!k || !k->generic_container) {
2324                         sigbuffer_free (&buf);
2325                         return 0;
2326                 }
2327                 encode_type (assembly, type, &buf);
2328                 break;
2329         }
2330         default:
2331                 sigbuffer_free (&buf);
2332                 return 0;
2333         }
2334
2335         table = &assembly->tables [MONO_TABLE_TYPESPEC];
2336         if (assembly->save) {
2337                 token = sigbuffer_add_to_blob_cached (assembly, &buf);
2338                 alloc_table (table, table->rows + 1);
2339                 values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
2340                 values [MONO_TYPESPEC_SIGNATURE] = token;
2341         }
2342         sigbuffer_free (&buf);
2343
2344         token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
2345         g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
2346         table->next_idx ++;
2347         return token;
2348 }
2349
2350 static guint32
2351 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
2352 {
2353         MONO_REQ_GC_UNSAFE_MODE;
2354
2355         MonoDynamicTable *table;
2356         guint32 *values;
2357         guint32 token, scope, enclosing;
2358         MonoClass *klass;
2359
2360         /* if the type requires a typespec, we must try that first*/
2361         if (try_typespec && (token = create_typespec (assembly, type)))
2362                 return token;
2363         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
2364         if (token)
2365                 return token;
2366         klass = mono_class_from_mono_type (type);
2367         if (!klass)
2368                 klass = mono_class_from_mono_type (type);
2369
2370         /*
2371          * If it's in the same module and not a generic type parameter:
2372          */
2373         if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && 
2374                         (type->type != MONO_TYPE_MVAR)) {
2375                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
2376                 token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
2377                 mono_dynamic_image_register_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
2378                 return token;
2379         }
2380
2381         if (klass->nested_in) {
2382                 enclosing = mono_image_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
2383                 /* get the typeref idx of the enclosing type */
2384                 enclosing >>= MONO_TYPEDEFORREF_BITS;
2385                 scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
2386         } else {
2387                 scope = resolution_scope_from_image (assembly, klass->image);
2388         }
2389         table = &assembly->tables [MONO_TABLE_TYPEREF];
2390         if (assembly->save) {
2391                 alloc_table (table, table->rows + 1);
2392                 values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
2393                 values [MONO_TYPEREF_SCOPE] = scope;
2394                 values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
2395                 values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
2396         }
2397         token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
2398         g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
2399         table->next_idx ++;
2400         mono_dynamic_image_register_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
2401         return token;
2402 }
2403
2404 /*
2405  * Despite the name, we handle also TypeSpec (with the above helper).
2406  */
2407 static guint32
2408 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
2409 {
2410         return mono_image_typedef_or_ref_full (assembly, type, TRUE);
2411 }
2412
2413 #ifndef DISABLE_REFLECTION_EMIT
2414 static guint32
2415 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
2416 {
2417         MONO_REQ_GC_NEUTRAL_MODE;
2418
2419         MonoDynamicTable *table;
2420         guint32 *values;
2421         guint32 token, pclass;
2422
2423         switch (parent & MONO_TYPEDEFORREF_MASK) {
2424         case MONO_TYPEDEFORREF_TYPEREF:
2425                 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
2426                 break;
2427         case MONO_TYPEDEFORREF_TYPESPEC:
2428                 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
2429                 break;
2430         case MONO_TYPEDEFORREF_TYPEDEF:
2431                 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
2432                 break;
2433         default:
2434                 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
2435                 return 0;
2436         }
2437         /* extract the index */
2438         parent >>= MONO_TYPEDEFORREF_BITS;
2439
2440         table = &assembly->tables [MONO_TABLE_MEMBERREF];
2441
2442         if (assembly->save) {
2443                 alloc_table (table, table->rows + 1);
2444                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
2445                 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
2446                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
2447                 values [MONO_MEMBERREF_SIGNATURE] = sig;
2448         }
2449
2450         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
2451         table->next_idx ++;
2452
2453         return token;
2454 }
2455
2456 /*
2457  * Insert a memberef row into the metadata: the token that point to the memberref
2458  * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
2459  * mono_image_get_fieldref_token()).
2460  * The sig param is an index to an already built signature.
2461  */
2462 static guint32
2463 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
2464 {
2465         MONO_REQ_GC_NEUTRAL_MODE;
2466
2467         guint32 parent = mono_image_typedef_or_ref (assembly, type);
2468         return mono_image_add_memberef_row (assembly, parent, name, sig);
2469 }
2470
2471
2472 static guint32
2473 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
2474 {
2475         MONO_REQ_GC_NEUTRAL_MODE;
2476
2477         guint32 token;
2478         MonoMethodSignature *sig;
2479         
2480         create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
2481
2482         if (create_typespec) {
2483                 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
2484                 if (token)
2485                         return token;
2486         } 
2487
2488         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
2489         if (token && !create_typespec)
2490                 return token;
2491
2492         g_assert (!method->is_inflated);
2493         if (!token) {
2494                 /*
2495                  * A methodref signature can't contain an unmanaged calling convention.
2496                  */
2497                 sig = mono_metadata_signature_dup (mono_method_signature (method));
2498                 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
2499                         sig->call_convention = MONO_CALL_DEFAULT;
2500                 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
2501                         method->name,  method_encode_signature (assembly, sig));
2502                 g_free (sig);
2503                 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
2504         }
2505
2506         if (create_typespec) {
2507                 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
2508                 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
2509                 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
2510
2511                 if (assembly->save) {
2512                         guint32 *values;
2513
2514                         alloc_table (table, table->rows + 1);
2515                         values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
2516                         values [MONO_METHODSPEC_METHOD] = token;
2517                         values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
2518                 }
2519
2520                 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
2521                 table->next_idx ++;
2522                 /*methodspec and memberef tokens are diferent, */
2523                 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
2524                 return token;
2525         }
2526         return token;
2527 }
2528
2529 static guint32
2530 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
2531 {
2532         guint32 token, parent, sig;
2533         ReflectionMethodBuilder rmb;
2534         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
2535         
2536         mono_error_init (error);
2537         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
2538         if (token)
2539                 return token;
2540
2541         if (!reflection_methodbuilder_from_method_builder (&rmb, method, error))
2542                 return 0;
2543
2544         /*
2545          * A methodref signature can't contain an unmanaged calling convention.
2546          * Since some flags are encoded as part of call_conv, we need to check against it.
2547         */
2548         if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
2549                 rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
2550
2551         sig = method_builder_encode_signature (assembly, &rmb, error);
2552         return_val_if_nok (error, 0);
2553
2554         if (tb->generic_params) {
2555                 parent = create_generic_typespec (assembly, tb, error);
2556                 return_val_if_nok (error, 0);
2557         } else {
2558                 MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
2559                 return_val_if_nok (error, 0);
2560
2561                 parent = mono_image_typedef_or_ref (assembly, t);
2562         }
2563
2564         char *name = mono_string_to_utf8_checked (method->name, error);
2565         return_val_if_nok (error, 0);
2566
2567         token = mono_image_add_memberef_row (assembly, parent, name, sig);
2568         g_free (name);
2569
2570         g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
2571
2572         return token;
2573 }
2574
2575 static guint32
2576 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
2577                                      const gchar *name, guint32 sig)
2578 {
2579         MonoDynamicTable *table;
2580         guint32 token;
2581         guint32 *values;
2582         
2583         table = &assembly->tables [MONO_TABLE_MEMBERREF];
2584
2585         if (assembly->save) {
2586                 alloc_table (table, table->rows + 1);
2587                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
2588                 values [MONO_MEMBERREF_CLASS] = original;
2589                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
2590                 values [MONO_MEMBERREF_SIGNATURE] = sig;
2591         }
2592
2593         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
2594         table->next_idx ++;
2595
2596         return token;
2597 }
2598
2599 static guint32
2600 encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
2601 {
2602         SigBuffer buf;
2603         int i;
2604         guint32 nparams = mono_array_length (mb->generic_params);
2605         guint32 idx;
2606
2607         if (!assembly->save)
2608                 return 0;
2609
2610         sigbuffer_init (&buf, 32);
2611
2612         sigbuffer_add_value (&buf, 0xa);
2613         sigbuffer_add_value (&buf, nparams);
2614
2615         for (i = 0; i < nparams; i++) {
2616                 sigbuffer_add_value (&buf, MONO_TYPE_MVAR);
2617                 sigbuffer_add_value (&buf, i);
2618         }
2619
2620         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
2621         sigbuffer_free (&buf);
2622         return idx;
2623 }
2624
2625 static guint32
2626 mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
2627 {
2628         MonoDynamicTable *table;
2629         guint32 *values;
2630         guint32 token, mtoken = 0;
2631
2632         mono_error_init (error);
2633         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
2634         if (token)
2635                 return token;
2636
2637         table = &assembly->tables [MONO_TABLE_METHODSPEC];
2638
2639         mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
2640         if (!mono_error_ok (error))
2641                 return 0;
2642
2643         switch (mono_metadata_token_table (mtoken)) {
2644         case MONO_TABLE_MEMBERREF:
2645                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
2646                 break;
2647         case MONO_TABLE_METHOD:
2648                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
2649                 break;
2650         default:
2651                 g_assert_not_reached ();
2652         }
2653
2654         if (assembly->save) {
2655                 alloc_table (table, table->rows + 1);
2656                 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
2657                 values [MONO_METHODSPEC_METHOD] = mtoken;
2658                 values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_definition_sig (assembly, mb);
2659         }
2660
2661         token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
2662         table->next_idx ++;
2663
2664         mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
2665         return token;
2666 }
2667
2668 static guint32
2669 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec, MonoError *error)
2670 {
2671         guint32 token;
2672
2673         mono_error_init (error);
2674
2675         if (mb->generic_params && create_methodspec) 
2676                 return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb, error);
2677
2678         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
2679         if (token)
2680                 return token;
2681
2682         token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
2683         if (!mono_error_ok (error))
2684                 return 0;
2685         mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
2686         return token;
2687 }
2688
2689 static guint32
2690 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb, MonoError *error)
2691 {
2692         guint32 token, parent, sig;
2693         ReflectionMethodBuilder rmb;
2694         char *name;
2695         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
2696         
2697         mono_error_init (error);
2698         
2699         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
2700         if (token)
2701                 return token;
2702
2703         if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
2704                 return 0;
2705
2706         if (tb->generic_params) {
2707                 parent = create_generic_typespec (assembly, tb, error);
2708                 return_val_if_nok (error, 0);
2709         } else {
2710                 MonoType * type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
2711                 return_val_if_nok (error, 0);
2712                 parent = mono_image_typedef_or_ref (assembly, type);
2713         }
2714         
2715         name = mono_string_to_utf8_checked (rmb.name, error);
2716         return_val_if_nok (error, 0);
2717         sig = method_builder_encode_signature (assembly, &rmb, error);
2718         return_val_if_nok (error, 0);
2719
2720         token = mono_image_add_memberef_row (assembly, parent, name, sig);
2721
2722         g_free (name);
2723         mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
2724         return token;
2725 }
2726 #endif
2727
2728 static gboolean
2729 is_field_on_inst (MonoClassField *field)
2730 {
2731         return (field->parent->generic_class && field->parent->generic_class->is_dynamic && ((MonoDynamicGenericClass*)field->parent->generic_class)->fields);
2732 }
2733
2734 /*
2735  * If FIELD is a field of a MonoDynamicGenericClass, return its non-inflated type.
2736  */
2737 static MonoType*
2738 get_field_on_inst_generic_type (MonoClassField *field)
2739 {
2740         MonoClass *klass, *gtd;
2741         MonoDynamicGenericClass *dgclass;
2742         int field_index;
2743
2744         g_assert (is_field_on_inst (field));
2745
2746         dgclass = (MonoDynamicGenericClass*)field->parent->generic_class;
2747
2748         if (field >= dgclass->fields && field - dgclass->fields < dgclass->count_fields) {
2749                 field_index = field - dgclass->fields;
2750                 return dgclass->field_generic_types [field_index];              
2751         }
2752
2753         klass = field->parent;
2754         gtd = klass->generic_class->container_class;
2755
2756         if (field >= klass->fields && field - klass->fields < klass->field.count) {
2757                 field_index = field - klass->fields;
2758                 return gtd->fields [field_index].type;
2759         }
2760
2761         g_assert_not_reached ();
2762         return 0;
2763 }
2764
2765 #ifndef DISABLE_REFLECTION_EMIT
2766 gboolean
2767 mono_is_sr_field_on_inst (MonoClassField *field)
2768 {
2769         return is_field_on_inst (field);
2770 }
2771 #else
2772 gboolean
2773 mono_is_sr_field_on_inst (MonoClassField *field)
2774 {
2775         return FALSE;
2776 }
2777 #endif /*DISABLE_REFLECTION_EMIT*/
2778
2779 #ifndef DISABLE_REFLECTION_EMIT
2780 MonoType*
2781 mono_reflection_get_field_on_inst_generic_type (MonoClassField *field)
2782 {
2783         return get_field_on_inst_generic_type (field);
2784 }
2785 #else
2786 MonoType*
2787 mono_reflection_get_field_on_inst_generic_type (MonoClassField *field)
2788 {
2789         g_assert_not_reached ();
2790         return NULL;
2791 }
2792 #endif /* DISABLE_REFLECTION_EMIT */
2793
2794 #ifndef DISABLE_REFLECTION_EMIT
2795 static guint32
2796 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
2797 {
2798         MonoType *type;
2799         guint32 token;
2800
2801         g_assert (field);
2802         g_assert (field->parent);
2803
2804         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
2805         if (token)
2806                 return token;
2807
2808         if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
2809                 int index = field - field->parent->fields;
2810                 type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
2811         } else {
2812                 if (is_field_on_inst (field))
2813                         type = get_field_on_inst_generic_type (field);
2814                 else
2815                         type = mono_field_get_type (field);
2816         }
2817         token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
2818                                                                                         mono_field_get_name (field),
2819                                                                                         fieldref_encode_signature (assembly, field->parent->image, type));
2820         mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
2821         return token;
2822 }
2823
2824 static guint32
2825 mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f, MonoError *error)
2826 {
2827         guint32 token;
2828         MonoClass *klass;
2829         MonoGenericClass *gclass;
2830         MonoType *type;
2831         char *name;
2832
2833         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
2834         if (token)
2835                 return token;
2836         if (is_sre_field_builder (mono_object_class (f->fb))) {
2837                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
2838                 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
2839                 return_val_if_nok (error, 0);
2840                 klass = mono_class_from_mono_type (type);
2841                 gclass = type->data.generic_class;
2842                 g_assert (gclass->is_dynamic);
2843
2844                 guint32 sig_token = field_encode_signature (assembly, fb, error);
2845                 return_val_if_nok (error, 0);
2846                 name = mono_string_to_utf8_checked (fb->name, error);
2847                 return_val_if_nok (error, 0);
2848                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig_token);
2849                 g_free (name);          
2850         } else if (is_sr_mono_field (mono_object_class (f->fb))) {
2851                 guint32 sig;
2852                 MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
2853
2854                 type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
2855                 return_val_if_nok (error, 0);
2856                 klass = mono_class_from_mono_type (type);
2857
2858                 sig = fieldref_encode_signature (assembly, field->parent->image, field->type);
2859                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
2860         } else {
2861                 char *name = mono_type_get_full_name (mono_object_class (f->fb));
2862                 g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
2863         }
2864
2865         mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
2866         return token;
2867 }
2868
2869 static guint32
2870 mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec, MonoError *error)
2871 {
2872         guint32 sig, token;
2873         MonoClass *klass;
2874         MonoGenericClass *gclass;
2875         MonoType *type;
2876
2877         mono_error_init (error);
2878
2879         /* A ctor cannot be a generic method, so we can ignore create_methodspec */
2880
2881         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
2882         if (token)
2883                 return token;
2884
2885         if (mono_is_sre_ctor_builder (mono_object_class (c->cb))) {
2886                 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
2887                 ReflectionMethodBuilder rmb;
2888                 char *name;
2889
2890                 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
2891                 return_val_if_nok (error, 0);
2892                 klass = mono_class_from_mono_type (type);
2893
2894                 gclass = type->data.generic_class;
2895                 g_assert (gclass->is_dynamic);
2896
2897                 if (!reflection_methodbuilder_from_ctor_builder (&rmb, cb, error))
2898                         return 0;
2899
2900                 sig = method_builder_encode_signature (assembly, &rmb, error);
2901                 return_val_if_nok (error, 0);
2902
2903                 name = mono_string_to_utf8_checked (rmb.name, error);
2904                 return_val_if_nok (error, 0);
2905
2906                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
2907                 g_free (name);
2908         } else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb))) {
2909                 MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
2910
2911                 type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
2912                 return_val_if_nok (error, 0);
2913                 klass = mono_class_from_mono_type (type);
2914
2915                 sig = method_encode_signature (assembly, mono_method_signature (mm));
2916                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
2917         } else {
2918                 char *name = mono_type_get_full_name (mono_object_class (c->cb));
2919                 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
2920         }
2921
2922
2923         mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
2924         return token;
2925 }
2926
2927 MonoMethod*
2928 mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderInst *m, MonoError *error)
2929 {
2930         MonoClass *klass;
2931         MonoGenericContext tmp_context;
2932         MonoType **type_argv;
2933         MonoGenericInst *ginst;
2934         MonoMethod *method, *inflated;
2935         int count, i;
2936
2937         mono_error_init (error);
2938
2939         init_type_builder_generics ((MonoObject*)m->inst, error);
2940         return_val_if_nok (error, NULL);
2941
2942         method = inflate_method (m->inst, (MonoObject*)m->mb, error);
2943         return_val_if_nok (error, NULL);
2944
2945         klass = method->klass;
2946
2947         if (m->method_args == NULL)
2948                 return method;
2949
2950         if (method->is_inflated)
2951                 method = ((MonoMethodInflated *) method)->declaring;
2952
2953         count = mono_array_length (m->method_args);
2954
2955         type_argv = g_new0 (MonoType *, count);
2956         for (i = 0; i < count; i++) {
2957                 MonoReflectionType *garg = (MonoReflectionType *)mono_array_get (m->method_args, gpointer, i);
2958                 type_argv [i] = mono_reflection_type_get_handle (garg, error);
2959                 return_val_if_nok (error, NULL);
2960         }
2961         ginst = mono_metadata_get_generic_inst (count, type_argv);
2962         g_free (type_argv);
2963
2964         tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
2965         tmp_context.method_inst = ginst;
2966
2967         inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error);
2968         mono_error_assert_ok (error);
2969         return inflated;
2970 }
2971
2972 static guint32
2973 mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec, MonoError *error)
2974 {
2975         guint32 sig, token = 0;
2976         MonoType *type;
2977         MonoClass *klass;
2978
2979         mono_error_init (error);
2980
2981         if (m->method_args) {
2982                 MonoMethod *inflated;
2983
2984                 inflated = mono_reflection_method_on_tb_inst_get_handle (m, error);
2985                 return_val_if_nok (error, 0);
2986
2987                 if (create_methodspec)
2988                         token = mono_image_get_methodspec_token (assembly, inflated);
2989                 else
2990                         token = mono_image_get_inflated_method_token (assembly, inflated);
2991                 return token;
2992         }
2993
2994         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
2995         if (token)
2996                 return token;
2997
2998         if (is_sre_method_builder (mono_object_class (m->mb))) {
2999                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
3000                 MonoGenericClass *gclass;
3001                 ReflectionMethodBuilder rmb;
3002                 char *name;
3003
3004                 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
3005                 return_val_if_nok (error, 0);
3006                 klass = mono_class_from_mono_type (type);
3007                 gclass = type->data.generic_class;
3008                 g_assert (gclass->is_dynamic);
3009
3010                 if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3011                         return 0;
3012
3013                 sig = method_builder_encode_signature (assembly, &rmb, error);
3014                 return_val_if_nok (error, 0);
3015
3016                 name = mono_string_to_utf8_checked (rmb.name, error);
3017                 return_val_if_nok (error, 0);
3018
3019                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
3020                 g_free (name);          
3021         } else if (is_sr_mono_method (mono_object_class (m->mb))) {
3022                 MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
3023
3024                 type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
3025                 return_val_if_nok (error, 0);
3026                 klass = mono_class_from_mono_type (type);
3027
3028                 sig = method_encode_signature (assembly, mono_method_signature (mm));
3029                 token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
3030         } else {
3031                 char *name = mono_type_get_full_name (mono_object_class (m->mb));
3032                 g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
3033         }
3034
3035         mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
3036         return token;
3037 }
3038
3039 static guint32
3040 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
3041 {
3042         SigBuffer buf;
3043         int i;
3044         guint32 nparams = context->method_inst->type_argc;
3045         guint32 idx;
3046
3047         if (!assembly->save)
3048                 return 0;
3049
3050         sigbuffer_init (&buf, 32);
3051         /*
3052          * FIXME: vararg, explicit_this, differenc call_conv values...
3053          */
3054         sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
3055         sigbuffer_add_value (&buf, nparams);
3056
3057         for (i = 0; i < nparams; i++)
3058                 encode_type (assembly, context->method_inst->type_argv [i], &buf);
3059
3060         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
3061         sigbuffer_free (&buf);
3062         return idx;
3063 }
3064
3065 static guint32
3066 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
3067 {
3068         MonoDynamicTable *table;
3069         guint32 *values;
3070         guint32 token, mtoken = 0, sig;
3071         MonoMethodInflated *imethod;
3072         MonoMethod *declaring;
3073
3074         table = &assembly->tables [MONO_TABLE_METHODSPEC];
3075
3076         g_assert (method->is_inflated);
3077         imethod = (MonoMethodInflated *) method;
3078         declaring = imethod->declaring;
3079
3080         sig = method_encode_signature (assembly, mono_method_signature (declaring));
3081         mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
3082
3083         if (!mono_method_signature (declaring)->generic_param_count)
3084                 return mtoken;
3085
3086         switch (mono_metadata_token_table (mtoken)) {
3087         case MONO_TABLE_MEMBERREF:
3088                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
3089                 break;
3090         case MONO_TABLE_METHOD:
3091                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
3092                 break;
3093         default:
3094                 g_assert_not_reached ();
3095         }
3096
3097         sig = encode_generic_method_sig (assembly, mono_method_get_context (method));
3098
3099         if (assembly->save) {
3100                 alloc_table (table, table->rows + 1);
3101                 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
3102                 values [MONO_METHODSPEC_METHOD] = mtoken;
3103                 values [MONO_METHODSPEC_SIGNATURE] = sig;
3104         }
3105
3106         token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
3107         table->next_idx ++;
3108
3109         return token;
3110 }
3111
3112 static guint32
3113 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
3114 {
3115         MonoMethodInflated *imethod;
3116         guint32 token;
3117         
3118         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
3119         if (token)
3120                 return token;
3121
3122         g_assert (method->is_inflated);
3123         imethod = (MonoMethodInflated *) method;
3124
3125         if (mono_method_signature (imethod->declaring)->generic_param_count) {
3126                 token = method_encode_methodspec (assembly, method);
3127         } else {
3128                 guint32 sig = method_encode_signature (
3129                         assembly, mono_method_signature (imethod->declaring));
3130                 token = mono_image_get_memberref_token (
3131                         assembly, &method->klass->byval_arg, method->name, sig);
3132         }
3133
3134         g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
3135         return token;
3136 }
3137
3138 static guint32
3139 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
3140 {
3141         MonoMethodInflated *imethod = (MonoMethodInflated *) m;
3142         guint32 sig, token;
3143
3144         sig = method_encode_signature (assembly, mono_method_signature (imethod->declaring));
3145         token = mono_image_get_memberref_token (
3146                 assembly, &m->klass->byval_arg, m->name, sig);
3147
3148         return token;
3149 }
3150
3151 static guint32
3152 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error)
3153 {
3154         MonoDynamicTable *table;
3155         MonoClass *klass;
3156         MonoType *type;
3157         guint32 *values;
3158         guint32 token;
3159         SigBuffer buf;
3160         int count, i;
3161
3162         /*
3163          * We're creating a TypeSpec for the TypeBuilder of a generic type declaration,
3164          * ie. what we'd normally use as the generic type in a TypeSpec signature.
3165          * Because of this, we must not insert it into the `typeref' hash table.
3166          */
3167         type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3168         return_val_if_nok (error, 0);
3169         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type));
3170         if (token)
3171                 return token;
3172
3173         sigbuffer_init (&buf, 32);
3174
3175         g_assert (tb->generic_params);
3176         klass = mono_class_from_mono_type (type);
3177
3178         if (tb->generic_container) {
3179                 if (!mono_reflection_create_generic_class (tb, error))
3180                         goto fail;
3181         }
3182
3183         sigbuffer_add_value (&buf, MONO_TYPE_GENERICINST);
3184         g_assert (klass->generic_container);
3185         sigbuffer_add_value (&buf, klass->byval_arg.type);
3186         sigbuffer_add_value (&buf, mono_image_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
3187
3188         count = mono_array_length (tb->generic_params);
3189         sigbuffer_add_value (&buf, count);
3190         for (i = 0; i < count; i++) {
3191                 MonoReflectionGenericParam *gparam;
3192
3193                 gparam = mono_array_get (tb->generic_params, MonoReflectionGenericParam *, i);
3194                 MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
3195                 if (!is_ok (error))
3196                         goto fail;
3197
3198                 encode_type (assembly, gparam_type, &buf);
3199         }
3200
3201         table = &assembly->tables [MONO_TABLE_TYPESPEC];
3202
3203         if (assembly->save) {
3204                 token = sigbuffer_add_to_blob_cached (assembly, &buf);
3205                 alloc_table (table, table->rows + 1);
3206                 values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
3207                 values [MONO_TYPESPEC_SIGNATURE] = token;
3208         }
3209         sigbuffer_free (&buf);
3210
3211         token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
3212         g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
3213         table->next_idx ++;
3214         return token;
3215 fail:
3216         sigbuffer_free (&buf);
3217         return 0;
3218 }
3219
3220 /*
3221  * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
3222  */
3223 static MonoType*
3224 add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt, MonoError *error)
3225 {
3226         int i, count, len, pos;
3227         MonoType *t;
3228
3229         mono_error_init (error);
3230
3231         count = 0;
3232         if (modreq)
3233                 count += mono_array_length (modreq);
3234         if (modopt)
3235                 count += mono_array_length (modopt);
3236
3237         if (count == 0)
3238                 return mono_metadata_type_dup (NULL, type);
3239
3240         len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
3241         t = (MonoType *)g_malloc (len);
3242         memcpy (t, type, MONO_SIZEOF_TYPE);
3243
3244         t->num_mods = count;
3245         pos = 0;
3246         if (modreq) {
3247                 for (i = 0; i < mono_array_length (modreq); ++i) {
3248                         MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
3249                         if (!is_ok (error))
3250                                 goto fail;
3251                         t->modifiers [pos].required = 1;
3252                         t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
3253                         pos ++;
3254                 }
3255         }
3256         if (modopt) {
3257                 for (i = 0; i < mono_array_length (modopt); ++i) {
3258                         MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
3259                         if (!is_ok (error))
3260                                 goto fail;
3261                         t->modifiers [pos].required = 0;
3262                         t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
3263                         pos ++;
3264                 }
3265         }
3266
3267         return t;
3268 fail:
3269         g_free (t);
3270         return NULL;
3271 }
3272
3273 static void
3274 init_type_builder_generics (MonoObject *type, MonoError *error)
3275 {
3276         MonoReflectionTypeBuilder *tb;
3277
3278         mono_error_init (error);
3279
3280         if (!is_sre_type_builder(mono_object_class (type)))
3281                 return;
3282         tb = (MonoReflectionTypeBuilder *)type;
3283
3284         if (tb && tb->generic_container)
3285                 mono_reflection_create_generic_class (tb, error);
3286 }
3287
3288 static guint32
3289 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
3290 {
3291         MonoDynamicTable *table;
3292         MonoType *custom = NULL, *type;
3293         guint32 *values;
3294         guint32 token, pclass, parent, sig;
3295         gchar *name;
3296
3297         mono_error_init (error);
3298
3299         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
3300         if (token)
3301                 return token;
3302
3303         MonoType *typeb = mono_reflection_type_get_handle (fb->typeb, error);
3304         return_val_if_nok (error, 0);
3305         /* FIXME: is this call necessary? */
3306         mono_class_from_mono_type (typeb);
3307
3308         /*FIXME this is one more layer of ugliness due how types are created.*/
3309         init_type_builder_generics (fb->type, error);
3310         return_val_if_nok (error, 0);
3311
3312         /* fb->type does not include the custom modifiers */
3313         /* FIXME: We should do this in one place when a fieldbuilder is created */
3314         type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3315         return_val_if_nok (error, 0);
3316
3317         if (fb->modreq || fb->modopt) {
3318                 type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt, error);
3319                 return_val_if_nok (error, 0);
3320         }
3321
3322         sig = fieldref_encode_signature (assembly, NULL, type);
3323         g_free (custom);
3324
3325         parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb, error);
3326         return_val_if_nok (error, 0);
3327         g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
3328         
3329         pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
3330         parent >>= MONO_TYPEDEFORREF_BITS;
3331
3332         table = &assembly->tables [MONO_TABLE_MEMBERREF];
3333
3334         name = mono_string_to_utf8_checked (fb->name, error);
3335         return_val_if_nok (error, 0);
3336
3337         if (assembly->save) {
3338                 alloc_table (table, table->rows + 1);
3339                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
3340                 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
3341                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
3342                 values [MONO_MEMBERREF_SIGNATURE] = sig;
3343         }
3344
3345         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
3346         table->next_idx ++;
3347         mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
3348         g_free (name);
3349         return token;
3350 }
3351
3352 static guint32
3353 mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
3354 {
3355         SigBuffer buf;
3356         guint32 nargs;
3357         guint32 i, idx;
3358
3359         mono_error_init (error);
3360
3361         if (!assembly->save)
3362                 return 0;
3363
3364         /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
3365         g_assert (helper->type == 2);
3366
3367         if (helper->arguments)
3368                 nargs = mono_array_length (helper->arguments);
3369         else
3370                 nargs = 0;
3371
3372         sigbuffer_init (&buf, 32);
3373
3374         /* Encode calling convention */
3375         /* Change Any to Standard */
3376         if ((helper->call_conv & 0x03) == 0x03)
3377                 helper->call_conv = 0x01;
3378         /* explicit_this implies has_this */
3379         if (helper->call_conv & 0x40)
3380                 helper->call_conv &= 0x20;
3381
3382         if (helper->call_conv == 0) { /* Unmanaged */
3383                 idx = helper->unmanaged_call_conv - 1;
3384         } else {
3385                 /* Managed */
3386                 idx = helper->call_conv & 0x60; /* has_this + explicit_this */
3387                 if (helper->call_conv & 0x02) /* varargs */
3388                         idx += 0x05;
3389         }
3390
3391         sigbuffer_add_byte (&buf, idx);
3392         sigbuffer_add_value (&buf, nargs);
3393         encode_reflection_type (assembly, helper->return_type, &buf, error);
3394         if (!is_ok (error))
3395                 goto fail;
3396         for (i = 0; i < nargs; ++i) {
3397                 MonoArray *modreqs = NULL;
3398                 MonoArray *modopts = NULL;
3399                 MonoReflectionType *pt;
3400
3401                 if (helper->modreqs && (i < mono_array_length (helper->modreqs)))
3402                         modreqs = mono_array_get (helper->modreqs, MonoArray*, i);
3403                 if (helper->modopts && (i < mono_array_length (helper->modopts)))
3404                         modopts = mono_array_get (helper->modopts, MonoArray*, i);
3405
3406                 encode_custom_modifiers (assembly, modreqs, modopts, &buf, error);
3407                 if (!is_ok (error))
3408                         goto fail;
3409                 pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
3410                 encode_reflection_type (assembly, pt, &buf, error);
3411                 if (!is_ok (error))
3412                         goto fail;
3413         }
3414         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
3415         sigbuffer_free (&buf);
3416
3417         return idx;
3418 fail:
3419         sigbuffer_free (&buf);
3420         return 0;
3421 }
3422
3423 static guint32 
3424 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
3425 {
3426         guint32 idx;
3427         MonoDynamicTable *table;
3428         guint32 *values;
3429
3430         mono_error_init (error);
3431
3432         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
3433         idx = table->next_idx ++;
3434         table->rows ++;
3435         alloc_table (table, table->rows);
3436         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
3437
3438         values [MONO_STAND_ALONE_SIGNATURE] =
3439                 mono_reflection_encode_sighelper (assembly, helper, error);
3440         return_val_if_nok (error, 0);
3441         
3442         return idx;
3443 }
3444
3445 static int
3446 reflection_cc_to_file (int call_conv) {
3447         switch (call_conv & 0x3) {
3448         case 0:
3449         case 1: return MONO_CALL_DEFAULT;
3450         case 2: return MONO_CALL_VARARG;
3451         default:
3452                 g_assert_not_reached ();
3453         }
3454         return 0;
3455 }
3456 #endif /* !DISABLE_REFLECTION_EMIT */
3457
3458 struct _ArrayMethod {
3459         MonoType *parent;
3460         MonoMethodSignature *sig;
3461         char *name;
3462         guint32 token;
3463 };
3464
3465 void
3466 mono_sre_array_method_free (ArrayMethod *am)
3467 {
3468         g_free (am->sig);
3469         g_free (am->name);
3470         g_free (am);
3471 }
3472
3473 #ifndef DISABLE_REFLECTION_EMIT
3474 static guint32
3475 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
3476 {
3477         guint32 nparams, i;
3478         GList *tmp;
3479         char *name = NULL;
3480         MonoMethodSignature *sig;
3481         ArrayMethod *am = NULL;
3482         MonoType *mtype;
3483
3484         mono_error_init (error);
3485
3486         nparams = mono_array_length (m->parameters);
3487         sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
3488         sig->hasthis = 1;
3489         sig->sentinelpos = -1;
3490         sig->call_convention = reflection_cc_to_file (m->call_conv);
3491         sig->param_count = nparams;
3492         if (m->ret) {
3493                 sig->ret = mono_reflection_type_get_handle (m->ret, error);
3494                 if (!is_ok (error))
3495                         goto fail;
3496         } else
3497                 sig->ret = &mono_defaults.void_class->byval_arg;
3498
3499         mtype = mono_reflection_type_get_handle (m->parent, error);
3500         if (!is_ok (error))
3501                 goto fail;
3502
3503         for (i = 0; i < nparams; ++i) {
3504                 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
3505                 if (!is_ok (error))
3506                         goto fail;
3507         }
3508
3509         name = mono_string_to_utf8_checked (m->name, error);
3510         if (!is_ok (error))
3511                 goto fail;
3512         for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
3513                 am = (ArrayMethod *)tmp->data;
3514                 if (strcmp (name, am->name) == 0 && 
3515                                 mono_metadata_type_equal (am->parent, mtype) &&
3516                                 mono_metadata_signature_equal (am->sig, sig)) {
3517                         g_free (name);
3518                         g_free (sig);
3519                         m->table_idx = am->token & 0xffffff;
3520                         return am->token;
3521                 }
3522         }
3523         am = g_new0 (ArrayMethod, 1);
3524         am->name = name;
3525         am->sig = sig;
3526         am->parent = mtype;
3527         am->token = mono_image_get_memberref_token (assembly, am->parent, name,
3528                 method_encode_signature (assembly, sig));
3529         assembly->array_methods = g_list_prepend (assembly->array_methods, am);
3530         m->table_idx = am->token & 0xffffff;
3531         return am->token;
3532 fail:
3533         g_free (am);
3534         g_free (name);
3535         g_free (sig);
3536         return 0;
3537
3538 }
3539
3540 /*
3541  * Insert into the metadata tables all the info about the TypeBuilder tb.
3542  * Data in the tables is inserted in a predefined order, since some tables need to be sorted.
3543  */
3544 static gboolean
3545 mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, MonoDynamicImage *assembly, MonoError *error)
3546 {
3547         MonoDynamicTable *table;
3548         guint *values;
3549         int i, is_object = 0, is_system = 0;
3550         char *n;
3551
3552         mono_error_init (error);
3553
3554         table = &assembly->tables [MONO_TABLE_TYPEDEF];
3555         values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
3556         values [MONO_TYPEDEF_FLAGS] = tb->attrs;
3557         n = mono_string_to_utf8_checked (tb->name, error);
3558         return_val_if_nok (error, FALSE);
3559         if (strcmp (n, "Object") == 0)
3560                 is_object++;
3561         values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
3562         g_free (n);
3563         n = mono_string_to_utf8_checked (tb->nspace, error);
3564         return_val_if_nok (error, FALSE);
3565         if (strcmp (n, "System") == 0)
3566                 is_system++;
3567         values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
3568         g_free (n);
3569         if (tb->parent && !(is_system && is_object) && 
3570                         !(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
3571                 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
3572                 return_val_if_nok (error, FALSE);
3573                 values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, parent_type);
3574         } else {
3575                 values [MONO_TYPEDEF_EXTENDS] = 0;
3576         }
3577         values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
3578         values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
3579
3580         /*
3581          * if we have explicitlayout or sequentiallayouts, output data in the
3582          * ClassLayout table.
3583          */
3584         if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
3585                         ((tb->class_size > 0) || (tb->packing_size > 0))) {
3586                 table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
3587                 table->rows++;
3588                 alloc_table (table, table->rows);
3589                 values = table->values + table->rows * MONO_CLASS_LAYOUT_SIZE;
3590                 values [MONO_CLASS_LAYOUT_PARENT] = tb->table_idx;
3591                 values [MONO_CLASS_LAYOUT_CLASS_SIZE] = tb->class_size;
3592                 values [MONO_CLASS_LAYOUT_PACKING_SIZE] = tb->packing_size;
3593         }
3594
3595         /* handle interfaces */
3596         if (tb->interfaces) {
3597                 table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
3598                 i = table->rows;
3599                 table->rows += mono_array_length (tb->interfaces);
3600                 alloc_table (table, table->rows);
3601                 values = table->values + (i + 1) * MONO_INTERFACEIMPL_SIZE;
3602                 for (i = 0; i < mono_array_length (tb->interfaces); ++i) {
3603                         MonoReflectionType* iface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
3604                         MonoType *iface_type = mono_reflection_type_get_handle (iface, error);
3605                         return_val_if_nok (error, FALSE);
3606                         values [MONO_INTERFACEIMPL_CLASS] = tb->table_idx;
3607                         values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, iface_type);
3608                         values += MONO_INTERFACEIMPL_SIZE;
3609                 }
3610         }
3611
3612         /* handle fields */
3613         if (tb->fields) {
3614                 table = &assembly->tables [MONO_TABLE_FIELD];
3615                 table->rows += tb->num_fields;
3616                 alloc_table (table, table->rows);
3617                 for (i = 0; i < tb->num_fields; ++i) {
3618                         mono_image_get_field_info (
3619                                 mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i), assembly, error);
3620                         return_val_if_nok (error, FALSE);
3621                 }
3622         }
3623
3624         /* handle constructors */
3625         if (tb->ctors) {
3626                 table = &assembly->tables [MONO_TABLE_METHOD];
3627                 table->rows += mono_array_length (tb->ctors);
3628                 alloc_table (table, table->rows);
3629                 for (i = 0; i < mono_array_length (tb->ctors); ++i) {
3630                         if (!mono_image_get_ctor_info (domain,
3631                                                        mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i),
3632                                                        assembly, error))
3633                                 return FALSE;
3634                 }
3635         }
3636
3637         /* handle methods */
3638         if (tb->methods) {
3639                 table = &assembly->tables [MONO_TABLE_METHOD];
3640                 table->rows += tb->num_methods;
3641                 alloc_table (table, table->rows);
3642                 for (i = 0; i < tb->num_methods; ++i) {
3643                         if (!mono_image_get_method_info (
3644                                     mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly, error))
3645                                 return FALSE;
3646                 }
3647         }
3648
3649         /* Do the same with properties etc.. */
3650         if (tb->events && mono_array_length (tb->events)) {
3651                 table = &assembly->tables [MONO_TABLE_EVENT];
3652                 table->rows += mono_array_length (tb->events);
3653                 alloc_table (table, table->rows);
3654                 table = &assembly->tables [MONO_TABLE_EVENTMAP];
3655                 table->rows ++;
3656                 alloc_table (table, table->rows);
3657                 values = table->values + table->rows * MONO_EVENT_MAP_SIZE;
3658                 values [MONO_EVENT_MAP_PARENT] = tb->table_idx;
3659                 values [MONO_EVENT_MAP_EVENTLIST] = assembly->tables [MONO_TABLE_EVENT].next_idx;
3660                 for (i = 0; i < mono_array_length (tb->events); ++i) {
3661                         mono_image_get_event_info (
3662                                 mono_array_get (tb->events, MonoReflectionEventBuilder*, i), assembly, error);
3663                         return_val_if_nok (error, FALSE);
3664                 }
3665         }
3666         if (tb->properties && mono_array_length (tb->properties)) {
3667                 table = &assembly->tables [MONO_TABLE_PROPERTY];
3668                 table->rows += mono_array_length (tb->properties);
3669                 alloc_table (table, table->rows);
3670                 table = &assembly->tables [MONO_TABLE_PROPERTYMAP];
3671                 table->rows ++;
3672                 alloc_table (table, table->rows);
3673                 values = table->values + table->rows * MONO_PROPERTY_MAP_SIZE;
3674                 values [MONO_PROPERTY_MAP_PARENT] = tb->table_idx;
3675                 values [MONO_PROPERTY_MAP_PROPERTY_LIST] = assembly->tables [MONO_TABLE_PROPERTY].next_idx;
3676                 for (i = 0; i < mono_array_length (tb->properties); ++i) {
3677                         mono_image_get_property_info (
3678                                 mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly, error);
3679                         return_val_if_nok (error, FALSE);
3680                 }
3681         }
3682
3683         /* handle generic parameters */
3684         if (tb->generic_params) {
3685                 table = &assembly->tables [MONO_TABLE_GENERICPARAM];
3686                 table->rows += mono_array_length (tb->generic_params);
3687                 alloc_table (table, table->rows);
3688                 for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
3689                         guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
3690
3691                         mono_image_get_generic_param_info (
3692                                 mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
3693                 }
3694         }
3695
3696         mono_image_add_decl_security (assembly, 
3697                 mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx), tb->permissions);
3698
3699         if (tb->subtypes) {
3700                 MonoDynamicTable *ntable;
3701                 
3702                 ntable = &assembly->tables [MONO_TABLE_NESTEDCLASS];
3703                 ntable->rows += mono_array_length (tb->subtypes);
3704                 alloc_table (ntable, ntable->rows);
3705                 values = ntable->values + ntable->next_idx * MONO_NESTED_CLASS_SIZE;
3706
3707                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3708                         MonoReflectionTypeBuilder *subtype = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
3709
3710                         values [MONO_NESTED_CLASS_NESTED] = subtype->table_idx;
3711                         values [MONO_NESTED_CLASS_ENCLOSING] = tb->table_idx;
3712                         /*g_print ("nesting %s (%d) in %s (%d) (rows %d/%d)\n",
3713                                 mono_string_to_utf8 (subtype->name), subtype->table_idx,
3714                                 mono_string_to_utf8 (tb->name), tb->table_idx,
3715                                 ntable->next_idx, ntable->rows);*/
3716                         values += MONO_NESTED_CLASS_SIZE;
3717                         ntable->next_idx++;
3718                 }
3719         }
3720
3721         return TRUE;
3722 }
3723 #endif
3724 static void
3725 collect_types (MonoPtrArray *types, MonoReflectionTypeBuilder *type)
3726 {
3727         int i;
3728
3729         mono_ptr_array_append (*types, type);
3730
3731         if (!type->subtypes)
3732                 return;
3733
3734         for (i = 0; i < mono_array_length (type->subtypes); ++i) {
3735                 MonoReflectionTypeBuilder *subtype = mono_array_get (type->subtypes, MonoReflectionTypeBuilder*, i);
3736                 collect_types (types, subtype);
3737         }
3738 }
3739
3740 static gint
3741 compare_types_by_table_idx (MonoReflectionTypeBuilder **type1, MonoReflectionTypeBuilder **type2)
3742 {
3743         if ((*type1)->table_idx < (*type2)->table_idx)
3744                 return -1;
3745         else
3746                 if ((*type1)->table_idx > (*type2)->table_idx)
3747                         return 1;
3748         else
3749                 return 0;
3750 }
3751
3752 static gboolean
3753 params_add_cattrs (MonoDynamicImage *assembly, MonoArray *pinfo, MonoError *error) {
3754         int i;
3755
3756         mono_error_init (error);
3757         if (!pinfo)
3758                 return TRUE;
3759         for (i = 0; i < mono_array_length (pinfo); ++i) {
3760                 MonoReflectionParamBuilder *pb;
3761                 pb = mono_array_get (pinfo, MonoReflectionParamBuilder *, i);
3762                 if (!pb)
3763                         continue;
3764                 if (!mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PARAMDEF, pb->cattrs, error))
3765                         return FALSE;
3766         }
3767
3768         return TRUE;
3769 }
3770
3771 static gboolean
3772 type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error) {
3773         int i;
3774
3775         mono_error_init (error);
3776         
3777         if (!mono_image_add_cattrs (assembly, tb->table_idx, MONO_CUSTOM_ATTR_TYPEDEF, tb->cattrs, error))
3778                 return FALSE;
3779         if (tb->fields) {
3780                 for (i = 0; i < tb->num_fields; ++i) {
3781                         MonoReflectionFieldBuilder* fb;
3782                         fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i);
3783                         if (!mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs, error))
3784                                 return FALSE;
3785                 }
3786         }
3787         if (tb->events) {
3788                 for (i = 0; i < mono_array_length (tb->events); ++i) {
3789                         MonoReflectionEventBuilder* eb;
3790                         eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3791                         if (!mono_image_add_cattrs (assembly, eb->table_idx, MONO_CUSTOM_ATTR_EVENT, eb->cattrs, error))
3792                                 return FALSE;
3793                 }
3794         }
3795         if (tb->properties) {
3796                 for (i = 0; i < mono_array_length (tb->properties); ++i) {
3797                         MonoReflectionPropertyBuilder* pb;
3798                         pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3799                         if (!mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PROPERTY, pb->cattrs, error))
3800                                 return FALSE;
3801                 }
3802         }
3803         if (tb->ctors) {
3804                 for (i = 0; i < mono_array_length (tb->ctors); ++i) {
3805                         MonoReflectionCtorBuilder* cb;
3806                         cb = mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i);
3807                         if (!mono_image_add_cattrs (assembly, cb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, cb->cattrs, error) ||
3808                             !params_add_cattrs (assembly, cb->pinfo, error))
3809                                 return FALSE;
3810                 }
3811         }
3812
3813         if (tb->methods) {
3814                 for (i = 0; i < tb->num_methods; ++i) {
3815                         MonoReflectionMethodBuilder* mb;
3816                         mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3817                         if (!mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs, error) ||
3818                             !params_add_cattrs (assembly, mb->pinfo, error))
3819                                 return FALSE;
3820                 }
3821         }
3822
3823         if (tb->subtypes) {
3824                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3825                         if (!type_add_cattrs (assembly, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), error))
3826                                 return FALSE;
3827                 }
3828         }
3829
3830         return TRUE;
3831 }
3832
3833 static gboolean
3834 module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *moduleb, MonoError *error)
3835 {
3836         int i;
3837         
3838         mono_error_init (error);
3839
3840         if (!mono_image_add_cattrs (assembly, moduleb->table_idx, MONO_CUSTOM_ATTR_MODULE, moduleb->cattrs, error))
3841                 return FALSE;
3842
3843         if (moduleb->global_methods) {
3844                 for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
3845                         MonoReflectionMethodBuilder* mb = mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i);
3846                         if (!mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs, error) ||
3847                             !params_add_cattrs (assembly, mb->pinfo, error))
3848                                 return FALSE;
3849                 }
3850         }
3851
3852         if (moduleb->global_fields) {
3853                 for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
3854                         MonoReflectionFieldBuilder *fb = mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i);
3855                         if (!mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs, error))
3856                                 return FALSE;
3857                 }
3858         }
3859         
3860         if (moduleb->types) {
3861                 for (i = 0; i < moduleb->num_types; ++i) {
3862                         if (!type_add_cattrs (assembly, mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i), error))
3863                                 return FALSE;
3864                 }
3865         }
3866
3867         return TRUE;
3868 }
3869
3870 static gboolean
3871 mono_image_fill_file_table (MonoDomain *domain, MonoReflectionModule *module, MonoDynamicImage *assembly, MonoError *error)
3872 {
3873         MonoDynamicTable *table;
3874         guint32 *values;
3875         char blob_size [6];
3876         guchar hash [20];
3877         char *b = blob_size;
3878         char *dir, *path;
3879
3880         mono_error_init (error);
3881
3882         table = &assembly->tables [MONO_TABLE_FILE];
3883         table->rows++;
3884         alloc_table (table, table->rows);
3885         values = table->values + table->next_idx * MONO_FILE_SIZE;
3886         values [MONO_FILE_FLAGS] = FILE_CONTAINS_METADATA;
3887         values [MONO_FILE_NAME] = string_heap_insert (&assembly->sheap, module->image->module_name);
3888         if (image_is_dynamic (module->image)) {
3889                 /* This depends on the fact that the main module is emitted last */
3890                 dir = mono_string_to_utf8_checked (((MonoReflectionModuleBuilder*)module)->assemblyb->dir, error);
3891                 return_val_if_nok (error, FALSE);
3892                 path = g_strdup_printf ("%s%c%s", dir, G_DIR_SEPARATOR, module->image->module_name);
3893         } else {
3894                 dir = NULL;
3895                 path = g_strdup (module->image->name);
3896         }
3897         mono_sha1_get_digest_from_file (path, hash);
3898         g_free (dir);
3899         g_free (path);
3900         mono_metadata_encode_value (20, b, &b);
3901         values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
3902         mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
3903         table->next_idx ++;
3904         return TRUE;
3905 }
3906
3907 static void
3908 mono_image_fill_module_table (MonoDomain *domain, MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoError *error)
3909 {
3910         MonoDynamicTable *table;
3911         int i;
3912
3913         mono_error_init (error);
3914
3915         table = &assembly->tables [MONO_TABLE_MODULE];
3916         mb->table_idx = table->next_idx ++;
3917         table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->module.name, error);
3918         return_if_nok (error);
3919         i = mono_image_add_stream_data (&assembly->guid, mono_array_addr (mb->guid, char, 0), 16);
3920         i /= 16;
3921         ++i;
3922         table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_GENERATION] = 0;
3923         table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_MVID] = i;
3924         table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENC] = 0;
3925         table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENCBASE] = 0;
3926 }
3927
3928 static guint32
3929 mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
3930         guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly)
3931 {
3932         MonoDynamicTable *table;
3933         guint32 *values;
3934         guint32 visib, res;
3935
3936         visib = klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
3937         if (! ((visib & TYPE_ATTRIBUTE_PUBLIC) || (visib & TYPE_ATTRIBUTE_NESTED_PUBLIC)))
3938                 return 0;
3939
3940         table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
3941         table->rows++;
3942         alloc_table (table, table->rows);
3943         values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
3944
3945         values [MONO_EXP_TYPE_FLAGS] = klass->flags;
3946         values [MONO_EXP_TYPE_TYPEDEF] = klass->type_token;
3947         if (klass->nested_in)
3948                 values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
3949         else
3950                 values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_FILE;
3951         values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
3952         values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
3953
3954         res = table->next_idx;
3955
3956         table->next_idx ++;
3957
3958         /* Emit nested types */
3959         if (klass->ext && klass->ext->nested_classes) {
3960                 GList *tmp;
3961
3962                 for (tmp = klass->ext->nested_classes; tmp; tmp = tmp->next)
3963                         mono_image_fill_export_table_from_class (domain, (MonoClass *)tmp->data, module_index, table->next_idx - 1, assembly);
3964         }
3965
3966         return res;
3967 }
3968
3969 static void
3970 mono_image_fill_export_table (MonoDomain *domain, MonoReflectionTypeBuilder *tb,
3971                               guint32 module_index, guint32 parent_index, MonoDynamicImage *assembly,
3972                               MonoError *error)
3973 {
3974         MonoClass *klass;
3975         guint32 idx, i;
3976
3977         mono_error_init (error);
3978
3979         MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3980         return_if_nok (error);
3981
3982         klass = mono_class_from_mono_type (t);
3983
3984         klass->type_token = mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx);
3985
3986         idx = mono_image_fill_export_table_from_class (domain, klass, module_index, 
3987                                                                                                    parent_index, assembly);
3988
3989         /* 
3990          * Emit nested types
3991          * We need to do this ourselves since klass->nested_classes is not set up.
3992          */
3993         if (tb->subtypes) {
3994                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3995                         mono_image_fill_export_table (domain, mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i), module_index, idx, assembly, error);
3996                         return_if_nok (error);
3997                 }
3998         }
3999 }
4000
4001 static void
4002 mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModule *module,
4003         guint32 module_index, MonoDynamicImage *assembly)
4004 {
4005         MonoImage *image = module->image;
4006         MonoTableInfo  *t;
4007         guint32 i;
4008
4009         t = &image->tables [MONO_TABLE_TYPEDEF];
4010
4011         for (i = 0; i < t->rows; ++i) {
4012                 MonoError error;
4013                 MonoClass *klass = mono_class_get_checked (image, mono_metadata_make_token (MONO_TABLE_TYPEDEF, i + 1), &error);
4014                 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
4015
4016                 if (klass->flags & TYPE_ATTRIBUTE_PUBLIC)
4017                         mono_image_fill_export_table_from_class (domain, klass, module_index, 0, assembly);
4018         }
4019 }
4020
4021 static void
4022 add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass, guint32 parent_index)
4023 {
4024         MonoDynamicTable *table;
4025         guint32 *values;
4026         guint32 scope, scope_idx, impl, current_idx;
4027         gboolean forwarder = TRUE;
4028         gpointer iter = NULL;
4029         MonoClass *nested;
4030
4031         if (klass->nested_in) {
4032                 impl = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
4033                 forwarder = FALSE;
4034         } else {
4035                 scope = resolution_scope_from_image (assembly, klass->image);
4036                 g_assert ((scope & MONO_RESOLUTION_SCOPE_MASK) == MONO_RESOLUTION_SCOPE_ASSEMBLYREF);
4037                 scope_idx = scope >> MONO_RESOLUTION_SCOPE_BITS;
4038                 impl = (scope_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
4039         }
4040
4041         table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
4042
4043         table->rows++;
4044         alloc_table (table, table->rows);
4045         current_idx = table->next_idx;
4046         values = table->values + current_idx * MONO_EXP_TYPE_SIZE;
4047
4048         values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
4049         values [MONO_EXP_TYPE_TYPEDEF] = 0;
4050         values [MONO_EXP_TYPE_IMPLEMENTATION] = impl;
4051         values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
4052         values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
4053
4054         table->next_idx++;
4055
4056         while ((nested = mono_class_get_nested_types (klass, &iter)))
4057                 add_exported_type (assemblyb, assembly, nested, current_idx);
4058 }
4059
4060 static void
4061 mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
4062 {
4063         MonoError error;
4064         MonoClass *klass;
4065         int i;
4066
4067         if (!assemblyb->type_forwarders)
4068                 return;
4069
4070         for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
4071                 MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType *, i);
4072                 MonoType *type;
4073                 if (!t)
4074                         continue;
4075
4076                 type = mono_reflection_type_get_handle (t, &error);
4077                 mono_error_assert_ok (&error);
4078                 g_assert (type);
4079
4080                 klass = mono_class_from_mono_type (type);
4081
4082                 add_exported_type (assemblyb, assembly, klass, 0);
4083         }
4084 }
4085
4086 #define align_pointer(base,p)\
4087         do {\
4088                 guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\
4089                 if (__diff & 3)\
4090                         (p) += 4 - (__diff & 3);\
4091         } while (0)
4092
4093 static int
4094 compare_constants (const void *a, const void *b)
4095 {
4096         const guint32 *a_values = (const guint32 *)a;
4097         const guint32 *b_values = (const guint32 *)b;
4098         return a_values [MONO_CONSTANT_PARENT] - b_values [MONO_CONSTANT_PARENT];
4099 }
4100
4101 static int
4102 compare_semantics (const void *a, const void *b)
4103 {
4104         const guint32 *a_values = (const guint32 *)a;
4105         const guint32 *b_values = (const guint32 *)b;
4106         int assoc = a_values [MONO_METHOD_SEMA_ASSOCIATION] - b_values [MONO_METHOD_SEMA_ASSOCIATION];
4107         if (assoc)
4108                 return assoc;
4109         return a_values [MONO_METHOD_SEMA_SEMANTICS] - b_values [MONO_METHOD_SEMA_SEMANTICS];
4110 }
4111
4112 static int
4113 compare_custom_attrs (const void *a, const void *b)
4114 {
4115         const guint32 *a_values = (const guint32 *)a;
4116         const guint32 *b_values = (const guint32 *)b;
4117
4118         return a_values [MONO_CUSTOM_ATTR_PARENT] - b_values [MONO_CUSTOM_ATTR_PARENT];
4119 }
4120
4121 static int
4122 compare_field_marshal (const void *a, const void *b)
4123 {
4124         const guint32 *a_values = (const guint32 *)a;
4125         const guint32 *b_values = (const guint32 *)b;
4126
4127         return a_values [MONO_FIELD_MARSHAL_PARENT] - b_values [MONO_FIELD_MARSHAL_PARENT];
4128 }
4129
4130 static int
4131 compare_nested (const void *a, const void *b)
4132 {
4133         const guint32 *a_values = (const guint32 *)a;
4134         const guint32 *b_values = (const guint32 *)b;
4135
4136         return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
4137 }
4138
4139 static int
4140 compare_genericparam (const void *a, const void *b)
4141 {
4142         MonoError error;
4143         const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
4144         const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
4145
4146         if ((*b_entry)->owner == (*a_entry)->owner) {
4147                 MonoType *a_type = mono_reflection_type_get_handle ((MonoReflectionType*)(*a_entry)->gparam, &error);
4148                 mono_error_assert_ok (&error);
4149                 MonoType *b_type = mono_reflection_type_get_handle ((MonoReflectionType*)(*b_entry)->gparam, &error);
4150                 mono_error_assert_ok (&error);
4151                 return 
4152                         mono_type_get_generic_param_num (a_type) -
4153                         mono_type_get_generic_param_num (b_type);
4154         } else
4155                 return (*a_entry)->owner - (*b_entry)->owner;
4156 }
4157
4158 static int
4159 compare_declsecurity_attrs (const void *a, const void *b)
4160 {
4161         const guint32 *a_values = (const guint32 *)a;
4162         const guint32 *b_values = (const guint32 *)b;
4163
4164         return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT];
4165 }
4166
4167 static int
4168 compare_interface_impl (const void *a, const void *b)
4169 {
4170         const guint32 *a_values = (const guint32 *)a;
4171         const guint32 *b_values = (const guint32 *)b;
4172
4173         int klass = a_values [MONO_INTERFACEIMPL_CLASS] - b_values [MONO_INTERFACEIMPL_CLASS];
4174         if (klass)
4175                 return klass;
4176
4177         return a_values [MONO_INTERFACEIMPL_INTERFACE] - b_values [MONO_INTERFACEIMPL_INTERFACE];
4178 }
4179
4180 struct StreamDesc {
4181         const char *name;
4182         MonoDynamicStream *stream;
4183 };
4184
4185 /*
4186  * build_compressed_metadata() fills in the blob of data that represents the 
4187  * raw metadata as it will be saved in the PE file. The five streams are output 
4188  * and the metadata tables are comnpressed from the guint32 array representation, 
4189  * to the compressed on-disk format.
4190  */
4191 static gboolean
4192 build_compressed_metadata (MonoDynamicImage *assembly, MonoError *error)
4193 {
4194         MonoDynamicTable *table;
4195         int i;
4196         guint64 valid_mask = 0;
4197         guint64 sorted_mask;
4198         guint32 heapt_size = 0;
4199         guint32 meta_size = 256; /* allow for header and other stuff */
4200         guint32 table_offset;
4201         guint32 ntables = 0;
4202         guint64 *int64val;
4203         guint32 *int32val;
4204         guint16 *int16val;
4205         MonoImage *meta;
4206         unsigned char *p;
4207         struct StreamDesc stream_desc [5];
4208
4209         mono_error_init (error);
4210
4211         qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam);
4212         for (i = 0; i < assembly->gen_params->len; i++) {
4213                 GenericParamTableEntry *entry = (GenericParamTableEntry *)g_ptr_array_index (assembly->gen_params, i);
4214                 if (!write_generic_param_entry (assembly, entry, error))
4215                         return FALSE;
4216         }
4217
4218         stream_desc [0].name  = "#~";
4219         stream_desc [0].stream = &assembly->tstream;
4220         stream_desc [1].name  = "#Strings";
4221         stream_desc [1].stream = &assembly->sheap;
4222         stream_desc [2].name  = "#US";
4223         stream_desc [2].stream = &assembly->us;
4224         stream_desc [3].name  = "#Blob";
4225         stream_desc [3].stream = &assembly->blob;
4226         stream_desc [4].name  = "#GUID";
4227         stream_desc [4].stream = &assembly->guid;
4228         
4229         /* tables that are sorted */
4230         sorted_mask = ((guint64)1 << MONO_TABLE_CONSTANT) | ((guint64)1 << MONO_TABLE_FIELDMARSHAL)
4231                 | ((guint64)1 << MONO_TABLE_METHODSEMANTICS) | ((guint64)1 << MONO_TABLE_CLASSLAYOUT)
4232                 | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
4233                 | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
4234                 | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
4235                 | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM)
4236                 | ((guint64)1 << MONO_TABLE_INTERFACEIMPL);
4237         
4238         /* Compute table sizes */
4239         /* the MonoImage has already been created in mono_image_basic_init() */
4240         meta = &assembly->image;
4241
4242         /* sizes should be multiple of 4 */
4243         mono_dynstream_data_align (&assembly->blob);
4244         mono_dynstream_data_align (&assembly->guid);
4245         mono_dynstream_data_align (&assembly->sheap);
4246         mono_dynstream_data_align (&assembly->us);
4247
4248         /* Setup the info used by compute_sizes () */
4249         meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
4250         meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0;
4251         meta->idx_string_wide = assembly->sheap.index >= 65536 ? 1 : 0;
4252
4253         meta_size += assembly->blob.index;
4254         meta_size += assembly->guid.index;
4255         meta_size += assembly->sheap.index;
4256         meta_size += assembly->us.index;
4257
4258         for (i=0; i < MONO_TABLE_NUM; ++i)
4259                 meta->tables [i].rows = assembly->tables [i].rows;
4260         
4261         for (i = 0; i < MONO_TABLE_NUM; i++){
4262                 if (meta->tables [i].rows == 0)
4263                         continue;
4264                 valid_mask |= (guint64)1 << i;
4265                 ntables ++;
4266                 meta->tables [i].row_size = mono_metadata_compute_size (
4267                         meta, i, &meta->tables [i].size_bitfield);
4268                 heapt_size += meta->tables [i].row_size * meta->tables [i].rows;
4269         }
4270         heapt_size += 24; /* #~ header size */
4271         heapt_size += ntables * 4;
4272         /* make multiple of 4 */
4273         heapt_size += 3;
4274         heapt_size &= ~3;
4275         meta_size += heapt_size;
4276         meta->raw_metadata = (char *)g_malloc0 (meta_size);
4277         p = (unsigned char*)meta->raw_metadata;
4278         /* the metadata signature */
4279         *p++ = 'B'; *p++ = 'S'; *p++ = 'J'; *p++ = 'B';
4280         /* version numbers and 4 bytes reserved */
4281         int16val = (guint16*)p;
4282         *int16val++ = GUINT16_TO_LE (meta->md_version_major);
4283         *int16val = GUINT16_TO_LE (meta->md_version_minor);
4284         p += 8;
4285         /* version string */
4286         int32val = (guint32*)p;
4287         *int32val = GUINT32_TO_LE ((strlen (meta->version) + 3) & (~3)); /* needs to be multiple of 4 */
4288         p += 4;
4289         memcpy (p, meta->version, strlen (meta->version));
4290         p += GUINT32_FROM_LE (*int32val);
4291         align_pointer (meta->raw_metadata, p);
4292         int16val = (guint16*)p;
4293         *int16val++ = GUINT16_TO_LE (0); /* flags must be 0 */
4294         *int16val = GUINT16_TO_LE (5); /* number of streams */
4295         p += 4;
4296
4297         /*
4298          * write the stream info.
4299          */
4300         table_offset = (p - (unsigned char*)meta->raw_metadata) + 5 * 8 + 40; /* room needed for stream headers */
4301         table_offset += 3; table_offset &= ~3;
4302
4303         assembly->tstream.index = heapt_size;
4304         for (i = 0; i < 5; ++i) {
4305                 int32val = (guint32*)p;
4306                 stream_desc [i].stream->offset = table_offset;
4307                 *int32val++ = GUINT32_TO_LE (table_offset);
4308                 *int32val = GUINT32_TO_LE (stream_desc [i].stream->index);
4309                 table_offset += GUINT32_FROM_LE (*int32val);
4310                 table_offset += 3; table_offset &= ~3;
4311                 p += 8;
4312                 strcpy ((char*)p, stream_desc [i].name);
4313                 p += strlen (stream_desc [i].name) + 1;
4314                 align_pointer (meta->raw_metadata, p);
4315         }
4316         /* 
4317          * now copy the data, the table stream header and contents goes first.
4318          */
4319         g_assert ((p - (unsigned char*)meta->raw_metadata) < assembly->tstream.offset);
4320         p = (guchar*)meta->raw_metadata + assembly->tstream.offset;
4321         int32val = (guint32*)p;
4322         *int32val = GUINT32_TO_LE (0); /* reserved */
4323         p += 4;
4324
4325         *p++ = 2; /* version */
4326         *p++ = 0;
4327
4328         if (meta->idx_string_wide)
4329                 *p |= 0x01;
4330         if (meta->idx_guid_wide)
4331                 *p |= 0x02;
4332         if (meta->idx_blob_wide)
4333                 *p |= 0x04;
4334         ++p;
4335         *p++ = 1; /* reserved */
4336         int64val = (guint64*)p;
4337         *int64val++ = GUINT64_TO_LE (valid_mask);
4338         *int64val++ = GUINT64_TO_LE (valid_mask & sorted_mask); /* bitvector of sorted tables  */
4339         p += 16;
4340         int32val = (guint32*)p;
4341         for (i = 0; i < MONO_TABLE_NUM; i++){
4342                 if (meta->tables [i].rows == 0)
4343                         continue;
4344                 *int32val++ = GUINT32_TO_LE (meta->tables [i].rows);
4345         }
4346         p = (unsigned char*)int32val;
4347
4348         /* sort the tables that still need sorting */
4349         table = &assembly->tables [MONO_TABLE_CONSTANT];
4350         if (table->rows)
4351                 qsort (table->values + MONO_CONSTANT_SIZE, table->rows, sizeof (guint32) * MONO_CONSTANT_SIZE, compare_constants);
4352         table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
4353         if (table->rows)
4354                 qsort (table->values + MONO_METHOD_SEMA_SIZE, table->rows, sizeof (guint32) * MONO_METHOD_SEMA_SIZE, compare_semantics);
4355         table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
4356         if (table->rows)
4357                 qsort (table->values + MONO_CUSTOM_ATTR_SIZE, table->rows, sizeof (guint32) * MONO_CUSTOM_ATTR_SIZE, compare_custom_attrs);
4358         table = &assembly->tables [MONO_TABLE_FIELDMARSHAL];
4359         if (table->rows)
4360                 qsort (table->values + MONO_FIELD_MARSHAL_SIZE, table->rows, sizeof (guint32) * MONO_FIELD_MARSHAL_SIZE, compare_field_marshal);
4361         table = &assembly->tables [MONO_TABLE_NESTEDCLASS];
4362         if (table->rows)
4363                 qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
4364         /* Section 21.11 DeclSecurity in Partition II doesn't specify this to be sorted by MS implementation requires it */
4365         table = &assembly->tables [MONO_TABLE_DECLSECURITY];
4366         if (table->rows)
4367                 qsort (table->values + MONO_DECL_SECURITY_SIZE, table->rows, sizeof (guint32) * MONO_DECL_SECURITY_SIZE, compare_declsecurity_attrs);
4368         table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
4369         if (table->rows)
4370                 qsort (table->values + MONO_INTERFACEIMPL_SIZE, table->rows, sizeof (guint32) * MONO_INTERFACEIMPL_SIZE, compare_interface_impl);
4371
4372         /* compress the tables */
4373         for (i = 0; i < MONO_TABLE_NUM; i++){
4374                 int row, col;
4375                 guint32 *values;
4376                 guint32 bitfield = meta->tables [i].size_bitfield;
4377                 if (!meta->tables [i].rows)
4378                         continue;
4379                 if (assembly->tables [i].columns != mono_metadata_table_count (bitfield))
4380                         g_error ("col count mismatch in %d: %d %d", i, assembly->tables [i].columns, mono_metadata_table_count (bitfield));
4381                 meta->tables [i].base = (char*)p;
4382                 for (row = 1; row <= meta->tables [i].rows; ++row) {
4383                         values = assembly->tables [i].values + row * assembly->tables [i].columns;
4384                         for (col = 0; col < assembly->tables [i].columns; ++col) {
4385                                 switch (mono_metadata_table_size (bitfield, col)) {
4386                                 case 1:
4387                                         *p++ = values [col];
4388                                         break;
4389                                 case 2:
4390                                         *p++ = values [col] & 0xff;
4391                                         *p++ = (values [col] >> 8) & 0xff;
4392                                         break;
4393                                 case 4:
4394                                         *p++ = values [col] & 0xff;
4395                                         *p++ = (values [col] >> 8) & 0xff;
4396                                         *p++ = (values [col] >> 16) & 0xff;
4397                                         *p++ = (values [col] >> 24) & 0xff;
4398                                         break;
4399                                 default:
4400                                         g_assert_not_reached ();
4401                                 }
4402                         }
4403                 }
4404                 g_assert ((p - (const unsigned char*)meta->tables [i].base) == (meta->tables [i].rows * meta->tables [i].row_size));
4405         }
4406         
4407         g_assert (assembly->guid.offset + assembly->guid.index < meta_size);
4408         memcpy (meta->raw_metadata + assembly->sheap.offset, assembly->sheap.data, assembly->sheap.index);
4409         memcpy (meta->raw_metadata + assembly->us.offset, assembly->us.data, assembly->us.index);
4410         memcpy (meta->raw_metadata + assembly->blob.offset, assembly->blob.data, assembly->blob.index);
4411         memcpy (meta->raw_metadata + assembly->guid.offset, assembly->guid.data, assembly->guid.index);
4412
4413         assembly->meta_size = assembly->guid.offset + assembly->guid.index;
4414
4415         return TRUE;
4416 }
4417
4418 /*
4419  * Some tables in metadata need to be sorted according to some criteria, but
4420  * when methods and fields are first created with reflection, they may be assigned a token
4421  * that doesn't correspond to the final token they will get assigned after the sorting.
4422  * ILGenerator.cs keeps a fixup table that maps the position of tokens in the IL code stream
4423  * with the reflection objects that represent them. Once all the tables are set up, the 
4424  * reflection objects will contains the correct table index. fixup_method() will fixup the
4425  * tokens for the method with ILGenerator @ilgen.
4426  */
4427 static void
4428 fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *assembly)
4429 {
4430         guint32 code_idx = GPOINTER_TO_UINT (value);
4431         MonoReflectionILTokenInfo *iltoken;
4432         MonoReflectionFieldBuilder *field;
4433         MonoReflectionCtorBuilder *ctor;
4434         MonoReflectionMethodBuilder *method;
4435         MonoReflectionTypeBuilder *tb;
4436         MonoReflectionArrayMethod *am;
4437         guint32 i, idx = 0;
4438         unsigned char *target;
4439
4440         for (i = 0; i < ilgen->num_token_fixups; ++i) {
4441                 iltoken = (MonoReflectionILTokenInfo *)mono_array_addr_with_size (ilgen->token_fixups, sizeof (MonoReflectionILTokenInfo), i);
4442                 target = (guchar*)assembly->code.data + code_idx + iltoken->code_pos;
4443                 switch (target [3]) {
4444                 case MONO_TABLE_FIELD:
4445                         if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
4446                                 field = (MonoReflectionFieldBuilder *)iltoken->member;
4447                                 idx = field->table_idx;
4448                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
4449                                 MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
4450                                 idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->field_to_table_idx, f));
4451                         } else {
4452                                 g_assert_not_reached ();
4453                         }
4454                         break;
4455                 case MONO_TABLE_METHOD:
4456                         if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
4457                                 method = (MonoReflectionMethodBuilder *)iltoken->member;
4458                                 idx = method->table_idx;
4459                         } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
4460                                 ctor = (MonoReflectionCtorBuilder *)iltoken->member;
4461                                 idx = ctor->table_idx;
4462                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") || 
4463                                            !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod")) {
4464                                 MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
4465                                 idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
4466                         } else {
4467                                 g_assert_not_reached ();
4468                         }
4469                         break;
4470                 case MONO_TABLE_TYPEDEF:
4471                         if (strcmp (iltoken->member->vtable->klass->name, "TypeBuilder"))
4472                                 g_assert_not_reached ();
4473                         tb = (MonoReflectionTypeBuilder *)iltoken->member;
4474                         idx = tb->table_idx;
4475                         break;
4476                 case MONO_TABLE_MEMBERREF:
4477                         if (!strcmp (iltoken->member->vtable->klass->name, "MonoArrayMethod")) {
4478                                 am = (MonoReflectionArrayMethod*)iltoken->member;
4479                                 idx = am->table_idx;
4480                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod") ||
4481                                    !strcmp (iltoken->member->vtable->klass->name, "MonoCMethod") ||
4482                                    !strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod") ||
4483                                    !strcmp (iltoken->member->vtable->klass->name, "MonoGenericCMethod")) {
4484                                 MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
4485                                 g_assert (m->klass->generic_class || m->klass->generic_container);
4486                                 continue;
4487                         } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
4488                                 continue;
4489                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
4490                                 MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
4491                                 g_assert (is_field_on_inst (f));
4492                                 continue;
4493                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder") ||
4494                                         !strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
4495                                 continue;
4496                         } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldOnTypeBuilderInst")) {
4497                                 continue;
4498                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
4499                                 continue;
4500                         } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorOnTypeBuilderInst")) {
4501                                 continue;
4502                         } else {
4503                                 g_assert_not_reached ();
4504                         }
4505                         break;
4506                 case MONO_TABLE_METHODSPEC:
4507                         if (!strcmp (iltoken->member->vtable->klass->name, "MonoGenericMethod")) {
4508                                 MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
4509                                 g_assert (mono_method_signature (m)->generic_param_count);
4510                                 continue;
4511                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
4512                                 continue;
4513                         } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) {
4514                                 continue;
4515                         } else {
4516                                 g_assert_not_reached ();
4517                         }
4518                         break;
4519                 default:
4520                         g_error ("got unexpected table 0x%02x in fixup", target [3]);
4521                 }
4522                 target [0] = idx & 0xff;
4523                 target [1] = (idx >> 8) & 0xff;
4524                 target [2] = (idx >> 16) & 0xff;
4525         }
4526 }
4527
4528 /*
4529  * fixup_cattrs:
4530  *
4531  *   The CUSTOM_ATTRIBUTE table might contain METHODDEF tokens whose final
4532  * value is not known when the table is emitted.
4533  */
4534 static void
4535 fixup_cattrs (MonoDynamicImage *assembly)
4536 {
4537         MonoDynamicTable *table;
4538         guint32 *values;
4539         guint32 type, i, idx, token;
4540         MonoObject *ctor;
4541
4542         table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
4543
4544         for (i = 0; i < table->rows; ++i) {
4545                 values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
4546
4547                 type = values [MONO_CUSTOM_ATTR_TYPE];
4548                 if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
4549                         idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
4550                         token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
4551                         ctor = (MonoObject *)mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token));
4552                         g_assert (ctor);
4553
4554                         if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
4555                                 MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
4556                                 idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
4557                                 values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
4558                         } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
4559                                 MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle;
4560                                 idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
4561                                 values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
4562                         }
4563                 }
4564         }
4565 }
4566
4567 static gboolean
4568 assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation, MonoError *error)
4569 {
4570         MonoDynamicTable *table;
4571         guint32 *values;
4572
4573         mono_error_init (error);
4574
4575         table = &assembly->tables [MONO_TABLE_MANIFESTRESOURCE];
4576         table->rows++;
4577         alloc_table (table, table->rows);
4578         values = table->values + table->next_idx * MONO_MANIFEST_SIZE;
4579         values [MONO_MANIFEST_OFFSET] = rsrc->offset;
4580         values [MONO_MANIFEST_FLAGS] = rsrc->attrs;
4581         values [MONO_MANIFEST_NAME] = string_heap_insert_mstring (&assembly->sheap, rsrc->name, error);
4582         return_val_if_nok (error, FALSE);
4583         values [MONO_MANIFEST_IMPLEMENTATION] = implementation;
4584         table->next_idx++;
4585         return TRUE;
4586 }
4587
4588 static gboolean
4589 assembly_add_resource (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, MonoError *error)
4590 {
4591         MonoDynamicTable *table;
4592         guint32 *values;
4593         char blob_size [6];
4594         guchar hash [20];
4595         char *b = blob_size;
4596         char *name, *sname;
4597         guint32 idx, offset;
4598
4599         mono_error_init (error);
4600
4601         if (rsrc->filename) {
4602                 name = mono_string_to_utf8_checked (rsrc->filename, error);
4603                 return_val_if_nok (error, FALSE);
4604                 sname = g_path_get_basename (name);
4605         
4606                 table = &assembly->tables [MONO_TABLE_FILE];
4607                 table->rows++;
4608                 alloc_table (table, table->rows);
4609                 values = table->values + table->next_idx * MONO_FILE_SIZE;
4610                 values [MONO_FILE_FLAGS] = FILE_CONTAINS_NO_METADATA;
4611                 values [MONO_FILE_NAME] = string_heap_insert (&assembly->sheap, sname);
4612                 g_free (sname);
4613
4614                 mono_sha1_get_digest_from_file (name, hash);
4615                 mono_metadata_encode_value (20, b, &b);
4616                 values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
4617                 mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
4618                 g_free (name);
4619                 idx = table->next_idx++;
4620                 rsrc->offset = 0;
4621                 idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS);
4622         } else {
4623                 char sizebuf [4];
4624                 char *data;
4625                 guint len;
4626                 if (rsrc->data) {
4627                         data = mono_array_addr (rsrc->data, char, 0);
4628                         len = mono_array_length (rsrc->data);
4629                 } else {
4630                         data = NULL;
4631                         len = 0;
4632                 }
4633                 offset = len;
4634                 sizebuf [0] = offset; sizebuf [1] = offset >> 8;
4635                 sizebuf [2] = offset >> 16; sizebuf [3] = offset >> 24;
4636                 rsrc->offset = mono_image_add_stream_data (&assembly->resources, sizebuf, 4);
4637                 mono_image_add_stream_data (&assembly->resources, data, len);
4638
4639                 if (!mb->is_main)
4640                         /* 
4641                          * The entry should be emitted into the MANIFESTRESOURCE table of 
4642                          * the main module, but that needs to reference the FILE table
4643                          * which isn't emitted yet.
4644                          */
4645                         return TRUE;
4646                 else
4647                         idx = 0;
4648         }
4649
4650         return assembly_add_resource_manifest (mb, assembly, rsrc, idx, error);
4651 }
4652
4653 static gboolean
4654 set_version_from_string (MonoString *version, guint32 *values, MonoError *error)
4655 {
4656         gchar *ver, *p, *str;
4657         guint32 i;
4658         
4659         mono_error_init (error);
4660
4661         values [MONO_ASSEMBLY_MAJOR_VERSION] = 0;
4662         values [MONO_ASSEMBLY_MINOR_VERSION] = 0;
4663         values [MONO_ASSEMBLY_REV_NUMBER] = 0;
4664         values [MONO_ASSEMBLY_BUILD_NUMBER] = 0;
4665         if (!version)
4666                 return TRUE;
4667         ver = str = mono_string_to_utf8_checked (version, error);
4668         return_val_if_nok (error, FALSE);
4669         for (i = 0; i < 4; ++i) {
4670                 values [MONO_ASSEMBLY_MAJOR_VERSION + i] = strtol (ver, &p, 10);
4671                 switch (*p) {
4672                 case '.':
4673                         p++;
4674                         break;
4675                 case '*':
4676                         /* handle Revision and Build */
4677                         p++;
4678                         break;
4679                 }
4680                 ver = p;
4681         }
4682         g_free (str);
4683         return TRUE;
4684 }
4685
4686 static guint32
4687 load_public_key (MonoArray *pkey, MonoDynamicImage *assembly) {
4688         gsize len;
4689         guint32 token = 0;
4690         char blob_size [6];
4691         char *b = blob_size;
4692
4693         if (!pkey)
4694                 return token;
4695
4696         len = mono_array_length (pkey);
4697         mono_metadata_encode_value (len, b, &b);
4698         token = mono_image_add_stream_data (&assembly->blob, blob_size, b - blob_size);
4699         mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, char, 0), len);
4700
4701         assembly->public_key = (guint8 *)g_malloc (len);
4702         memcpy (assembly->public_key, mono_array_addr (pkey, char, 0), len);
4703         assembly->public_key_len = len;
4704
4705         /* Special case: check for ECMA key (16 bytes) */
4706         if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, char, 0), len)) {
4707                 /* In this case we must reserve 128 bytes (1024 bits) for the signature */
4708                 assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH;
4709         } else if (len >= MONO_PUBLIC_KEY_HEADER_LENGTH + MONO_MINIMUM_PUBLIC_KEY_LENGTH) {
4710                 /* minimum key size (in 2.0) is 384 bits */
4711                 assembly->strong_name_size = len - MONO_PUBLIC_KEY_HEADER_LENGTH;
4712         } else {
4713                 /* FIXME - verifier */
4714                 g_warning ("Invalid public key length: %d bits (total: %d)", (int)MONO_PUBLIC_KEY_BIT_SIZE (len), (int)len);
4715                 assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH; /* to be safe */
4716         }
4717         assembly->strong_name = (char *)g_malloc0 (assembly->strong_name_size);
4718
4719         return token;
4720 }
4721
4722 static gboolean
4723 mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb, MonoError *error)
4724 {
4725         MonoDynamicTable *table;
4726         MonoDynamicImage *assembly;
4727         MonoReflectionAssemblyBuilder *assemblyb;
4728         MonoDomain *domain;
4729         guint32 *values;
4730         int i;
4731         guint32 module_index;
4732
4733         mono_error_init (error);
4734
4735         assemblyb = moduleb->assemblyb;
4736         assembly = moduleb->dynamic_image;
4737         domain = mono_object_domain (assemblyb);
4738
4739         /* Emit ASSEMBLY table */
4740         table = &assembly->tables [MONO_TABLE_ASSEMBLY];
4741         alloc_table (table, 1);
4742         values = table->values + MONO_ASSEMBLY_SIZE;
4743         values [MONO_ASSEMBLY_HASH_ALG] = assemblyb->algid? assemblyb->algid: ASSEMBLY_HASH_SHA1;
4744         values [MONO_ASSEMBLY_NAME] = string_heap_insert_mstring (&assembly->sheap, assemblyb->name, error);
4745         return_val_if_nok (error, FALSE);
4746         if (assemblyb->culture) {
4747                 values [MONO_ASSEMBLY_CULTURE] = string_heap_insert_mstring (&assembly->sheap, assemblyb->culture, error);
4748                 return_val_if_nok (error, FALSE);
4749         } else {
4750                 values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
4751         }
4752         values [MONO_ASSEMBLY_PUBLIC_KEY] = load_public_key (assemblyb->public_key, assembly);
4753         values [MONO_ASSEMBLY_FLAGS] = assemblyb->flags;
4754         if (!set_version_from_string (assemblyb->version, values, error))
4755                 return FALSE;
4756
4757         /* Emit FILE + EXPORTED_TYPE table */
4758         module_index = 0;
4759         for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4760                 int j;
4761                 MonoReflectionModuleBuilder *file_module = 
4762                         mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i);
4763                 if (file_module != moduleb) {
4764                         if (!mono_image_fill_file_table (domain, (MonoReflectionModule*)file_module, assembly, error))
4765                                 return FALSE;
4766                         module_index ++;
4767                         if (file_module->types) {
4768                                 for (j = 0; j < file_module->num_types; ++j) {
4769                                         MonoReflectionTypeBuilder *tb = mono_array_get (file_module->types, MonoReflectionTypeBuilder*, j);
4770                                         mono_image_fill_export_table (domain, tb, module_index, 0, assembly, error);
4771                                         return_val_if_nok (error, FALSE);
4772                                 }
4773                         }
4774                 }
4775         }
4776         if (assemblyb->loaded_modules) {
4777                 for (i = 0; i < mono_array_length (assemblyb->loaded_modules); ++i) {
4778                         MonoReflectionModule *file_module = 
4779                                 mono_array_get (assemblyb->loaded_modules, MonoReflectionModule*, i);
4780                         if (!mono_image_fill_file_table (domain, file_module, assembly, error))
4781                                 return FALSE;
4782                         module_index ++;
4783                         mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly);
4784                 }
4785         }
4786         if (assemblyb->type_forwarders)
4787                 mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly);
4788
4789         /* Emit MANIFESTRESOURCE table */
4790         module_index = 0;
4791         for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4792                 int j;
4793                 MonoReflectionModuleBuilder *file_module = 
4794                         mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i);
4795                 /* The table for the main module is emitted later */
4796                 if (file_module != moduleb) {
4797                         module_index ++;
4798                         if (file_module->resources) {
4799                                 int len = mono_array_length (file_module->resources);
4800                                 for (j = 0; j < len; ++j) {
4801                                         MonoReflectionResource* res = (MonoReflectionResource*)mono_array_addr (file_module->resources, MonoReflectionResource, j);
4802                                         if (!assembly_add_resource_manifest (file_module, assembly, res, MONO_IMPLEMENTATION_FILE | (module_index << MONO_IMPLEMENTATION_BITS), error))
4803                                                 return FALSE;
4804                                 }
4805                         }
4806                 }
4807         }
4808         return TRUE;
4809 }
4810
4811 #ifndef DISABLE_REFLECTION_EMIT_SAVE
4812
4813 /*
4814  * mono_image_build_metadata() will fill the info in all the needed metadata tables
4815  * for the modulebuilder @moduleb.
4816  * At the end of the process, method and field tokens are fixed up and the 
4817  * on-disk compressed metadata representation is created.
4818  * Return TRUE on success, or FALSE on failure and sets @error
4819  */
4820 gboolean
4821 mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb, MonoError *error)
4822 {
4823         MonoDynamicTable *table;
4824         MonoDynamicImage *assembly;
4825         MonoReflectionAssemblyBuilder *assemblyb;
4826         MonoDomain *domain;
4827         MonoPtrArray types;
4828         guint32 *values;
4829         int i, j;
4830
4831         mono_error_init (error);
4832
4833         assemblyb = moduleb->assemblyb;
4834         assembly = moduleb->dynamic_image;
4835         domain = mono_object_domain (assemblyb);
4836
4837         if (assembly->text_rva)
4838                 return TRUE;
4839
4840         assembly->text_rva = START_TEXT_RVA;
4841
4842         if (moduleb->is_main) {
4843                 mono_image_emit_manifest (moduleb, error);
4844                 return_val_if_nok (error, FALSE);
4845         }
4846
4847         table = &assembly->tables [MONO_TABLE_TYPEDEF];
4848         table->rows = 1; /* .<Module> */
4849         table->next_idx++;
4850         alloc_table (table, table->rows);
4851         /*
4852          * Set the first entry.
4853          */
4854         values = table->values + table->columns;
4855         values [MONO_TYPEDEF_FLAGS] = 0;
4856         values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, "<Module>") ;
4857         values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, "") ;
4858         values [MONO_TYPEDEF_EXTENDS] = 0;
4859         values [MONO_TYPEDEF_FIELD_LIST] = 1;
4860         values [MONO_TYPEDEF_METHOD_LIST] = 1;
4861
4862         /* 
4863          * handle global methods 
4864          * FIXME: test what to do when global methods are defined in multiple modules.
4865          */
4866         if (moduleb->global_methods) {
4867                 table = &assembly->tables [MONO_TABLE_METHOD];
4868                 table->rows += mono_array_length (moduleb->global_methods);
4869                 alloc_table (table, table->rows);
4870                 for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
4871                         if (!mono_image_get_method_info (
4872                                     mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i), assembly, error))
4873                                 goto leave;
4874                 }
4875         }
4876         if (moduleb->global_fields) {
4877                 table = &assembly->tables [MONO_TABLE_FIELD];
4878                 table->rows += mono_array_length (moduleb->global_fields);
4879                 alloc_table (table, table->rows);
4880                 for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
4881                         mono_image_get_field_info (
4882                                 mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i), assembly,
4883                                 error);
4884                         if (!is_ok (error))
4885                                 goto leave;
4886                 }
4887         }
4888
4889         table = &assembly->tables [MONO_TABLE_MODULE];
4890         alloc_table (table, 1);
4891         mono_image_fill_module_table (domain, moduleb, assembly, error);
4892         if (!is_ok (error))
4893                 goto leave;
4894
4895         /* Collect all types into a list sorted by their table_idx */
4896         mono_ptr_array_init (types, moduleb->num_types, MONO_ROOT_SOURCE_REFLECTION, "dynamic module types list");
4897
4898         if (moduleb->types)
4899                 for (i = 0; i < moduleb->num_types; ++i) {
4900                         MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
4901                         collect_types (&types, type);
4902                 }
4903
4904         mono_ptr_array_sort (types, (int (*)(const void *, const void *))compare_types_by_table_idx);
4905         table = &assembly->tables [MONO_TABLE_TYPEDEF];
4906         table->rows += mono_ptr_array_size (types);
4907         alloc_table (table, table->rows);
4908
4909         /*
4910          * Emit type names + namespaces at one place inside the string heap,
4911          * so load_class_names () needs to touch fewer pages.
4912          */
4913         for (i = 0; i < mono_ptr_array_size (types); ++i) {
4914                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
4915                 string_heap_insert_mstring (&assembly->sheap, tb->nspace, error);
4916                 if (!is_ok (error))
4917                         goto leave_types;
4918         }
4919         for (i = 0; i < mono_ptr_array_size (types); ++i) {
4920                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
4921                 string_heap_insert_mstring (&assembly->sheap, tb->name, error);
4922                 if (!is_ok (error))
4923                         goto leave_types;
4924         }
4925
4926         for (i = 0; i < mono_ptr_array_size (types); ++i) {
4927                 MonoReflectionTypeBuilder *type = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
4928                 if (!mono_image_get_type_info (domain, type, assembly, error))
4929                         goto leave_types;
4930         }
4931
4932         /* 
4933          * table->rows is already set above and in mono_image_fill_module_table.
4934          */
4935         /* add all the custom attributes at the end, once all the indexes are stable */
4936         if (!mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs, error))
4937                 goto leave_types;
4938
4939         /* CAS assembly permissions */
4940         if (assemblyb->permissions_minimum)
4941                 mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_minimum);
4942         if (assemblyb->permissions_optional)
4943                 mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_optional);
4944         if (assemblyb->permissions_refused)
4945                 mono_image_add_decl_security (assembly, mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1), assemblyb->permissions_refused);
4946
4947         if (!module_add_cattrs (assembly, moduleb, error))
4948                 goto leave_types;
4949
4950         /* fixup tokens */
4951         mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
4952
4953         /* Create the MethodImpl table.  We do this after emitting all methods so we already know
4954          * the final tokens and don't need another fixup pass. */
4955
4956         if (moduleb->global_methods) {
4957                 for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
4958                         MonoReflectionMethodBuilder *mb = mono_array_get (
4959                                 moduleb->global_methods, MonoReflectionMethodBuilder*, i);
4960                         if (!mono_image_add_methodimpl (assembly, mb, error))
4961                                 goto leave_types;
4962                 }
4963         }
4964
4965         for (i = 0; i < mono_ptr_array_size (types); ++i) {
4966                 MonoReflectionTypeBuilder *type = (MonoReflectionTypeBuilder *)mono_ptr_array_get (types, i);
4967                 if (type->methods) {
4968                         for (j = 0; j < type->num_methods; ++j) {
4969                                 MonoReflectionMethodBuilder *mb = mono_array_get (
4970                                         type->methods, MonoReflectionMethodBuilder*, j);
4971
4972                                 if (!mono_image_add_methodimpl (assembly, mb, error))
4973                                         goto leave_types;
4974                         }
4975                 }
4976         }
4977
4978         fixup_cattrs (assembly);
4979
4980 leave_types:
4981         mono_ptr_array_destroy (types);
4982 leave:
4983
4984         return mono_error_ok (error);
4985 }
4986
4987 #else /* DISABLE_REFLECTION_EMIT_SAVE */
4988
4989 gboolean
4990 mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb, MonoError *error)
4991 {
4992         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit_save, so saving of dynamic assemblies is not supported.");
4993 }
4994
4995 #endif /* DISABLE_REFLECTION_EMIT_SAVE */
4996
4997
4998 #ifndef DISABLE_REFLECTION_EMIT
4999
5000 /*
5001  * mono_image_insert_string:
5002  * @module: module builder object
5003  * @str: a string
5004  *
5005  * Insert @str into the user string stream of @module.
5006  */
5007 guint32
5008 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
5009 {
5010         MonoDynamicImage *assembly;
5011         guint32 idx;
5012         char buf [16];
5013         char *b = buf;
5014         
5015         if (!module->dynamic_image)
5016                 mono_image_module_basic_init (module);
5017
5018         assembly = module->dynamic_image;
5019         
5020         if (assembly->save) {
5021                 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
5022                 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
5023 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
5024         {
5025                 char *swapped = g_malloc (2 * mono_string_length (str));
5026                 const char *p = (const char*)mono_string_chars (str);
5027
5028                 swap_with_size (swapped, p, 2, mono_string_length (str));
5029                 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
5030                 g_free (swapped);
5031         }
5032 #else
5033                 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
5034 #endif
5035                 mono_image_add_stream_data (&assembly->us, "", 1);
5036         } else {
5037                 idx = assembly->us.index ++;
5038         }
5039
5040         mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
5041
5042         return MONO_TOKEN_STRING | idx;
5043 }
5044
5045 guint32
5046 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
5047 {
5048         MonoClass *klass;
5049         guint32 token = 0;
5050         MonoMethodSignature *sig;
5051
5052         mono_error_init (error);
5053
5054         klass = obj->vtable->klass;
5055         if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
5056                 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
5057                 MonoMethodSignature *old;
5058                 guint32 sig_token, parent;
5059                 int nargs, i;
5060
5061                 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
5062
5063                 nargs = mono_array_length (opt_param_types);
5064                 old = mono_method_signature (method);
5065                 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
5066
5067                 sig->hasthis = old->hasthis;
5068                 sig->explicit_this = old->explicit_this;
5069                 sig->call_convention = old->call_convention;
5070                 sig->generic_param_count = old->generic_param_count;
5071                 sig->param_count = old->param_count + nargs;
5072                 sig->sentinelpos = old->param_count;
5073                 sig->ret = old->ret;
5074
5075                 for (i = 0; i < old->param_count; i++)
5076                         sig->params [i] = old->params [i];
5077
5078                 for (i = 0; i < nargs; i++) {
5079                         MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
5080                         sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
5081                         if (!is_ok (error)) goto fail;
5082                 }
5083
5084                 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
5085                 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
5086                 parent >>= MONO_TYPEDEFORREF_BITS;
5087
5088                 parent <<= MONO_MEMBERREF_PARENT_BITS;
5089                 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
5090
5091                 sig_token = method_encode_signature (assembly, sig);
5092                 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
5093         } else if (strcmp (klass->name, "MethodBuilder") == 0) {
5094                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
5095                 ReflectionMethodBuilder rmb;
5096                 guint32 parent, sig_token;
5097                 int nopt_args, nparams, ngparams, i;
5098
5099                 if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
5100                         goto fail;
5101                 
5102                 rmb.opt_types = opt_param_types;
5103                 nopt_args = mono_array_length (opt_param_types);
5104
5105                 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
5106                 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
5107                 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
5108
5109                 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
5110                 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
5111                 sig->call_convention = rmb.call_conv;
5112                 sig->generic_param_count = ngparams;
5113                 sig->param_count = nparams + nopt_args;
5114                 sig->sentinelpos = nparams;
5115                 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
5116                 if (!is_ok (error)) goto fail;
5117
5118                 for (i = 0; i < nparams; i++) {
5119                         MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
5120                         sig->params [i] = mono_reflection_type_get_handle (rt, error);
5121                         if (!is_ok (error)) goto fail;
5122                 }
5123
5124                 for (i = 0; i < nopt_args; i++) {
5125                         MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
5126                         sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
5127                         if (!is_ok (error)) goto fail;
5128                 }
5129
5130                 sig_token = method_builder_encode_signature (assembly, &rmb, error);
5131                 if (!is_ok (error))
5132                         goto fail;
5133
5134                 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
5135                 if (!mono_error_ok (error))
5136                         goto fail;
5137                 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
5138
5139                 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
5140                 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
5141
5142                 char *name = mono_string_to_utf8_checked (rmb.name, error);
5143                 if (!is_ok (error)) goto fail;
5144                 token = mono_image_get_varargs_method_token (
5145                         assembly, parent, name, sig_token);
5146                 g_free (name);
5147         } else {
5148                 g_error ("requested method token for %s\n", klass->name);
5149         }
5150
5151         g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
5152         mono_dynamic_image_register_token (assembly, token, obj);
5153         return token;
5154 fail:
5155         g_assert (!mono_error_ok (error));
5156         return 0;
5157 }
5158
5159 /*
5160  * mono_image_create_token:
5161  * @assembly: a dynamic assembly
5162  * @obj:
5163  * @register_token: Whenever to register the token in the assembly->tokens hash. 
5164  *
5165  * Get a token to insert in the IL code stream for the given MemberInfo.
5166  * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, 
5167  * the table_idx-es were recomputed, so registering the token would overwrite an existing 
5168  * entry.
5169  */
5170 guint32
5171 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
5172                          gboolean create_open_instance, gboolean register_token,
5173                          MonoError *error)
5174 {
5175         MonoClass *klass;
5176         guint32 token = 0;
5177
5178         mono_error_init (error);
5179
5180         klass = obj->vtable->klass;
5181
5182         /* Check for user defined reflection objects */
5183         /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
5184         if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
5185                 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
5186                 return 0;
5187         }
5188
5189         if (strcmp (klass->name, "MethodBuilder") == 0) {
5190                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
5191                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
5192
5193                 if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
5194                         token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
5195                 else {
5196                         token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance, error);
5197                         if (!mono_error_ok (error))
5198                                 return 0;
5199                 }
5200                 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
5201         } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
5202                 MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
5203                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
5204
5205                 if (tb->module->dynamic_image == assembly && !tb->generic_params)
5206                         token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
5207                 else {
5208                         token = mono_image_get_ctorbuilder_token (assembly, mb, error);
5209                         if (!mono_error_ok (error))
5210                                 return 0;
5211                 }
5212                 /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
5213         } else if (strcmp (klass->name, "FieldBuilder") == 0) {
5214                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
5215                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
5216                 if (tb->generic_params) {
5217                         token = mono_image_get_generic_field_token (assembly, fb, error);
5218                         return_val_if_nok (error, 0);
5219                 } else {
5220                         if (tb->module->dynamic_image == assembly) {
5221                                 token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
5222                         } else {
5223                                 token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
5224                         }
5225                 }
5226         } else if (strcmp (klass->name, "TypeBuilder") == 0) {
5227                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
5228                 if (create_open_instance && tb->generic_params) {
5229                         MonoType *type;
5230                         init_type_builder_generics (obj, error);
5231                         return_val_if_nok (error, 0);
5232                         type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5233                         return_val_if_nok (error, 0);
5234                         token = mono_image_typedef_or_ref_full (assembly, type, TRUE);
5235                         token = mono_metadata_token_from_dor (token);
5236                 } else if (tb->module->dynamic_image == assembly) {
5237                         token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
5238                 } else {
5239                         MonoType *type;
5240                         type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5241                         return_val_if_nok (error, 0);
5242                         token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
5243                 }
5244         } else if (strcmp (klass->name, "RuntimeType") == 0) {
5245                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5246                 return_val_if_nok (error, 0);
5247                 MonoClass *mc = mono_class_from_mono_type (type);
5248                 token = mono_metadata_token_from_dor (
5249                         mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
5250         } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
5251                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5252                 return_val_if_nok (error, 0);
5253                 token = mono_metadata_token_from_dor (
5254                         mono_image_typedef_or_ref (assembly, type));
5255         } else if (strcmp (klass->name, "MonoGenericClass") == 0) {
5256                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5257                 return_val_if_nok (error, 0);
5258                 token = mono_metadata_token_from_dor (
5259                         mono_image_typedef_or_ref (assembly, type));
5260         } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
5261                    strcmp (klass->name, "MonoMethod") == 0 ||
5262                    strcmp (klass->name, "MonoGenericMethod") == 0 ||
5263                    strcmp (klass->name, "MonoGenericCMethod") == 0) {
5264                 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
5265                 if (m->method->is_inflated) {
5266                         if (create_open_instance)
5267                                 token = mono_image_get_methodspec_token (assembly, m->method);
5268                         else
5269                                 token = mono_image_get_inflated_method_token (assembly, m->method);
5270                 } else if ((m->method->klass->image == &assembly->image) &&
5271                          !m->method->klass->generic_class) {
5272                         static guint32 method_table_idx = 0xffffff;
5273                         if (m->method->klass->wastypebuilder) {
5274                                 /* we use the same token as the one that was assigned
5275                                  * to the Methodbuilder.
5276                                  * FIXME: do the equivalent for Fields.
5277                                  */
5278                                 token = m->method->token;
5279                         } else {
5280                                 /*
5281                                  * Each token should have a unique index, but the indexes are
5282                                  * assigned by managed code, so we don't know about them. An
5283                                  * easy solution is to count backwards...
5284                                  */
5285                                 method_table_idx --;
5286                                 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
5287                         }
5288                 } else {
5289                         token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
5290                 }
5291                 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
5292         } else if (strcmp (klass->name, "MonoField") == 0) {
5293                 MonoReflectionField *f = (MonoReflectionField *)obj;
5294                 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
5295                         static guint32 field_table_idx = 0xffffff;
5296                         field_table_idx --;
5297                         token = MONO_TOKEN_FIELD_DEF | field_table_idx;
5298                 } else {
5299                         token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
5300                 }
5301                 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
5302         } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
5303                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
5304                 token = mono_image_get_array_token (assembly, m, error);
5305                 return_val_if_nok (error, 0);
5306         } else if (strcmp (klass->name, "SignatureHelper") == 0) {
5307                 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
5308                 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
5309                 return_val_if_nok (error, 0);
5310         } else if (strcmp (klass->name, "EnumBuilder") == 0) {
5311                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5312                 return_val_if_nok (error, 0);
5313                 token = mono_metadata_token_from_dor (
5314                         mono_image_typedef_or_ref (assembly, type));
5315         } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
5316                 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
5317                 token = mono_image_get_field_on_inst_token (assembly, f, error);
5318                 return_val_if_nok (error, 0);
5319         } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
5320                 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
5321                 token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance, error);
5322                 if (!mono_error_ok (error))
5323                         return 0;
5324         } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
5325                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
5326                 token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance, error);
5327                 if (!mono_error_ok (error))
5328                         return 0;
5329         } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
5330                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
5331                 return_val_if_nok (error, 0);
5332                 token = mono_metadata_token_from_dor (
5333                                 mono_image_typedef_or_ref (assembly, type));
5334         } else {
5335                 g_error ("requested token for %s\n", klass->name);
5336         }
5337
5338         if (register_token)
5339                 mono_image_register_token (assembly, token, obj);
5340
5341         return token;
5342 }
5343
5344
5345 #endif
5346
5347 #ifndef DISABLE_REFLECTION_EMIT
5348
5349 /*
5350  * mono_image_basic_init:
5351  * @assembly: an assembly builder object
5352  *
5353  * Create the MonoImage that represents the assembly builder and setup some
5354  * of the helper hash table and the basic metadata streams.
5355  */
5356 static void
5357 mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
5358 {
5359         MonoError error;
5360         MonoDynamicAssembly *assembly;
5361         MonoDynamicImage *image;
5362         MonoDomain *domain = mono_object_domain (assemblyb);
5363         
5364         if (assemblyb->dynamic_assembly)
5365                 return;
5366
5367 #if HAVE_BOEHM_GC
5368         /* assembly->assembly.image might be GC allocated */
5369         assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
5370 #else
5371         assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
5372 #endif
5373
5374         mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
5375         
5376         assembly->assembly.ref_count = 1;
5377         assembly->assembly.dynamic = TRUE;
5378         assembly->assembly.corlib_internal = assemblyb->corlib_internal;
5379         assemblyb->assembly.assembly = (MonoAssembly*)assembly;
5380         assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
5381         if (mono_error_set_pending_exception (&error))
5382                 return;
5383         if (assemblyb->culture) {
5384                 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
5385                 if (mono_error_set_pending_exception (&error))
5386                         return;
5387         } else
5388                 assembly->assembly.aname.culture = g_strdup ("");
5389
5390         if (assemblyb->version) {
5391                         char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
5392                         if (mono_error_set_pending_exception (&error))
5393                                 return;
5394                         char **version = g_strsplit (vstr, ".", 4);
5395                         char **parts = version;
5396                         assembly->assembly.aname.major = atoi (*parts++);
5397                         assembly->assembly.aname.minor = atoi (*parts++);
5398                         assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
5399                         assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
5400
5401                         g_strfreev (version);
5402                         g_free (vstr);
5403         } else {
5404                         assembly->assembly.aname.major = 0;
5405                         assembly->assembly.aname.minor = 0;
5406                         assembly->assembly.aname.build = 0;
5407                         assembly->assembly.aname.revision = 0;
5408         }
5409
5410         assembly->run = assemblyb->access != 2;
5411         assembly->save = assemblyb->access != 1;
5412         assembly->domain = domain;
5413
5414         char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
5415         if (mono_error_set_pending_exception (&error))
5416                 return;
5417         image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
5418         image->initial_image = TRUE;
5419         assembly->assembly.aname.name = image->image.name;
5420         assembly->assembly.image = &image->image;
5421         if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
5422                 /* -1 to correct for the trailing NULL byte */
5423                 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
5424                         g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
5425                 }
5426                 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);           
5427         }
5428
5429         mono_domain_assemblies_lock (domain);
5430         domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
5431         mono_domain_assemblies_unlock (domain);
5432
5433         register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
5434         
5435         mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
5436         
5437         mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
5438 }
5439
5440 #endif /* !DISABLE_REFLECTION_EMIT */
5441
5442 #ifndef DISABLE_REFLECTION_EMIT_SAVE
5443
5444 static int
5445 calc_section_size (MonoDynamicImage *assembly)
5446 {
5447         int nsections = 0;
5448
5449         /* alignment constraints */
5450         mono_image_add_stream_zero (&assembly->code, 4 - (assembly->code.index % 4));
5451         g_assert ((assembly->code.index % 4) == 0);
5452         assembly->meta_size += 3;
5453         assembly->meta_size &= ~3;
5454         mono_image_add_stream_zero (&assembly->resources, 4 - (assembly->resources.index % 4));
5455         g_assert ((assembly->resources.index % 4) == 0);
5456
5457         assembly->sections [MONO_SECTION_TEXT].size = assembly->meta_size + assembly->code.index + assembly->resources.index + assembly->strong_name_size;
5458         assembly->sections [MONO_SECTION_TEXT].attrs = SECT_FLAGS_HAS_CODE | SECT_FLAGS_MEM_EXECUTE | SECT_FLAGS_MEM_READ;
5459         nsections++;
5460
5461         if (assembly->win32_res) {
5462                 guint32 res_size = (assembly->win32_res_size + 3) & ~3;
5463
5464                 assembly->sections [MONO_SECTION_RSRC].size = res_size;
5465                 assembly->sections [MONO_SECTION_RSRC].attrs = SECT_FLAGS_HAS_INITIALIZED_DATA | SECT_FLAGS_MEM_READ;
5466                 nsections++;
5467         }
5468
5469         assembly->sections [MONO_SECTION_RELOC].size = 12;
5470         assembly->sections [MONO_SECTION_RELOC].attrs = SECT_FLAGS_MEM_READ | SECT_FLAGS_MEM_DISCARDABLE | SECT_FLAGS_HAS_INITIALIZED_DATA;
5471         nsections++;
5472
5473         return nsections;
5474 }
5475
5476 typedef struct {
5477         guint32 id;
5478         guint32 offset;
5479         GSList *children;
5480         MonoReflectionWin32Resource *win32_res; /* Only for leaf nodes */
5481 } ResTreeNode;
5482
5483 static int
5484 resource_tree_compare_by_id (gconstpointer a, gconstpointer b)
5485 {
5486         ResTreeNode *t1 = (ResTreeNode*)a;
5487         ResTreeNode *t2 = (ResTreeNode*)b;
5488
5489         return t1->id - t2->id;
5490 }
5491
5492 /*
5493  * resource_tree_create:
5494  *
5495  *  Organize the resources into a resource tree.
5496  */
5497 static ResTreeNode *
5498 resource_tree_create (MonoArray *win32_resources)
5499 {
5500         ResTreeNode *tree, *res_node, *type_node, *lang_node;
5501         GSList *l;
5502         int i;
5503
5504         tree = g_new0 (ResTreeNode, 1);
5505         
5506         for (i = 0; i < mono_array_length (win32_resources); ++i) {
5507                 MonoReflectionWin32Resource *win32_res =
5508                         (MonoReflectionWin32Resource*)mono_array_addr (win32_resources, MonoReflectionWin32Resource, i);
5509
5510                 /* Create node */
5511
5512                 /* FIXME: BUG: this stores managed references in unmanaged memory */
5513                 lang_node = g_new0 (ResTreeNode, 1);
5514                 lang_node->id = win32_res->lang_id;
5515                 lang_node->win32_res = win32_res;
5516
5517                 /* Create type node if neccesary */
5518                 type_node = NULL;
5519                 for (l = tree->children; l; l = l->next)
5520                         if (((ResTreeNode*)(l->data))->id == win32_res->res_type) {
5521                                 type_node = (ResTreeNode*)l->data;
5522                                 break;
5523                         }
5524
5525                 if (!type_node) {
5526                         type_node = g_new0 (ResTreeNode, 1);
5527                         type_node->id = win32_res->res_type;
5528
5529                         /* 
5530                          * The resource types have to be sorted otherwise
5531                          * Windows Explorer can't display the version information.
5532                          */
5533                         tree->children = g_slist_insert_sorted (tree->children, 
5534                                 type_node, resource_tree_compare_by_id);
5535                 }
5536
5537                 /* Create res node if neccesary */
5538                 res_node = NULL;
5539                 for (l = type_node->children; l; l = l->next)
5540                         if (((ResTreeNode*)(l->data))->id == win32_res->res_id) {
5541                                 res_node = (ResTreeNode*)l->data;
5542                                 break;
5543                         }
5544
5545                 if (!res_node) {
5546                         res_node = g_new0 (ResTreeNode, 1);
5547                         res_node->id = win32_res->res_id;
5548                         type_node->children = g_slist_append (type_node->children, res_node);
5549                 }
5550
5551                 res_node->children = g_slist_append (res_node->children, lang_node);
5552         }
5553
5554         return tree;
5555 }
5556
5557 /*
5558  * resource_tree_encode:
5559  * 
5560  *   Encode the resource tree into the format used in the PE file.
5561  */
5562 static void
5563 resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
5564 {
5565         char *entries;
5566         MonoPEResourceDir dir;
5567         MonoPEResourceDirEntry dir_entry;
5568         MonoPEResourceDataEntry data_entry;
5569         GSList *l;
5570         guint32 res_id_entries;
5571
5572         /*
5573          * For the format of the resource directory, see the article
5574          * "An In-Depth Look into the Win32 Portable Executable File Format" by
5575          * Matt Pietrek
5576          */
5577
5578         memset (&dir, 0, sizeof (dir));
5579         memset (&dir_entry, 0, sizeof (dir_entry));
5580         memset (&data_entry, 0, sizeof (data_entry));
5581
5582         g_assert (sizeof (dir) == 16);
5583         g_assert (sizeof (dir_entry) == 8);
5584         g_assert (sizeof (data_entry) == 16);
5585
5586         node->offset = p - begin;
5587
5588         /* IMAGE_RESOURCE_DIRECTORY */
5589         res_id_entries = g_slist_length (node->children);
5590         dir.res_id_entries = GUINT16_TO_LE (res_id_entries);
5591
5592         memcpy (p, &dir, sizeof (dir));
5593         p += sizeof (dir);
5594
5595         /* Reserve space for entries */
5596         entries = p;
5597         p += sizeof (dir_entry) * res_id_entries;
5598
5599         /* Write children */
5600         for (l = node->children; l; l = l->next) {
5601                 ResTreeNode *child = (ResTreeNode*)l->data;
5602
5603                 if (child->win32_res) {
5604                         guint32 size;
5605
5606                         child->offset = p - begin;
5607
5608                         /* IMAGE_RESOURCE_DATA_ENTRY */
5609                         data_entry.rde_data_offset = GUINT32_TO_LE (p - begin + sizeof (data_entry));
5610                         size = mono_array_length (child->win32_res->res_data);
5611                         data_entry.rde_size = GUINT32_TO_LE (size);
5612
5613                         memcpy (p, &data_entry, sizeof (data_entry));
5614                         p += sizeof (data_entry);
5615
5616                         memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), size);
5617                         p += size;
5618                 } else {
5619                         resource_tree_encode (child, begin, p, &p);
5620                 }
5621         }
5622
5623         /* IMAGE_RESOURCE_ENTRY */
5624         for (l = node->children; l; l = l->next) {
5625                 ResTreeNode *child = (ResTreeNode*)l->data;
5626
5627                 MONO_PE_RES_DIR_ENTRY_SET_NAME (dir_entry, FALSE, child->id);
5628                 MONO_PE_RES_DIR_ENTRY_SET_DIR (dir_entry, !child->win32_res, child->offset);
5629
5630                 memcpy (entries, &dir_entry, sizeof (dir_entry));
5631                 entries += sizeof (dir_entry);
5632         }
5633
5634         *endbuf = p;
5635 }
5636
5637 static void
5638 resource_tree_free (ResTreeNode * node)
5639 {
5640         GSList * list;
5641         for (list = node->children; list; list = list->next)
5642                 resource_tree_free ((ResTreeNode*)list->data);
5643         g_slist_free(node->children);
5644         g_free (node);
5645 }
5646
5647 static void
5648 assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssemblyBuilder *assemblyb)
5649 {
5650         char *buf;
5651         char *p;
5652         guint32 size, i;
5653         MonoReflectionWin32Resource *win32_res;
5654         ResTreeNode *tree;
5655
5656         if (!assemblyb->win32_resources)
5657                 return;
5658
5659         /*
5660          * Resources are stored in a three level tree inside the PE file.
5661          * - level one contains a node for each type of resource
5662          * - level two contains a node for each resource
5663          * - level three contains a node for each instance of a resource for a
5664          *   specific language.
5665          */
5666
5667         tree = resource_tree_create (assemblyb->win32_resources);
5668
5669         /* Estimate the size of the encoded tree */
5670         size = 0;
5671         for (i = 0; i < mono_array_length (assemblyb->win32_resources); ++i) {
5672                 win32_res = (MonoReflectionWin32Resource*)mono_array_addr (assemblyb->win32_resources, MonoReflectionWin32Resource, i);
5673                 size += mono_array_length (win32_res->res_data);
5674         }
5675         /* Directory structure */
5676         size += mono_array_length (assemblyb->win32_resources) * 256;
5677         p = buf = (char *)g_malloc (size);
5678
5679         resource_tree_encode (tree, p, p, &p);
5680
5681         g_assert (p - buf <= size);
5682
5683         assembly->win32_res = (char *)g_malloc (p - buf);
5684         assembly->win32_res_size = p - buf;
5685         memcpy (assembly->win32_res, buf, p - buf);
5686
5687         g_free (buf);
5688         resource_tree_free (tree);
5689 }
5690
5691 static void
5692 fixup_resource_directory (char *res_section, char *p, guint32 rva)
5693 {
5694         MonoPEResourceDir *dir = (MonoPEResourceDir*)p;
5695         int i;
5696
5697         p += sizeof (MonoPEResourceDir);
5698         for (i = 0; i < GUINT16_FROM_LE (dir->res_named_entries) + GUINT16_FROM_LE (dir->res_id_entries); ++i) {
5699                 MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p;
5700                 char *child = res_section + MONO_PE_RES_DIR_ENTRY_DIR_OFFSET (*dir_entry);
5701                 if (MONO_PE_RES_DIR_ENTRY_IS_DIR (*dir_entry)) {
5702                         fixup_resource_directory (res_section, child, rva);
5703                 } else {
5704                         MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child;
5705                         data_entry->rde_data_offset = GUINT32_TO_LE (GUINT32_FROM_LE (data_entry->rde_data_offset) + rva);
5706                 }
5707
5708                 p += sizeof (MonoPEResourceDirEntry);
5709         }
5710 }
5711
5712 static void
5713 checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
5714 {
5715         guint32 dummy;
5716         if (!WriteFile (f, buffer, numbytes, &dummy, NULL))
5717                 g_error ("WriteFile returned %d\n", GetLastError ());
5718 }
5719
5720 /*
5721  * mono_image_create_pefile:
5722  * @mb: a module builder object
5723  * 
5724  * This function creates the PE-COFF header, the image sections, the CLI header  * etc. all the data is written in
5725  * assembly->pefile where it can be easily retrieved later in chunks.
5726  */
5727 gboolean
5728 mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file, MonoError *error)
5729 {
5730         MonoMSDOSHeader *msdos;
5731         MonoDotNetHeader *header;
5732         MonoSectionTable *section;
5733         MonoCLIHeader *cli_header;
5734         guint32 size, image_size, virtual_base, text_offset;
5735         guint32 header_start, section_start, file_offset, virtual_offset;
5736         MonoDynamicImage *assembly;
5737         MonoReflectionAssemblyBuilder *assemblyb;
5738         MonoDynamicStream pefile_stream = {0};
5739         MonoDynamicStream *pefile = &pefile_stream;
5740         int i, nsections;
5741         guint32 *rva, value;
5742         guchar *p;
5743         static const unsigned char msheader[] = {
5744                 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,  0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
5745                 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5746                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5747                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
5748                 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,  0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
5749                 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,  0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
5750                 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e,  0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
5751                 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5752         };
5753
5754         mono_error_init (error);
5755
5756         assemblyb = mb->assemblyb;
5757
5758         mono_image_basic_init (assemblyb);
5759         assembly = mb->dynamic_image;
5760
5761         assembly->pe_kind = assemblyb->pe_kind;
5762         assembly->machine = assemblyb->machine;
5763         ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->pe_kind = assemblyb->pe_kind;
5764         ((MonoDynamicImage*)assemblyb->dynamic_assembly->assembly.image)->machine = assemblyb->machine;
5765         
5766         if (!mono_image_build_metadata (mb, error))
5767                 return FALSE;
5768         
5769
5770         if (mb->is_main && assemblyb->resources) {
5771                 int len = mono_array_length (assemblyb->resources);
5772                 for (i = 0; i < len; ++i) {
5773                         if (!assembly_add_resource (mb, assembly, (MonoReflectionResource*)mono_array_addr (assemblyb->resources, MonoReflectionResource, i), error))
5774                                 return FALSE;
5775                 }
5776         }
5777
5778         if (mb->resources) {
5779                 int len = mono_array_length (mb->resources);
5780                 for (i = 0; i < len; ++i) {
5781                         if (!assembly_add_resource (mb, assembly, (MonoReflectionResource*)mono_array_addr (mb->resources, MonoReflectionResource, i), error))
5782                                 return FALSE;
5783                 }
5784         }
5785
5786         if (!build_compressed_metadata (assembly, error))
5787                 return FALSE;
5788
5789         if (mb->is_main)
5790                 assembly_add_win32_resources (assembly, assemblyb);
5791
5792         nsections = calc_section_size (assembly);
5793         
5794         /* The DOS header and stub */
5795         g_assert (sizeof (MonoMSDOSHeader) == sizeof (msheader));
5796         mono_image_add_stream_data (pefile, (char*)msheader, sizeof (msheader));
5797
5798         /* the dotnet header */
5799         header_start = mono_image_add_stream_zero (pefile, sizeof (MonoDotNetHeader));
5800
5801         /* the section tables */
5802         section_start = mono_image_add_stream_zero (pefile, sizeof (MonoSectionTable) * nsections);
5803
5804         file_offset = section_start + sizeof (MonoSectionTable) * nsections;
5805         virtual_offset = VIRT_ALIGN;
5806         image_size = 0;
5807
5808         for (i = 0; i < MONO_SECTION_MAX; ++i) {
5809                 if (!assembly->sections [i].size)
5810                         continue;
5811                 /* align offsets */
5812                 file_offset += FILE_ALIGN - 1;
5813                 file_offset &= ~(FILE_ALIGN - 1);
5814                 virtual_offset += VIRT_ALIGN - 1;
5815                 virtual_offset &= ~(VIRT_ALIGN - 1);
5816
5817                 assembly->sections [i].offset = file_offset;
5818                 assembly->sections [i].rva = virtual_offset;
5819
5820                 file_offset += assembly->sections [i].size;
5821                 virtual_offset += assembly->sections [i].size;
5822                 image_size += (assembly->sections [i].size + VIRT_ALIGN - 1) & ~(VIRT_ALIGN - 1);
5823         }
5824
5825         file_offset += FILE_ALIGN - 1;
5826         file_offset &= ~(FILE_ALIGN - 1);
5827
5828         image_size += section_start + sizeof (MonoSectionTable) * nsections;
5829
5830         /* back-patch info */
5831         msdos = (MonoMSDOSHeader*)pefile->data;
5832         msdos->pe_offset = GUINT32_FROM_LE (sizeof (MonoMSDOSHeader));
5833
5834         header = (MonoDotNetHeader*)(pefile->data + header_start);
5835         header->pesig [0] = 'P';
5836         header->pesig [1] = 'E';
5837         
5838         header->coff.coff_machine = GUINT16_FROM_LE (assemblyb->machine);
5839         header->coff.coff_sections = GUINT16_FROM_LE (nsections);
5840         header->coff.coff_time = GUINT32_FROM_LE (time (NULL));
5841         header->coff.coff_opt_header_size = GUINT16_FROM_LE (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4);
5842         if (assemblyb->pekind == 1) {
5843                 /* it's a dll */
5844                 header->coff.coff_attributes = GUINT16_FROM_LE (0x210e);
5845         } else {
5846                 /* it's an exe */
5847                 header->coff.coff_attributes = GUINT16_FROM_LE (0x010e);
5848         }
5849
5850         virtual_base = 0x400000; /* FIXME: 0x10000000 if a DLL */
5851
5852         header->pe.pe_magic = GUINT16_FROM_LE (0x10B);
5853         header->pe.pe_major = 6;
5854         header->pe.pe_minor = 0;
5855         size = assembly->sections [MONO_SECTION_TEXT].size;
5856         size += FILE_ALIGN - 1;
5857         size &= ~(FILE_ALIGN - 1);
5858         header->pe.pe_code_size = GUINT32_FROM_LE(size);
5859         size = assembly->sections [MONO_SECTION_RSRC].size;
5860         size += FILE_ALIGN - 1;
5861         size &= ~(FILE_ALIGN - 1);
5862         header->pe.pe_data_size = GUINT32_FROM_LE(size);
5863         g_assert (START_TEXT_RVA == assembly->sections [MONO_SECTION_TEXT].rva);
5864         header->pe.pe_rva_code_base = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_TEXT].rva);
5865         header->pe.pe_rva_data_base = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].rva);
5866         /* pe_rva_entry_point always at the beginning of the text section */
5867         header->pe.pe_rva_entry_point = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_TEXT].rva);
5868
5869         header->nt.pe_image_base = GUINT32_FROM_LE (virtual_base);
5870         header->nt.pe_section_align = GUINT32_FROM_LE (VIRT_ALIGN);
5871         header->nt.pe_file_alignment = GUINT32_FROM_LE (FILE_ALIGN);
5872         header->nt.pe_os_major = GUINT16_FROM_LE (4);
5873         header->nt.pe_os_minor = GUINT16_FROM_LE (0);
5874         header->nt.pe_subsys_major = GUINT16_FROM_LE (4);
5875         size = section_start;
5876         size += FILE_ALIGN - 1;
5877         size &= ~(FILE_ALIGN - 1);
5878         header->nt.pe_header_size = GUINT32_FROM_LE (size);
5879         size = image_size;
5880         size += VIRT_ALIGN - 1;
5881         size &= ~(VIRT_ALIGN - 1);
5882         header->nt.pe_image_size = GUINT32_FROM_LE (size);
5883
5884         /*
5885         // Translate the PEFileKind value to the value expected by the Windows loader
5886         */
5887         {
5888                 short kind;
5889
5890                 /*
5891                 // PEFileKinds.Dll == 1
5892                 // PEFileKinds.ConsoleApplication == 2
5893                 // PEFileKinds.WindowApplication == 3
5894                 //
5895                 // need to get:
5896                 //     IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
5897                 //     IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
5898                 */
5899                 if (assemblyb->pekind == 3)
5900                         kind = 2;
5901                 else
5902                         kind = 3;
5903                 
5904                 header->nt.pe_subsys_required = GUINT16_FROM_LE (kind);
5905         }    
5906         header->nt.pe_stack_reserve = GUINT32_FROM_LE (0x00100000);
5907         header->nt.pe_stack_commit = GUINT32_FROM_LE (0x00001000);
5908         header->nt.pe_heap_reserve = GUINT32_FROM_LE (0x00100000);
5909         header->nt.pe_heap_commit = GUINT32_FROM_LE (0x00001000);
5910         header->nt.pe_loader_flags = GUINT32_FROM_LE (0);
5911         header->nt.pe_data_dir_count = GUINT32_FROM_LE (16);
5912
5913         /* fill data directory entries */
5914
5915         header->datadir.pe_resource_table.size = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].size);
5916         header->datadir.pe_resource_table.rva = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RSRC].rva);
5917
5918         header->datadir.pe_reloc_table.size = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RELOC].size);
5919         header->datadir.pe_reloc_table.rva = GUINT32_FROM_LE (assembly->sections [MONO_SECTION_RELOC].rva);
5920
5921         header->datadir.pe_cli_header.size = GUINT32_FROM_LE (72);
5922         header->datadir.pe_cli_header.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->cli_header_offset);
5923         header->datadir.pe_iat.size = GUINT32_FROM_LE (8);
5924         header->datadir.pe_iat.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
5925         /* patch entrypoint name */
5926         if (assemblyb->pekind == 1)
5927                 memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorDllMain", 12);
5928         else
5929                 memcpy (assembly->code.data + assembly->imp_names_offset + 2, "_CorExeMain", 12);
5930         /* patch imported function RVA name */
5931         rva = (guint32*)(assembly->code.data + assembly->iat_offset);
5932         *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset);
5933
5934         /* the import table */
5935         header->datadir.pe_import_table.size = GUINT32_FROM_LE (79); /* FIXME: magic number? */
5936         header->datadir.pe_import_table.rva = GUINT32_FROM_LE (assembly->text_rva + assembly->idt_offset);
5937         /* patch imported dll RVA name and other entries in the dir */
5938         rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, name_rva));
5939         *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->imp_names_offset + 14); /* 14 is hint+strlen+1 of func name */
5940         rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_address_table_rva));
5941         *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->iat_offset);
5942         rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_lookup_table));
5943         *rva = GUINT32_FROM_LE (assembly->text_rva + assembly->ilt_offset);
5944
5945         p = (guchar*)(assembly->code.data + assembly->ilt_offset);
5946         value = (assembly->text_rva + assembly->imp_names_offset);
5947         *p++ = (value) & 0xff;
5948         *p++ = (value >> 8) & (0xff);
5949         *p++ = (value >> 16) & (0xff);
5950         *p++ = (value >> 24) & (0xff);
5951
5952         /* the CLI header info */
5953         cli_header = (MonoCLIHeader*)(assembly->code.data + assembly->cli_header_offset);
5954         cli_header->ch_size = GUINT32_FROM_LE (72);
5955         cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
5956         cli_header->ch_runtime_minor = GUINT16_FROM_LE (5);
5957         cli_header->ch_flags = GUINT32_FROM_LE (assemblyb->pe_kind);
5958         if (assemblyb->entry_point) {
5959                 guint32 table_idx = 0;
5960                 if (!strcmp (assemblyb->entry_point->object.vtable->klass->name, "MethodBuilder")) {
5961                         MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
5962                         table_idx = methodb->table_idx;
5963                 } else {
5964                         table_idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
5965                 }
5966                 cli_header->ch_entry_point = GUINT32_FROM_LE (table_idx | MONO_TOKEN_METHOD_DEF);
5967         } else {
5968                 cli_header->ch_entry_point = GUINT32_FROM_LE (0);
5969         }
5970         /* The embedded managed resources */
5971         text_offset = assembly->text_rva + assembly->code.index;
5972         cli_header->ch_resources.rva = GUINT32_FROM_LE (text_offset);
5973         cli_header->ch_resources.size = GUINT32_FROM_LE (assembly->resources.index);
5974         text_offset += assembly->resources.index;
5975         cli_header->ch_metadata.rva = GUINT32_FROM_LE (text_offset);
5976         cli_header->ch_metadata.size = GUINT32_FROM_LE (assembly->meta_size);
5977         text_offset += assembly->meta_size;
5978         if (assembly->strong_name_size) {
5979                 cli_header->ch_strong_name.rva = GUINT32_FROM_LE (text_offset);
5980                 cli_header->ch_strong_name.size = GUINT32_FROM_LE (assembly->strong_name_size);
5981                 text_offset += assembly->strong_name_size;
5982         }
5983
5984         /* write the section tables and section content */
5985         section = (MonoSectionTable*)(pefile->data + section_start);
5986         for (i = 0; i < MONO_SECTION_MAX; ++i) {
5987                 static const char section_names [][7] = {
5988                         ".text", ".rsrc", ".reloc"
5989                 };
5990                 if (!assembly->sections [i].size)
5991                         continue;
5992                 strcpy (section->st_name, section_names [i]);
5993                 /*g_print ("output section %s (%d), size: %d\n", section->st_name, i, assembly->sections [i].size);*/
5994                 section->st_virtual_address = GUINT32_FROM_LE (assembly->sections [i].rva);
5995                 section->st_virtual_size = GUINT32_FROM_LE (assembly->sections [i].size);
5996                 section->st_raw_data_size = GUINT32_FROM_LE (GUINT32_TO_LE (section->st_virtual_size) + (FILE_ALIGN - 1));
5997                 section->st_raw_data_size &= GUINT32_FROM_LE (~(FILE_ALIGN - 1));
5998                 section->st_raw_data_ptr = GUINT32_FROM_LE (assembly->sections [i].offset);
5999                 section->st_flags = GUINT32_FROM_LE (assembly->sections [i].attrs);
6000                 section ++;
6001         }
6002         
6003         checked_write_file (file, pefile->data, pefile->index);
6004         
6005         mono_dynamic_stream_reset (pefile);
6006         
6007         for (i = 0; i < MONO_SECTION_MAX; ++i) {
6008                 if (!assembly->sections [i].size)
6009                         continue;
6010                 
6011                 if (SetFilePointer (file, assembly->sections [i].offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
6012                         g_error ("SetFilePointer returned %d\n", GetLastError ());
6013                 
6014                 switch (i) {
6015                 case MONO_SECTION_TEXT:
6016                         /* patch entry point */
6017                         p = (guchar*)(assembly->code.data + 2);
6018                         value = (virtual_base + assembly->text_rva + assembly->iat_offset);
6019                         *p++ = (value) & 0xff;
6020                         *p++ = (value >> 8) & 0xff;
6021                         *p++ = (value >> 16) & 0xff;
6022                         *p++ = (value >> 24) & 0xff;
6023                 
6024                         checked_write_file (file, assembly->code.data, assembly->code.index);
6025                         checked_write_file (file, assembly->resources.data, assembly->resources.index);
6026                         checked_write_file (file, assembly->image.raw_metadata, assembly->meta_size);
6027                         checked_write_file (file, assembly->strong_name, assembly->strong_name_size);
6028                                 
6029
6030                         g_free (assembly->image.raw_metadata);
6031                         break;
6032                 case MONO_SECTION_RELOC: {
6033                         struct {
6034                                 guint32 page_rva;
6035                                 guint32 block_size;
6036                                 guint16 type_and_offset;
6037                                 guint16 term;
6038                         } reloc;
6039                         
6040                         g_assert (sizeof (reloc) == 12);
6041                         
6042                         reloc.page_rva = GUINT32_FROM_LE (assembly->text_rva);
6043                         reloc.block_size = GUINT32_FROM_LE (12);
6044                         
6045                         /* 
6046                          * the entrypoint is always at the start of the text section 
6047                          * 3 is IMAGE_REL_BASED_HIGHLOW
6048                          * 2 is patch_size_rva - text_rva
6049                          */
6050                         reloc.type_and_offset = GUINT16_FROM_LE ((3 << 12) + (2));
6051                         reloc.term = 0;
6052                         
6053                         checked_write_file (file, &reloc, sizeof (reloc));
6054                         
6055                         break;
6056                 }
6057                 case MONO_SECTION_RSRC:
6058                         if (assembly->win32_res) {
6059
6060                                 /* Fixup the offsets in the IMAGE_RESOURCE_DATA_ENTRY structures */
6061                                 fixup_resource_directory (assembly->win32_res, assembly->win32_res, assembly->sections [i].rva);
6062                                 checked_write_file (file, assembly->win32_res, assembly->win32_res_size);
6063                         }
6064                         break;
6065                 default:
6066                         g_assert_not_reached ();
6067                 }
6068         }
6069         
6070         /* check that the file is properly padded */
6071         if (SetFilePointer (file, file_offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
6072                 g_error ("SetFilePointer returned %d\n", GetLastError ());
6073         if (! SetEndOfFile (file))
6074                 g_error ("SetEndOfFile returned %d\n", GetLastError ());
6075         
6076         mono_dynamic_stream_reset (&assembly->code);
6077         mono_dynamic_stream_reset (&assembly->us);
6078         mono_dynamic_stream_reset (&assembly->blob);
6079         mono_dynamic_stream_reset (&assembly->guid);
6080         mono_dynamic_stream_reset (&assembly->sheap);
6081
6082         g_hash_table_foreach (assembly->blob_cache, (GHFunc)g_free, NULL);
6083         g_hash_table_destroy (assembly->blob_cache);
6084         assembly->blob_cache = NULL;
6085
6086         return TRUE;
6087 }
6088
6089 #else /* DISABLE_REFLECTION_EMIT_SAVE */
6090
6091 gboolean
6092 mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file, MonoError *error)
6093 {
6094         g_assert_not_reached ();
6095 }
6096
6097 #endif /* DISABLE_REFLECTION_EMIT_SAVE */
6098
6099 #ifndef DISABLE_REFLECTION_EMIT
6100
6101 MonoReflectionModule *
6102 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
6103 {
6104         char *name;
6105         MonoImage *image;
6106         MonoImageOpenStatus status;
6107         MonoDynamicAssembly *assembly;
6108         guint32 module_count;
6109         MonoImage **new_modules;
6110         gboolean *new_modules_loaded;
6111         
6112         mono_error_init (error);
6113         
6114         name = mono_string_to_utf8_checked (fileName, error);
6115         return_val_if_nok (error, NULL);
6116
6117         image = mono_image_open (name, &status);
6118         if (!image) {
6119                 if (status == MONO_IMAGE_ERROR_ERRNO)
6120                         mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
6121                 else
6122                         mono_error_set_bad_image_name (error, name, NULL);
6123                 g_free (name);
6124                 return NULL;
6125         }
6126
6127         g_free (name);
6128
6129         assembly = ab->dynamic_assembly;
6130         image->assembly = (MonoAssembly*)assembly;
6131
6132         module_count = image->assembly->image->module_count;
6133         new_modules = g_new0 (MonoImage *, module_count + 1);
6134         new_modules_loaded = g_new0 (gboolean, module_count + 1);
6135
6136         if (image->assembly->image->modules)
6137                 memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
6138         if (image->assembly->image->modules_loaded)
6139                 memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
6140         new_modules [module_count] = image;
6141         new_modules_loaded [module_count] = TRUE;
6142         mono_image_addref (image);
6143
6144         g_free (image->assembly->image->modules);
6145         image->assembly->image->modules = new_modules;
6146         image->assembly->image->modules_loaded = new_modules_loaded;
6147         image->assembly->image->module_count ++;
6148
6149         mono_assembly_load_references (image, &status);
6150         if (status) {
6151                 mono_image_close (image);
6152                 mono_error_set_exception_instance (error, mono_get_exception_file_not_found (fileName));
6153                 return NULL;
6154         }
6155
6156         return mono_module_get_object_checked (mono_domain_get (), image, error);
6157 }
6158
6159 #endif /* DISABLE_REFLECTION_EMIT */
6160
6161 #ifndef DISABLE_REFLECTION_EMIT
6162 static gpointer
6163 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
6164 {
6165         CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
6166 }
6167
6168 static gpointer
6169 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
6170 {
6171         CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
6172 }
6173
6174 static gboolean
6175 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
6176 {
6177         MonoDynamicImage *image = moduleb->dynamic_image;
6178         MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
6179         mono_error_init (error);
6180         if (!image) {
6181                 int module_count;
6182                 MonoImage **new_modules;
6183                 MonoImage *ass;
6184                 char *name, *fqname;
6185                 /*
6186                  * FIXME: we already created an image in mono_image_basic_init (), but
6187                  * we don't know which module it belongs to, since that is only 
6188                  * determined at assembly save time.
6189                  */
6190                 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
6191                 name = mono_string_to_utf8_checked (ab->name, error);
6192                 return_val_if_nok (error, FALSE);
6193                 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
6194                 if (!is_ok (error)) {
6195                         g_free (name);
6196                         return FALSE;
6197                 }
6198                 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
6199
6200                 moduleb->module.image = &image->image;
6201                 moduleb->dynamic_image = image;
6202                 register_module (mono_object_domain (moduleb), moduleb, image);
6203
6204                 /* register the module with the assembly */
6205                 ass = ab->dynamic_assembly->assembly.image;
6206                 module_count = ass->module_count;
6207                 new_modules = g_new0 (MonoImage *, module_count + 1);
6208
6209                 if (ass->modules)
6210                         memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
6211                 new_modules [module_count] = &image->image;
6212                 mono_image_addref (&image->image);
6213
6214                 g_free (ass->modules);
6215                 ass->modules = new_modules;
6216                 ass->module_count ++;
6217         }
6218         return TRUE;
6219 }
6220
6221 static void
6222 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
6223 {
6224         MonoError error;
6225         (void) image_module_basic_init (moduleb, &error);
6226         mono_error_set_pending_exception (&error);
6227 }
6228
6229 #endif
6230
6231 static gboolean
6232 is_corlib_type (MonoClass *klass)
6233 {
6234         return klass->image == mono_defaults.corlib;
6235 }
6236
6237 #define check_corlib_type_cached(_class, _namespace, _name) do { \
6238         static MonoClass *cached_class; \
6239         if (cached_class) \
6240                 return cached_class == _class; \
6241         if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
6242                 cached_class = _class; \
6243                 return TRUE; \
6244         } \
6245         return FALSE; \
6246 } while (0) \
6247
6248
6249
6250 #ifndef DISABLE_REFLECTION_EMIT
6251 static gboolean
6252 is_sre_array (MonoClass *klass)
6253 {
6254         check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
6255 }
6256
6257 static gboolean
6258 is_sre_byref (MonoClass *klass)
6259 {
6260         check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
6261 }
6262
6263 static gboolean
6264 is_sre_pointer (MonoClass *klass)
6265 {
6266         check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
6267 }
6268
6269 static gboolean
6270 is_sre_generic_instance (MonoClass *klass)
6271 {
6272         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
6273 }
6274
6275 static gboolean
6276 is_sre_type_builder (MonoClass *klass)
6277 {
6278         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
6279 }
6280
6281 static gboolean
6282 is_sre_method_builder (MonoClass *klass)
6283 {
6284         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
6285 }
6286
6287 gboolean
6288 mono_is_sre_ctor_builder (MonoClass *klass)
6289 {
6290         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
6291 }
6292
6293 static gboolean
6294 is_sre_field_builder (MonoClass *klass)
6295 {
6296         check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
6297 }
6298
6299 gboolean
6300 mono_is_sre_method_on_tb_inst (MonoClass *klass)
6301 {
6302         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
6303 }
6304
6305 gboolean
6306 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
6307 {
6308         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
6309 }
6310
6311 static MonoReflectionType*
6312 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
6313 {
6314         static MonoMethod *method_get_underlying_system_type = NULL;
6315         MonoReflectionType *rt;
6316         MonoMethod *usertype_method;
6317
6318         mono_error_init (error);
6319
6320         if (!method_get_underlying_system_type)
6321                 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
6322
6323         usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
6324
6325         rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
6326
6327         return rt;
6328 }
6329
6330 MonoReflectionType*
6331 mono_reflection_type_resolve_user_types (MonoReflectionType *type, MonoError *error)
6332 {
6333         mono_error_init (error);
6334         if (!type || type->type)
6335                 return type;
6336
6337         if (mono_reflection_is_usertype (type)) {
6338                 type = mono_reflection_type_get_underlying_system_type (type, error);
6339                 return_val_if_nok (error, NULL);
6340                 if (mono_reflection_is_usertype (type)) {
6341                         mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported22");
6342                         return NULL;
6343                 }
6344         }
6345
6346         return type;
6347 }
6348
6349
6350 MonoType*
6351 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
6352 {
6353         MonoClass *klass;
6354         mono_error_init (error);
6355
6356         if (!ref)
6357                 return NULL;
6358         if (ref->type)
6359                 return ref->type;
6360
6361         if (mono_reflection_is_usertype (ref)) {
6362                 ref = mono_reflection_type_get_underlying_system_type (ref, error);
6363                 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
6364                         return NULL;
6365                 if (ref->type)
6366                         return ref->type;
6367         }
6368
6369         klass = mono_object_class (ref);
6370
6371         if (is_sre_array (klass)) {
6372                 MonoType *res;
6373                 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
6374                 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
6375                 return_val_if_nok (error, NULL);
6376                 g_assert (base);
6377                 if (sre_array->rank == 0) //single dimentional array
6378                         res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
6379                 else
6380                         res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
6381                 sre_array->type.type = res;
6382                 return res;
6383         } else if (is_sre_byref (klass)) {
6384                 MonoType *res;
6385                 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
6386                 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
6387                 return_val_if_nok (error, NULL);
6388                 g_assert (base);
6389                 res = &mono_class_from_mono_type (base)->this_arg;
6390                 sre_byref->type.type = res;
6391                 return res;
6392         } else if (is_sre_pointer (klass)) {
6393                 MonoType *res;
6394                 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
6395                 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
6396                 return_val_if_nok (error, NULL);
6397                 g_assert (base);
6398                 res = &mono_ptr_class_get (base)->byval_arg;
6399                 sre_pointer->type.type = res;
6400                 return res;
6401         } else if (is_sre_generic_instance (klass)) {
6402                 MonoType *res, **types;
6403                 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
6404                 int i, count;
6405
6406                 count = mono_array_length (gclass->type_arguments);
6407                 types = g_new0 (MonoType*, count);
6408                 for (i = 0; i < count; ++i) {
6409                         MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
6410                         types [i] = mono_reflection_type_get_handle (t, error);
6411                         if (!types[i] || !is_ok (error)) {
6412                                 g_free (types);
6413                                 return NULL;
6414                         }
6415                 }
6416
6417                 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
6418                 g_free (types);
6419                 g_assert (res);
6420                 gclass->type.type = res;
6421                 return res;
6422         }
6423
6424         g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
6425         return NULL;
6426 }
6427
6428 void
6429 ves_icall_SymbolType_create_unmanaged_type (MonoReflectionType *type)
6430 {
6431         MonoError error;
6432         mono_reflection_type_get_handle (type, &error);
6433         mono_error_set_pending_exception (&error);
6434 }
6435
6436 static gboolean
6437 reflection_register_with_runtime (MonoReflectionType *type, MonoError *error)
6438 {
6439         MonoDomain *domain = mono_object_domain ((MonoObject*)type);
6440         MonoClass *klass;
6441
6442         mono_error_init (error);
6443
6444         MonoType *res = mono_reflection_type_get_handle (type, error);
6445
6446         if (!res && is_ok (error)) {
6447                 mono_error_set_argument (error, NULL, "Invalid generic instantiation, one or more arguments are not proper user types");
6448         }
6449         return_val_if_nok (error, FALSE);
6450
6451         klass = mono_class_from_mono_type (res);
6452
6453         mono_loader_lock (); /*same locking as mono_type_get_object_checked */
6454         mono_domain_lock (domain);
6455
6456         if (!image_is_dynamic (klass->image)) {
6457                 mono_class_setup_supertypes (klass);
6458         } else {
6459                 if (!domain->type_hash)
6460                         domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
6461                                         (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "domain reflection types table");
6462                 mono_g_hash_table_insert (domain->type_hash, res, type);
6463         }
6464         mono_domain_unlock (domain);
6465         mono_loader_unlock ();
6466
6467         return TRUE;
6468 }
6469
6470 void
6471 mono_reflection_register_with_runtime (MonoReflectionType *type)
6472 {
6473         MonoError error;
6474         (void) reflection_register_with_runtime (type, &error);
6475         mono_error_set_pending_exception (&error);
6476 }
6477
6478 /**
6479  * LOCKING: Assumes the loader lock is held.
6480  */
6481 static MonoMethodSignature*
6482 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
6483         MonoMethodSignature *sig;
6484         int count, i;
6485
6486         mono_error_init (error);
6487
6488         count = parameters? mono_array_length (parameters): 0;
6489
6490         sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
6491         sig->param_count = count;
6492         sig->sentinelpos = -1; /* FIXME */
6493         for (i = 0; i < count; ++i) {
6494                 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
6495                 if (!is_ok (error)) {
6496                         image_g_free (image, sig);
6497                         return NULL;
6498                 }
6499         }
6500         return sig;
6501 }
6502
6503 /**
6504  * LOCKING: Assumes the loader lock is held.
6505  */
6506 static MonoMethodSignature*
6507 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
6508         MonoMethodSignature *sig;
6509
6510         mono_error_init (error);
6511
6512         sig = parameters_to_signature (image, ctor->parameters, error);
6513         return_val_if_nok (error, NULL);
6514         sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
6515         sig->ret = &mono_defaults.void_class->byval_arg;
6516         return sig;
6517 }
6518
6519 /**
6520  * LOCKING: Assumes the loader lock is held.
6521  */
6522 static MonoMethodSignature*
6523 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
6524         MonoMethodSignature *sig;
6525
6526         mono_error_init (error);
6527
6528         sig = parameters_to_signature (image, method->parameters, error);
6529         return_val_if_nok (error, NULL);
6530         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
6531         if (method->rtype) {
6532                 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
6533                 if (!is_ok (error)) {
6534                         image_g_free (image, sig);
6535                         return NULL;
6536                 }
6537         } else {
6538                 sig->ret = &mono_defaults.void_class->byval_arg;
6539         }
6540         sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
6541         return sig;
6542 }
6543
6544 static MonoMethodSignature*
6545 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
6546         MonoMethodSignature *sig;
6547
6548         mono_error_init (error);
6549
6550         sig = parameters_to_signature (NULL, method->parameters, error);
6551         return_val_if_nok (error, NULL);
6552         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
6553         if (method->rtype) {
6554                 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
6555                 if (!is_ok (error)) {
6556                         g_free (sig);
6557                         return NULL;
6558                 }
6559         } else {
6560                 sig->ret = &mono_defaults.void_class->byval_arg;
6561         }
6562         sig->generic_param_count = 0;
6563         return sig;
6564 }
6565
6566 static void
6567 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
6568 {
6569         mono_error_init (error);
6570         MonoClass *klass = mono_object_class (prop);
6571         if (strcmp (klass->name, "PropertyBuilder") == 0) {
6572                 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
6573                 *name = mono_string_to_utf8_checked (pb->name, error);
6574                 return_if_nok (error);
6575                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
6576         } else {
6577                 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
6578                 *name = g_strdup (p->property->name);
6579                 if (p->property->get)
6580                         *type = mono_method_signature (p->property->get)->ret;
6581                 else
6582                         *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
6583         }
6584 }
6585
6586 static void
6587 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
6588 {
6589         mono_error_init (error);
6590         MonoClass *klass = mono_object_class (field);
6591         if (strcmp (klass->name, "FieldBuilder") == 0) {
6592                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
6593                 *name = mono_string_to_utf8_checked (fb->name, error);
6594                 return_if_nok (error);
6595                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
6596         } else {
6597                 MonoReflectionField *f = (MonoReflectionField *)field;
6598                 *name = g_strdup (mono_field_get_name (f->field));
6599                 *type = f->field->type;
6600         }
6601 }
6602
6603 #else /* DISABLE_REFLECTION_EMIT */
6604
6605 void
6606 mono_reflection_register_with_runtime (MonoReflectionType *type)
6607 {
6608         /* This is empty */
6609 }
6610
6611 static gboolean
6612 is_sre_type_builder (MonoClass *klass)
6613 {
6614         return FALSE;
6615 }
6616
6617 static gboolean
6618 is_sre_generic_instance (MonoClass *klass)
6619 {
6620         return FALSE;
6621 }
6622
6623 gboolean
6624 mono_is_sre_ctor_builder (MonoClass *klass)
6625 {
6626         return FALSE;
6627 }
6628
6629 gboolean
6630 mono_is_sre_method_on_tb_inst (MonoClass *klass)
6631 {
6632         return FALSE;
6633 }
6634
6635 gboolean
6636 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
6637 {
6638         return FALSE;
6639 }
6640
6641 static void
6642 init_type_builder_generics (MonoObject *type, MonoError *error)
6643 {
6644         mono_error_init (error);
6645 }
6646
6647 #endif /* !DISABLE_REFLECTION_EMIT */
6648
6649
6650 static gboolean
6651 is_sr_mono_field (MonoClass *klass)
6652 {
6653         check_corlib_type_cached (klass, "System.Reflection", "MonoField");
6654 }
6655
6656 gboolean
6657 mono_is_sr_mono_property (MonoClass *klass)
6658 {
6659         check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
6660 }
6661
6662 static gboolean
6663 is_sr_mono_method (MonoClass *klass)
6664 {
6665         check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
6666 }
6667
6668 gboolean
6669 mono_is_sr_mono_cmethod (MonoClass *klass)
6670 {
6671         check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
6672 }
6673
6674 static gboolean
6675 is_sr_mono_generic_method (MonoClass *klass)
6676 {
6677         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericMethod");
6678 }
6679
6680 static gboolean
6681 is_sr_mono_generic_cmethod (MonoClass *klass)
6682 {
6683         check_corlib_type_cached (klass, "System.Reflection", "MonoGenericCMethod");
6684 }
6685
6686 gboolean
6687 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
6688 {
6689         return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass) || is_sr_mono_generic_method (klass) || is_sr_mono_generic_cmethod (klass);
6690 }
6691
6692 gboolean
6693 mono_is_sre_type_builder (MonoClass *klass)
6694 {
6695         return is_sre_type_builder (klass);
6696 }
6697
6698 gboolean
6699 mono_is_sre_generic_instance (MonoClass *klass)
6700 {
6701         return is_sre_generic_instance (klass);
6702 }
6703
6704
6705
6706 /**
6707  * encode_cattr_value:
6708  * Encode a value in a custom attribute stream of bytes.
6709  * The value to encode is either supplied as an object in argument val
6710  * (valuetypes are boxed), or as a pointer to the data in the
6711  * argument argval.
6712  * @type represents the type of the value
6713  * @buffer is the start of the buffer
6714  * @p the current position in the buffer
6715  * @buflen contains the size of the buffer and is used to return the new buffer size
6716  * if this needs to be realloced.
6717  * @retbuffer and @retp return the start and the position of the buffer
6718  * @error set on error.
6719  */
6720 static void
6721 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
6722 {
6723         MonoTypeEnum simple_type;
6724         
6725         mono_error_init (error);
6726         if ((p-buffer) + 10 >= *buflen) {
6727                 char *newbuf;
6728                 *buflen *= 2;
6729                 newbuf = (char *)g_realloc (buffer, *buflen);
6730                 p = newbuf + (p-buffer);
6731                 buffer = newbuf;
6732         }
6733         if (!argval)
6734                 argval = ((char*)arg + sizeof (MonoObject));
6735         simple_type = type->type;
6736 handle_enum:
6737         switch (simple_type) {
6738         case MONO_TYPE_BOOLEAN:
6739         case MONO_TYPE_U1:
6740         case MONO_TYPE_I1:
6741                 *p++ = *argval;
6742                 break;
6743         case MONO_TYPE_CHAR:
6744         case MONO_TYPE_U2:
6745         case MONO_TYPE_I2:
6746                 swap_with_size (p, argval, 2, 1);
6747                 p += 2;
6748                 break;
6749         case MONO_TYPE_U4:
6750         case MONO_TYPE_I4:
6751         case MONO_TYPE_R4:
6752                 swap_with_size (p, argval, 4, 1);
6753                 p += 4;
6754                 break;
6755         case MONO_TYPE_R8:
6756                 swap_with_size (p, argval, 8, 1);
6757                 p += 8;
6758                 break;
6759         case MONO_TYPE_U8:
6760         case MONO_TYPE_I8:
6761                 swap_with_size (p, argval, 8, 1);
6762                 p += 8;
6763                 break;
6764         case MONO_TYPE_VALUETYPE:
6765                 if (type->data.klass->enumtype) {
6766                         simple_type = mono_class_enum_basetype (type->data.klass)->type;
6767                         goto handle_enum;
6768                 } else {
6769                         g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
6770                 }
6771                 break;
6772         case MONO_TYPE_STRING: {
6773                 char *str;
6774                 guint32 slen;
6775                 if (!arg) {
6776                         *p++ = 0xFF;
6777                         break;
6778                 }
6779                 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
6780                 return_if_nok (error);
6781                 slen = strlen (str);
6782                 if ((p-buffer) + 10 + slen >= *buflen) {
6783                         char *newbuf;
6784                         *buflen *= 2;
6785                         *buflen += slen;
6786                         newbuf = (char *)g_realloc (buffer, *buflen);
6787                         p = newbuf + (p-buffer);
6788                         buffer = newbuf;
6789                 }
6790                 mono_metadata_encode_value (slen, p, &p);
6791                 memcpy (p, str, slen);
6792                 p += slen;
6793                 g_free (str);
6794                 break;
6795         }
6796         case MONO_TYPE_CLASS: {
6797                 char *str;
6798                 guint32 slen;
6799                 MonoType *arg_type;
6800                 if (!arg) {
6801                         *p++ = 0xFF;
6802                         break;
6803                 }
6804 handle_type:
6805                 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
6806                 return_if_nok (error);
6807
6808                 str = type_get_qualified_name (arg_type, NULL);
6809                 slen = strlen (str);
6810                 if ((p-buffer) + 10 + slen >= *buflen) {
6811                         char *newbuf;
6812                         *buflen *= 2;
6813                         *buflen += slen;
6814                         newbuf = (char *)g_realloc (buffer, *buflen);
6815                         p = newbuf + (p-buffer);
6816                         buffer = newbuf;
6817                 }
6818                 mono_metadata_encode_value (slen, p, &p);
6819                 memcpy (p, str, slen);
6820                 p += slen;
6821                 g_free (str);
6822                 break;
6823         }
6824         case MONO_TYPE_SZARRAY: {
6825                 int len, i;
6826                 MonoClass *eclass, *arg_eclass;
6827
6828                 if (!arg) {
6829                         *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
6830                         break;
6831                 }
6832                 len = mono_array_length ((MonoArray*)arg);
6833                 *p++ = len & 0xff;
6834                 *p++ = (len >> 8) & 0xff;
6835                 *p++ = (len >> 16) & 0xff;
6836                 *p++ = (len >> 24) & 0xff;
6837                 *retp = p;
6838                 *retbuffer = buffer;
6839                 eclass = type->data.klass;
6840                 arg_eclass = mono_object_class (arg)->element_class;
6841
6842                 if (!eclass) {
6843                         /* Happens when we are called from the MONO_TYPE_OBJECT case below */
6844                         eclass = mono_defaults.object_class;
6845                 }
6846                 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
6847                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
6848                         int elsize = mono_class_array_element_size (arg_eclass);
6849                         for (i = 0; i < len; ++i) {
6850                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
6851                                 return_if_nok (error);
6852                                 elptr += elsize;
6853                         }
6854                 } else if (eclass->valuetype && arg_eclass->valuetype) {
6855                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
6856                         int elsize = mono_class_array_element_size (eclass);
6857                         for (i = 0; i < len; ++i) {
6858                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
6859                                 return_if_nok (error);
6860                                 elptr += elsize;
6861                         }
6862                 } else {
6863                         for (i = 0; i < len; ++i) {
6864                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
6865                                 return_if_nok (error);
6866                         }
6867                 }
6868                 break;
6869         }
6870         case MONO_TYPE_OBJECT: {
6871                 MonoClass *klass;
6872                 char *str;
6873                 guint32 slen;
6874
6875                 /*
6876                  * The parameter type is 'object' but the type of the actual
6877                  * argument is not. So we have to add type information to the blob
6878                  * too. This is completely undocumented in the spec.
6879                  */
6880
6881                 if (arg == NULL) {
6882                         *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
6883                         *p++ = 0xFF;
6884                         break;
6885                 }
6886                 
6887                 klass = mono_object_class (arg);
6888
6889                 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
6890                         *p++ = 0x50;
6891                         goto handle_type;
6892                 } else {
6893                         return_if_nok (error);
6894                 }
6895
6896                 if (klass->enumtype) {
6897                         *p++ = 0x55;
6898                 } else if (klass == mono_defaults.string_class) {
6899                         simple_type = MONO_TYPE_STRING;
6900                         *p++ = 0x0E;
6901                         goto handle_enum;
6902                 } else if (klass->rank == 1) {
6903                         *p++ = 0x1D;
6904                         if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
6905                                 /* See Partition II, Appendix B3 */
6906                                 *p++ = 0x51;
6907                         else
6908                                 *p++ = klass->element_class->byval_arg.type;
6909                         encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
6910                         return_if_nok (error);
6911                         break;
6912                 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
6913                         *p++ = simple_type = klass->byval_arg.type;
6914                         goto handle_enum;
6915                 } else {
6916                         g_error ("unhandled type in custom attr");
6917                 }
6918                 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
6919                 slen = strlen (str);
6920                 if ((p-buffer) + 10 + slen >= *buflen) {
6921                         char *newbuf;
6922                         *buflen *= 2;
6923                         *buflen += slen;
6924                         newbuf = (char *)g_realloc (buffer, *buflen);
6925                         p = newbuf + (p-buffer);
6926                         buffer = newbuf;
6927                 }
6928                 mono_metadata_encode_value (slen, p, &p);
6929                 memcpy (p, str, slen);
6930                 p += slen;
6931                 g_free (str);
6932                 simple_type = mono_class_enum_basetype (klass)->type;
6933                 goto handle_enum;
6934         }
6935         default:
6936                 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
6937         }
6938         *retp = p;
6939         *retbuffer = buffer;
6940 }
6941
6942 static void
6943 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
6944 {
6945         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
6946                 char *str = type_get_qualified_name (type, NULL);
6947                 int slen = strlen (str);
6948
6949                 *p++ = 0x55;
6950                 /*
6951                  * This seems to be optional...
6952                  * *p++ = 0x80;
6953                  */
6954                 mono_metadata_encode_value (slen, p, &p);
6955                 memcpy (p, str, slen);
6956                 p += slen;
6957                 g_free (str);
6958         } else if (type->type == MONO_TYPE_OBJECT) {
6959                 *p++ = 0x51;
6960         } else if (type->type == MONO_TYPE_CLASS) {
6961                 /* it should be a type: encode_cattr_value () has the check */
6962                 *p++ = 0x50;
6963         } else {
6964                 mono_metadata_encode_value (type->type, p, &p);
6965                 if (type->type == MONO_TYPE_SZARRAY)
6966                         /* See the examples in Partition VI, Annex B */
6967                         encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
6968         }
6969
6970         *retp = p;
6971 }
6972
6973 #ifndef DISABLE_REFLECTION_EMIT
6974 static void
6975 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
6976 {
6977         int len;
6978
6979         mono_error_init (error);
6980
6981         /* Preallocate a large enough buffer */
6982         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
6983                 char *str = type_get_qualified_name (type, NULL);
6984                 len = strlen (str);
6985                 g_free (str);
6986         } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
6987                 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
6988                 len = strlen (str);
6989                 g_free (str);
6990         } else {
6991                 len = 0;
6992         }
6993         len += strlen (name);
6994
6995         if ((p-buffer) + 20 + len >= *buflen) {
6996                 char *newbuf;
6997                 *buflen *= 2;
6998                 *buflen += len;
6999                 newbuf = (char *)g_realloc (buffer, *buflen);
7000                 p = newbuf + (p-buffer);
7001                 buffer = newbuf;
7002         }
7003
7004         encode_field_or_prop_type (type, p, &p);
7005
7006         len = strlen (name);
7007         mono_metadata_encode_value (len, p, &p);
7008         memcpy (p, name, len);
7009         p += len;
7010         encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
7011         return_if_nok (error);
7012         *retp = p;
7013         *retbuffer = buffer;
7014 }
7015
7016 /**
7017  * mono_reflection_get_custom_attrs_blob:
7018  * @ctor: custom attribute constructor
7019  * @ctorArgs: arguments o the constructor
7020  * @properties:
7021  * @propValues:
7022  * @fields:
7023  * @fieldValues:
7024  * 
7025  * Creates the blob of data that needs to be saved in the metadata and that represents
7026  * the custom attributed described by @ctor, @ctorArgs etc.
7027  * Returns: a Byte array representing the blob of data.
7028  */
7029 MonoArray*
7030 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
7031 {
7032         MonoError error;
7033         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
7034         mono_error_cleanup (&error);
7035         return result;
7036 }
7037
7038 /**
7039  * mono_reflection_get_custom_attrs_blob_checked:
7040  * @ctor: custom attribute constructor
7041  * @ctorArgs: arguments o the constructor
7042  * @properties:
7043  * @propValues:
7044  * @fields:
7045  * @fieldValues:
7046  * @error: set on error
7047  * 
7048  * Creates the blob of data that needs to be saved in the metadata and that represents
7049  * the custom attributed described by @ctor, @ctorArgs etc.
7050  * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
7051  */
7052 MonoArray*
7053 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
7054 {
7055         MonoArray *result = NULL;
7056         MonoMethodSignature *sig;
7057         MonoObject *arg;
7058         char *buffer, *p;
7059         guint32 buflen, i;
7060
7061         mono_error_init (error);
7062
7063         if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
7064                 /* sig is freed later so allocate it in the heap */
7065                 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
7066                 if (!is_ok (error)) {
7067                         g_free (sig);
7068                         return NULL;
7069                 }
7070         } else {
7071                 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
7072         }
7073
7074         g_assert (mono_array_length (ctorArgs) == sig->param_count);
7075         buflen = 256;
7076         p = buffer = (char *)g_malloc (buflen);
7077         /* write the prolog */
7078         *p++ = 1;
7079         *p++ = 0;
7080         for (i = 0; i < sig->param_count; ++i) {
7081                 arg = mono_array_get (ctorArgs, MonoObject*, i);
7082                 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
7083                 if (!is_ok (error)) goto leave;
7084         }
7085         i = 0;
7086         if (properties)
7087                 i += mono_array_length (properties);
7088         if (fields)
7089                 i += mono_array_length (fields);
7090         *p++ = i & 0xff;
7091         *p++ = (i >> 8) & 0xff;
7092         if (properties) {
7093                 MonoObject *prop;
7094                 for (i = 0; i < mono_array_length (properties); ++i) {
7095                         MonoType *ptype;
7096                         char *pname;
7097
7098                         prop = (MonoObject *)mono_array_get (properties, gpointer, i);
7099                         get_prop_name_and_type (prop, &pname, &ptype, error);
7100                         if (!is_ok (error)) goto leave;
7101                         *p++ = 0x54; /* PROPERTY signature */
7102                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
7103                         g_free (pname);
7104                         if (!is_ok (error)) goto leave;
7105                 }
7106         }
7107
7108         if (fields) {
7109                 MonoObject *field;
7110                 for (i = 0; i < mono_array_length (fields); ++i) {
7111                         MonoType *ftype;
7112                         char *fname;
7113
7114                         field = (MonoObject *)mono_array_get (fields, gpointer, i);
7115                         get_field_name_and_type (field, &fname, &ftype, error);
7116                         if (!is_ok (error)) goto leave;
7117                         *p++ = 0x53; /* FIELD signature */
7118                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
7119                         g_free (fname);
7120                         if (!is_ok (error)) goto leave;
7121                 }
7122         }
7123
7124         g_assert (p - buffer <= buflen);
7125         buflen = p - buffer;
7126         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
7127         if (!is_ok (error))
7128                 goto leave;
7129         p = mono_array_addr (result, char, 0);
7130         memcpy (p, buffer, buflen);
7131 leave:
7132         g_free (buffer);
7133         if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
7134                 g_free (sig);
7135         return result;
7136 }
7137
7138 /**
7139  * reflection_setup_internal_class:
7140  * @tb: a TypeBuilder object
7141  * @error: set on error
7142  *
7143  * Creates a MonoClass that represents the TypeBuilder.
7144  * This is a trick that lets us simplify a lot of reflection code
7145  * (and will allow us to support Build and Run assemblies easier).
7146  *
7147  * Returns TRUE on success. On failure, returns FALSE and sets @error.
7148  */
7149 static gboolean
7150 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
7151 {
7152         MonoClass *klass, *parent;
7153
7154         mono_error_init (error);
7155         RESOLVE_TYPE (tb->parent, error);
7156         return_val_if_nok (error, FALSE);
7157
7158         mono_loader_lock ();
7159
7160         if (tb->parent) {
7161                 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
7162                 if (!is_ok (error)) {
7163                         mono_loader_unlock ();
7164                         return FALSE;
7165                 }
7166                 /* check so we can compile corlib correctly */
7167                 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
7168                         /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
7169                         parent = parent_type->data.klass;
7170                 } else {
7171                         parent = mono_class_from_mono_type (parent_type);
7172                 }
7173         } else {
7174                 parent = NULL;
7175         }
7176         
7177         /* the type has already being created: it means we just have to change the parent */
7178         if (tb->type.type) {
7179                 klass = mono_class_from_mono_type (tb->type.type);
7180                 klass->parent = NULL;
7181                 /* fool mono_class_setup_parent */
7182                 klass->supertypes = NULL;
7183                 mono_class_setup_parent (klass, parent);
7184                 mono_class_setup_mono_type (klass);
7185                 mono_loader_unlock ();
7186                 return TRUE;
7187         }
7188
7189         klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
7190
7191         klass->image = &tb->module->dynamic_image->image;
7192
7193         klass->inited = 1; /* we lie to the runtime */
7194         klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
7195         if (!is_ok (error))
7196                 goto failure;
7197         klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
7198         if (!is_ok (error))
7199                 goto failure;
7200         klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
7201         klass->flags = tb->attrs;
7202         
7203         mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
7204
7205         klass->element_class = klass;
7206
7207         if (mono_class_get_ref_info (klass) == NULL) {
7208
7209                 mono_class_set_ref_info (klass, tb);
7210
7211                 /* Put into cache so mono_class_get_checked () will find it.
7212                 Skip nested types as those should not be available on the global scope. */
7213                 if (!tb->nesting_type)
7214                         mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
7215
7216                 /*
7217                 We must register all types as we cannot rely on the name_cache hashtable since we find the class
7218                 by performing a mono_class_get which does the full resolution.
7219
7220                 Working around this semantics would require us to write a lot of code for no clear advantage.
7221                 */
7222                 mono_image_append_class_to_reflection_info_set (klass);
7223         } else {
7224                 g_assert (mono_class_get_ref_info (klass) == tb);
7225         }
7226
7227         mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
7228
7229         if (parent != NULL) {
7230                 mono_class_setup_parent (klass, parent);
7231         } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
7232                 const char *old_n = klass->name;
7233                 /* trick to get relative numbering right when compiling corlib */
7234                 klass->name = "BuildingObject";
7235                 mono_class_setup_parent (klass, mono_defaults.object_class);
7236                 klass->name = old_n;
7237         }
7238
7239         if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
7240                         (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
7241                         (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
7242                 klass->instance_size = sizeof (MonoObject);
7243                 klass->size_inited = 1;
7244                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
7245         }
7246
7247         mono_class_setup_mono_type (klass);
7248
7249         mono_class_setup_supertypes (klass);
7250
7251         /*
7252          * FIXME: handle interfaces.
7253          */
7254
7255         tb->type.type = &klass->byval_arg;
7256
7257         if (tb->nesting_type) {
7258                 g_assert (tb->nesting_type->type);
7259                 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
7260                 if (!is_ok (error)) goto failure;
7261                 klass->nested_in = mono_class_from_mono_type (nesting_type);
7262         }
7263
7264         /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
7265
7266         mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
7267         
7268         mono_loader_unlock ();
7269         return TRUE;
7270
7271 failure:
7272         mono_loader_unlock ();
7273         return FALSE;
7274 }
7275
7276 /**
7277  * ves_icall_TypeBuilder_setup_internal_class:
7278  * @tb: a TypeBuilder object
7279  *
7280  * (icall)
7281  * Creates a MonoClass that represents the TypeBuilder.
7282  * This is a trick that lets us simplify a lot of reflection code
7283  * (and will allow us to support Build and Run assemblies easier).
7284  *
7285  */
7286 void
7287 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
7288 {
7289         MonoError error;
7290         (void) reflection_setup_internal_class (tb, &error);
7291         mono_error_set_pending_exception (&error);
7292 }
7293
7294 /*
7295  * ves_icall_TypeBuilder_setup_generic_class:
7296  * @tb: a TypeBuilder object
7297  *
7298  * Setup the generic class before adding the first generic parameter.
7299  */
7300 void
7301 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
7302 {
7303 }
7304
7305 /**
7306  * mono_reflection_create_generic_class:
7307  * @tb: a TypeBuilder object
7308  * @error: set on error
7309  *
7310  * Creates the generic class after all generic parameters have been added.
7311  * On success returns TRUE, on failure returns FALSE and sets @error.
7312  * 
7313  */
7314 gboolean
7315 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
7316 {
7317
7318         MonoClass *klass;
7319         int count, i;
7320
7321         mono_error_init (error);
7322
7323         klass = mono_class_from_mono_type (tb->type.type);
7324
7325         count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
7326
7327         if (klass->generic_container || (count == 0))
7328                 return TRUE;
7329
7330         g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
7331
7332         klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
7333
7334         klass->generic_container->owner.klass = klass;
7335         klass->generic_container->type_argc = count;
7336         klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
7337
7338         klass->is_generic = 1;
7339
7340         for (i = 0; i < count; i++) {
7341                 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
7342                 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
7343                 return_val_if_nok (error, FALSE);
7344                 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
7345                 klass->generic_container->type_params [i] = *param;
7346                 /*Make sure we are a diferent type instance */
7347                 klass->generic_container->type_params [i].param.owner = klass->generic_container;
7348                 klass->generic_container->type_params [i].info.pklass = NULL;
7349                 klass->generic_container->type_params [i].info.flags = gparam->attrs;
7350
7351                 g_assert (klass->generic_container->type_params [i].param.owner);
7352         }
7353
7354         klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
7355         return TRUE;
7356 }
7357
7358 /**
7359  * reflection_create_internal_class:
7360  * @tb: a TypeBuilder object
7361  * @error: set on error
7362  *
7363  * Actually create the MonoClass that is associated with the TypeBuilder.
7364  * On success returns TRUE, on failure returns FALSE and sets @error.
7365  *
7366  */
7367 static gboolean
7368 reflection_create_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
7369 {
7370         MonoClass *klass;
7371
7372         mono_error_init (error);
7373         klass = mono_class_from_mono_type (tb->type.type);
7374
7375         mono_loader_lock ();
7376         if (klass->enumtype && mono_class_enum_basetype (klass) == NULL) {
7377                 MonoReflectionFieldBuilder *fb;
7378                 MonoClass *ec;
7379                 MonoType *enum_basetype;
7380
7381                 g_assert (tb->fields != NULL);
7382                 g_assert (mono_array_length (tb->fields) >= 1);
7383
7384                 fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
7385
7386                 MonoType *field_type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
7387                 if (!is_ok (error)) {
7388                         mono_loader_unlock ();
7389                         return FALSE;
7390                 }
7391                 if (!mono_type_is_valid_enum_basetype (field_type)) {
7392                         mono_loader_unlock ();
7393                         return TRUE;
7394                 }
7395
7396                 enum_basetype = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
7397                 if (!is_ok (error)) {
7398                         mono_loader_unlock ();
7399                         return FALSE;
7400                 }
7401                 klass->element_class = mono_class_from_mono_type (enum_basetype);
7402                 if (!klass->element_class)
7403                         klass->element_class = mono_class_from_mono_type (enum_basetype);
7404
7405                 /*
7406                  * get the element_class from the current corlib.
7407                  */
7408                 ec = default_class_from_mono_type (enum_basetype);
7409                 klass->instance_size = ec->instance_size;
7410                 klass->size_inited = 1;
7411                 /* 
7412                  * this is almost safe to do with enums and it's needed to be able
7413                  * to create objects of the enum type (for use in SetConstant).
7414                  */
7415                 /* FIXME: Does this mean enums can't have method overrides ? */
7416                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
7417         }
7418         mono_loader_unlock ();
7419         return TRUE;
7420 }
7421
7422 /**
7423  * ves_icall_TypeBuilder_create_internal_class:
7424  * @tb: a TypeBuilder object
7425  *
7426  * (icall)
7427  * Actually create the MonoClass that is associated with the TypeBuilder.
7428  */
7429 void
7430 ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
7431 {
7432         MonoError error;
7433         (void) reflection_create_internal_class (tb, &error);
7434         mono_error_set_pending_exception (&error);
7435 }
7436
7437 static MonoMarshalSpec*
7438 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
7439                                 MonoReflectionMarshal *minfo, MonoError *error)
7440 {
7441         MonoMarshalSpec *res;
7442
7443         mono_error_init (error);
7444
7445         res = image_g_new0 (image, MonoMarshalSpec, 1);
7446         res->native = (MonoMarshalNative)minfo->type;
7447
7448         switch (minfo->type) {
7449         case MONO_NATIVE_LPARRAY:
7450                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
7451                 if (minfo->has_size) {
7452                         res->data.array_data.param_num = minfo->param_num;
7453                         res->data.array_data.num_elem = minfo->count;
7454                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
7455                 }
7456                 else {
7457                         res->data.array_data.param_num = -1;
7458                         res->data.array_data.num_elem = -1;
7459                         res->data.array_data.elem_mult = -1;
7460                 }
7461                 break;
7462
7463         case MONO_NATIVE_BYVALTSTR:
7464         case MONO_NATIVE_BYVALARRAY:
7465                 res->data.array_data.num_elem = minfo->count;
7466                 break;
7467
7468         case MONO_NATIVE_CUSTOM:
7469                 if (minfo->marshaltyperef) {
7470                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
7471                         if (!is_ok (error)) {
7472                                 image_g_free (image, res);
7473                                 return NULL;
7474                         }
7475                         res->data.custom_data.custom_name =
7476                                 type_get_fully_qualified_name (marshaltyperef);
7477                 }
7478                 if (minfo->mcookie) {
7479                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
7480                         if (!is_ok (error)) {
7481                                 image_g_free (image, res);
7482                                 return NULL;
7483                         }
7484                 }
7485                 break;
7486
7487         default:
7488                 break;
7489         }
7490
7491         return res;
7492 }
7493 #endif /* !DISABLE_REFLECTION_EMIT */
7494
7495 MonoReflectionMarshalAsAttribute*
7496 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
7497                                                         MonoMarshalSpec *spec, MonoError *error)
7498 {
7499         MonoReflectionType *rt;
7500         MonoReflectionMarshalAsAttribute *minfo;
7501         MonoType *mtype;
7502
7503         mono_error_init (error);
7504         
7505         minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
7506         if (!minfo)
7507                 return NULL;
7508         minfo->utype = spec->native;
7509
7510         switch (minfo->utype) {
7511         case MONO_NATIVE_LPARRAY:
7512                 minfo->array_subtype = spec->data.array_data.elem_type;
7513                 minfo->size_const = spec->data.array_data.num_elem;
7514                 if (spec->data.array_data.param_num != -1)
7515                         minfo->size_param_index = spec->data.array_data.param_num;
7516                 break;
7517
7518         case MONO_NATIVE_BYVALTSTR:
7519         case MONO_NATIVE_BYVALARRAY:
7520                 minfo->size_const = spec->data.array_data.num_elem;
7521                 break;
7522
7523         case MONO_NATIVE_CUSTOM:
7524                 if (spec->data.custom_data.custom_name) {
7525                         mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
7526                         return_val_if_nok  (error, NULL);
7527
7528                         if (mtype) {
7529                                 rt = mono_type_get_object_checked (domain, mtype, error);
7530                                 if (!rt)
7531                                         return NULL;
7532
7533                                 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
7534                         }
7535
7536                         MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
7537                 }
7538                 if (spec->data.custom_data.cookie)
7539                         MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
7540                 break;
7541
7542         default:
7543                 break;
7544         }
7545
7546         return minfo;
7547 }
7548
7549 #ifndef DISABLE_REFLECTION_EMIT
7550 static MonoMethod*
7551 reflection_methodbuilder_to_mono_method (MonoClass *klass,
7552                                          ReflectionMethodBuilder *rmb,
7553                                          MonoMethodSignature *sig,
7554                                          MonoError *error)
7555 {
7556         MonoMethod *m;
7557         MonoMethodWrapper *wrapperm;
7558         MonoMarshalSpec **specs;
7559         MonoReflectionMethodAux *method_aux;
7560         MonoImage *image;
7561         gboolean dynamic;
7562         int i;
7563
7564         mono_error_init (error);
7565         /*
7566          * Methods created using a MethodBuilder should have their memory allocated
7567          * inside the image mempool, while dynamic methods should have their memory
7568          * malloc'd.
7569          */
7570         dynamic = rmb->refs != NULL;
7571         image = dynamic ? NULL : klass->image;
7572
7573         if (!dynamic)
7574                 g_assert (!klass->generic_class);
7575
7576         mono_loader_lock ();
7577
7578         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
7579                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
7580                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
7581         else
7582                 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
7583
7584         wrapperm = (MonoMethodWrapper*)m;
7585
7586         m->dynamic = dynamic;
7587         m->slot = -1;
7588         m->flags = rmb->attrs;
7589         m->iflags = rmb->iattrs;
7590         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
7591         m->klass = klass;
7592         m->signature = sig;
7593         m->sre_method = TRUE;
7594         m->skip_visibility = rmb->skip_visibility;
7595         if (rmb->table_idx)
7596                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
7597
7598         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
7599                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
7600                         m->string_ctor = 1;
7601
7602                 m->signature->pinvoke = 1;
7603         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
7604                 m->signature->pinvoke = 1;
7605
7606                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
7607
7608                 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
7609                 mono_error_assert_ok (error);
7610                 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
7611                 mono_error_assert_ok (error);
7612                 
7613                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
7614
7615                 if (image_is_dynamic (klass->image))
7616                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
7617
7618                 mono_loader_unlock ();
7619
7620                 return m;
7621         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
7622                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
7623                 MonoMethodHeader *header;
7624                 guint32 code_size;
7625                 gint32 max_stack, i;
7626                 gint32 num_locals = 0;
7627                 gint32 num_clauses = 0;
7628                 guint8 *code;
7629
7630                 if (rmb->ilgen) {
7631                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
7632                         code_size = rmb->ilgen->code_len;
7633                         max_stack = rmb->ilgen->max_stack;
7634                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
7635                         if (rmb->ilgen->ex_handlers)
7636                                 num_clauses = method_count_clauses (rmb->ilgen);
7637                 } else {
7638                         if (rmb->code) {
7639                                 code = mono_array_addr (rmb->code, guint8, 0);
7640                                 code_size = mono_array_length (rmb->code);
7641                                 /* we probably need to run a verifier on the code... */
7642                                 max_stack = 8; 
7643                         }
7644                         else {
7645                                 code = NULL;
7646                                 code_size = 0;
7647                                 max_stack = 8;
7648                         }
7649                 }
7650
7651                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
7652                 header->code_size = code_size;
7653                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
7654                 memcpy ((char*)header->code, code, code_size);
7655                 header->max_stack = max_stack;
7656                 header->init_locals = rmb->init_locals;
7657                 header->num_locals = num_locals;
7658
7659                 for (i = 0; i < num_locals; ++i) {
7660                         MonoReflectionLocalBuilder *lb = 
7661                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
7662
7663                         header->locals [i] = image_g_new0 (image, MonoType, 1);
7664                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
7665                         mono_error_assert_ok (error);
7666                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
7667                 }
7668
7669                 header->num_clauses = num_clauses;
7670                 if (num_clauses) {
7671                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
7672                                                                  rmb->ilgen, num_clauses, error);
7673                         mono_error_assert_ok (error);
7674                 }
7675
7676                 wrapperm->header = header;
7677         }
7678
7679         if (rmb->generic_params) {
7680                 int count = mono_array_length (rmb->generic_params);
7681                 MonoGenericContainer *container = rmb->generic_container;
7682
7683                 g_assert (container);
7684
7685                 container->type_argc = count;
7686                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
7687                 container->owner.method = m;
7688                 container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
7689
7690                 m->is_generic = TRUE;
7691                 mono_method_set_generic_container (m, container);
7692
7693                 for (i = 0; i < count; i++) {
7694                         MonoReflectionGenericParam *gp =
7695                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
7696                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
7697                         mono_error_assert_ok (error);
7698                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
7699                         container->type_params [i] = *param;
7700                 }
7701
7702                 /*
7703                  * The method signature might have pointers to generic parameters that belong to other methods.
7704                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
7705                  * generic parameters.
7706                  */
7707                 for (i = 0; i < m->signature->param_count; ++i) {
7708                         MonoType *t = m->signature->params [i];
7709                         if (t->type == MONO_TYPE_MVAR) {
7710                                 MonoGenericParam *gparam =  t->data.generic_param;
7711                                 if (gparam->num < count) {
7712                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
7713                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
7714                                 }
7715
7716                         }
7717                 }
7718
7719                 if (klass->generic_container) {
7720                         container->parent = klass->generic_container;
7721                         container->context.class_inst = klass->generic_container->context.class_inst;
7722                 }
7723                 container->context.method_inst = mono_get_shared_generic_inst (container);
7724         }
7725
7726         if (rmb->refs) {
7727                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
7728                 int i;
7729                 void **data;
7730
7731                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
7732
7733                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
7734                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
7735                 for (i = 0; i < rmb->nrefs; ++i)
7736                         data [i + 1] = rmb->refs [i];
7737         }
7738
7739         method_aux = NULL;
7740
7741         /* Parameter info */
7742         if (rmb->pinfo) {
7743                 if (!method_aux)
7744                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
7745                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
7746                 for (i = 0; i <= m->signature->param_count; ++i) {
7747                         MonoReflectionParamBuilder *pb;
7748                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
7749                                 if ((i > 0) && (pb->attrs)) {
7750                                         /* Make a copy since it might point to a shared type structure */
7751                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
7752                                         m->signature->params [i - 1]->attrs = pb->attrs;
7753                                 }
7754
7755                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
7756                                         MonoDynamicImage *assembly;
7757                                         guint32 idx, len;
7758                                         MonoTypeEnum def_type;
7759                                         char *p;
7760                                         const char *p2;
7761
7762                                         if (!method_aux->param_defaults) {
7763                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
7764                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
7765                                         }
7766                                         assembly = (MonoDynamicImage*)klass->image;
7767                                         idx = encode_constant (assembly, pb->def_value, &def_type);
7768                                         /* Copy the data from the blob since it might get realloc-ed */
7769                                         p = assembly->blob.data + idx;
7770                                         len = mono_metadata_decode_blob_size (p, &p2);
7771                                         len += p2 - p;
7772                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
7773                                         method_aux->param_default_types [i] = def_type;
7774                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
7775                                 }
7776
7777                                 if (pb->name) {
7778                                         method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
7779                                         mono_error_assert_ok (error);
7780                                 }
7781                                 if (pb->cattrs) {
7782                                         if (!method_aux->param_cattr)
7783                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
7784                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
7785                                 }
7786                         }
7787                 }
7788         }
7789
7790         /* Parameter marshalling */
7791         specs = NULL;
7792         if (rmb->pinfo)         
7793                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
7794                         MonoReflectionParamBuilder *pb;
7795                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
7796                                 if (pb->marshal_info) {
7797                                         if (specs == NULL)
7798                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
7799                                         specs [pb->position] = 
7800                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
7801                                         if (!is_ok (error)) {
7802                                                 mono_loader_unlock ();
7803                                                 image_g_free (image, specs);
7804                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
7805                                                 return NULL;
7806                                         }
7807                                 }
7808                         }
7809                 }
7810         if (specs != NULL) {
7811                 if (!method_aux)
7812                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
7813                 method_aux->param_marshall = specs;
7814         }
7815
7816         if (image_is_dynamic (klass->image) && method_aux)
7817                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
7818
7819         mono_loader_unlock ();
7820
7821         return m;
7822 }       
7823
7824 static MonoMethod*
7825 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
7826 {
7827         ReflectionMethodBuilder rmb;
7828         MonoMethodSignature *sig;
7829
7830         mono_loader_lock ();
7831         g_assert (klass->image != NULL);
7832         sig = ctor_builder_to_signature (klass->image, mb, error);
7833         mono_loader_unlock ();
7834         return_val_if_nok (error, NULL);
7835
7836         if (!reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
7837                 return NULL;
7838
7839         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
7840         return_val_if_nok (error, NULL);
7841         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
7842
7843         /* If we are in a generic class, we might be called multiple times from inflate_method */
7844         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
7845                 /* ilgen is no longer needed */
7846                 mb->ilgen = NULL;
7847         }
7848
7849         return mb->mhandle;
7850 }
7851
7852 static MonoMethod*
7853 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
7854 {
7855         ReflectionMethodBuilder rmb;
7856         MonoMethodSignature *sig;
7857
7858         mono_error_init (error);
7859
7860         mono_loader_lock ();
7861         g_assert (klass->image != NULL);
7862         sig = method_builder_to_signature (klass->image, mb, error);
7863         mono_loader_unlock ();
7864         return_val_if_nok (error, NULL);
7865
7866         if (!reflection_methodbuilder_from_method_builder (&rmb, mb, error))
7867                 return NULL;
7868
7869         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
7870         return_val_if_nok (error, NULL);
7871         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
7872
7873         /* If we are in a generic class, we might be called multiple times from inflate_method */
7874         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
7875                 /* ilgen is no longer needed */
7876                 mb->ilgen = NULL;
7877         }
7878         return mb->mhandle;
7879 }
7880
7881 static MonoClassField*
7882 fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb, MonoError *error)
7883 {
7884         MonoClassField *field;
7885         MonoType *custom;
7886
7887         mono_error_init (error);
7888
7889         field = g_new0 (MonoClassField, 1);
7890
7891         field->name = mono_string_to_utf8_image (klass->image, fb->name, error);
7892         mono_error_assert_ok (error);
7893         if (fb->attrs || fb->modreq || fb->modopt) {
7894                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
7895                 if (!is_ok (error)) {
7896                         g_free (field);
7897                         return NULL;
7898                 }
7899                 field->type = mono_metadata_type_dup (NULL, type);
7900                 field->type->attrs = fb->attrs;
7901
7902                 g_assert (image_is_dynamic (klass->image));
7903                 custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt, error);
7904                 g_free (field->type);
7905                 if (!is_ok (error)) {
7906                         g_free (field);
7907                         return NULL;
7908                 }
7909                 field->type = mono_metadata_type_dup (klass->image, custom);
7910                 g_free (custom);
7911         } else {
7912                 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
7913                 if (!is_ok (error)) {
7914                         g_free (field);
7915                         return NULL;
7916                 }
7917         }
7918         if (fb->offset != -1)
7919                 field->offset = fb->offset;
7920         field->parent = klass;
7921         mono_save_custom_attrs (klass->image, field, fb->cattrs);
7922
7923         // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
7924
7925         return field;
7926 }
7927 #endif
7928
7929 #ifndef DISABLE_REFLECTION_EMIT
7930
7931 static MonoMethod *
7932 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
7933 {
7934         MonoMethodInflated *imethod;
7935         MonoGenericContext *context;
7936         int i;
7937
7938         /*
7939          * With generic code sharing the klass might not be inflated.
7940          * This can happen because classes inflated with their own
7941          * type arguments are "normalized" to the uninflated class.
7942          */
7943         if (!klass->generic_class)
7944                 return method;
7945
7946         context = mono_class_get_context (klass);
7947
7948         if (klass->method.count && klass->methods) {
7949                 /* Find the already created inflated method */
7950                 for (i = 0; i < klass->method.count; ++i) {
7951                         g_assert (klass->methods [i]->is_inflated);
7952                         if (((MonoMethodInflated*)klass->methods [i])->declaring == method)
7953                                 break;
7954                 }
7955                 g_assert (i < klass->method.count);
7956                 imethod = (MonoMethodInflated*)klass->methods [i];
7957         } else {
7958                 MonoError error;
7959                 imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full_checked (method, klass, context, &error);
7960                 mono_error_assert_ok (&error);
7961         }
7962
7963         if (method->is_generic && image_is_dynamic (method->klass->image)) {
7964                 MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
7965
7966                 mono_image_lock ((MonoImage*)image);
7967                 mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
7968                 mono_image_unlock ((MonoImage*)image);
7969         }
7970         return (MonoMethod *) imethod;
7971 }
7972
7973 static MonoMethod *
7974 inflate_method (MonoReflectionType *type, MonoObject *obj, MonoError *error)
7975 {
7976         MonoMethod *method;
7977         MonoClass *gklass;
7978
7979         mono_error_init (error);
7980
7981         MonoClass *type_class = mono_object_class (type);
7982
7983         if (is_sre_generic_instance (type_class)) {
7984                 MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
7985                 MonoType *generic_type = mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type, error);
7986                 return_val_if_nok (error, NULL);
7987                 gklass = mono_class_from_mono_type (generic_type);
7988         } else if (is_sre_type_builder (type_class)) {
7989                 MonoType *t = mono_reflection_type_get_handle (type, error);
7990                 return_val_if_nok (error, NULL);
7991                 gklass = mono_class_from_mono_type (t);
7992         } else if (type->type) {
7993                 gklass = mono_class_from_mono_type (type->type);
7994                 gklass = mono_class_get_generic_type_definition (gklass);
7995         } else {
7996                 g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
7997         }
7998
7999         if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
8000                 if (((MonoReflectionMethodBuilder*)obj)->mhandle)
8001                         method = ((MonoReflectionMethodBuilder*)obj)->mhandle;
8002                 else {
8003                         method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj, error);
8004                         if (!method)
8005                                 return NULL;
8006                 }
8007         else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) {
8008                 method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj, error);
8009                 if (!method)
8010                         return NULL;
8011         } else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
8012                 method = ((MonoReflectionMethod *) obj)->method;
8013         else {
8014                 method = NULL; /* prevent compiler warning */
8015                 g_error ("can't handle type %s", obj->vtable->klass->name);
8016         }
8017
8018         MonoType *t = mono_reflection_type_get_handle (type, error);
8019         return_val_if_nok (error, NULL);
8020         return inflate_mono_method (mono_class_from_mono_type (t), method, obj);
8021 }
8022
8023 /*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
8024 static gboolean
8025 reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields, MonoError *error)
8026 {
8027         MonoGenericClass *gclass;
8028         MonoDynamicGenericClass *dgclass;
8029         MonoClass *klass, *gklass;
8030         MonoType *gtype;
8031         int i;
8032
8033         mono_error_init (error);
8034
8035         gtype = mono_reflection_type_get_handle ((MonoReflectionType*)type, error);
8036         return_val_if_nok (error, FALSE);
8037         klass = mono_class_from_mono_type (gtype);
8038         g_assert (gtype->type == MONO_TYPE_GENERICINST);
8039         gclass = gtype->data.generic_class;
8040
8041         if (!gclass->is_dynamic)
8042                 return TRUE;
8043
8044         dgclass = (MonoDynamicGenericClass *) gclass;
8045
8046         if (dgclass->initialized)
8047                 return TRUE;
8048
8049         gklass = gclass->container_class;
8050         mono_class_init (gklass);
8051
8052         dgclass->count_fields = fields ? mono_array_length (fields) : 0;
8053
8054         dgclass->fields = mono_image_set_new0 (gclass->owner, MonoClassField, dgclass->count_fields);
8055         dgclass->field_objects = mono_image_set_new0 (gclass->owner, MonoObject*, dgclass->count_fields);
8056         dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
8057
8058         for (i = 0; i < dgclass->count_fields; i++) {
8059                 MonoObject *obj = (MonoObject *)mono_array_get (fields, gpointer, i);
8060                 MonoClassField *field, *inflated_field = NULL;
8061
8062                 if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) {
8063                         inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj, error);
8064                         return_val_if_nok (error, FALSE);
8065                 } else if (!strcmp (obj->vtable->klass->name, "MonoField"))
8066                         field = ((MonoReflectionField *) obj)->field;
8067                 else {
8068                         field = NULL; /* prevent compiler warning */
8069                         g_assert_not_reached ();
8070                 }
8071
8072                 dgclass->fields [i] = *field;
8073                 dgclass->fields [i].parent = klass;
8074                 dgclass->fields [i].type = mono_class_inflate_generic_type_checked (
8075                         field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass), error);
8076                 mono_error_assert_ok (error); /* FIXME don't swallow the error */
8077                 dgclass->field_generic_types [i] = field->type;
8078                 MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i], MONO_ROOT_SOURCE_REFLECTION, "dynamic generic class field object");
8079                 dgclass->field_objects [i] = obj;
8080
8081                 if (inflated_field) {
8082                         g_free (inflated_field);
8083                 } else {
8084                         dgclass->fields [i].name = mono_image_set_strdup (gclass->owner, dgclass->fields [i].name);
8085                 }
8086         }
8087
8088         dgclass->initialized = TRUE;
8089         return TRUE;
8090 }
8091
8092 void
8093 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
8094 {
8095         MonoError error;
8096         (void) reflection_generic_class_initialize (type, fields, &error);
8097         mono_error_set_pending_exception (&error);
8098 }
8099
8100 void
8101 mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
8102 {
8103         MonoDynamicGenericClass *dgclass;
8104         int i;
8105
8106         g_assert (gclass->is_dynamic);
8107
8108         dgclass = (MonoDynamicGenericClass *)gclass;
8109
8110         for (i = 0; i < dgclass->count_fields; ++i) {
8111                 MonoClassField *field = dgclass->fields + i;
8112                 mono_metadata_free_type (field->type);
8113                 MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
8114         }
8115 }
8116
8117 /**
8118  * fix_partial_generic_class:
8119  * @klass: a generic instantiation MonoClass
8120  * @error: set on error
8121  *
8122  * Assumes that the generic container of @klass has its vtable
8123  * initialized, and updates the parent class, insterfaces, methods and
8124  * fields of @klass by inflating the types using the generic context.
8125  *
8126  * On success returns TRUE, on failure returns FALSE and sets @error.
8127  *
8128  */
8129 static gboolean
8130 fix_partial_generic_class (MonoClass *klass, MonoError *error)
8131 {
8132         MonoClass *gklass = klass->generic_class->container_class;
8133         MonoDynamicGenericClass *dgclass;
8134         int i;
8135
8136         mono_error_init (error);
8137
8138         if (klass->wastypebuilder)
8139                 return TRUE;
8140
8141         dgclass = (MonoDynamicGenericClass *)  klass->generic_class;
8142         if (klass->parent != gklass->parent) {
8143                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
8144                 if (mono_error_ok (error)) {
8145                         MonoClass *parent = mono_class_from_mono_type (parent_type);
8146                         mono_metadata_free_type (parent_type);
8147                         if (parent != klass->parent) {
8148                                 /*fool mono_class_setup_parent*/
8149                                 klass->supertypes = NULL;
8150                                 mono_class_setup_parent (klass, parent);
8151                         }
8152                 } else {
8153                         if (gklass->wastypebuilder)
8154                                 klass->wastypebuilder = TRUE;
8155                         return FALSE;
8156                 }
8157         }
8158
8159         if (!dgclass->initialized)
8160                 return TRUE;
8161
8162         if (klass->method.count != gklass->method.count) {
8163                 klass->method.count = gklass->method.count;
8164                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
8165
8166                 for (i = 0; i < klass->method.count; i++) {
8167                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
8168                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
8169                         mono_error_assert_ok (error);
8170                 }
8171         }
8172
8173         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
8174                 klass->interface_count = gklass->interface_count;
8175                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
8176                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
8177
8178                 for (i = 0; i < gklass->interface_count; ++i) {
8179                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
8180                         return_val_if_nok (error, FALSE);
8181
8182                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
8183                         mono_metadata_free_type (iface_type);
8184
8185                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
8186                                 return FALSE;
8187                 }
8188                 klass->interfaces_inited = 1;
8189         }
8190
8191         if (klass->field.count != gklass->field.count) {
8192                 klass->field.count = gklass->field.count;
8193                 klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
8194
8195                 for (i = 0; i < klass->field.count; i++) {
8196                         klass->fields [i] = gklass->fields [i];
8197                         klass->fields [i].parent = klass;
8198                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
8199                         return_val_if_nok (error, FALSE);
8200                 }
8201         }
8202
8203         /*We can only finish with this klass once it's parent has as well*/
8204         if (gklass->wastypebuilder)
8205                 klass->wastypebuilder = TRUE;
8206         return TRUE;
8207 }
8208
8209 /**
8210  * ensure_generic_class_runtime_vtable:
8211  * @klass a generic class
8212  * @error set on error
8213  *
8214  * Ensures that the generic container of @klass has a vtable and
8215  * returns TRUE on success.  On error returns FALSE and sets @error.
8216  */
8217 static gboolean
8218 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
8219 {
8220         MonoClass *gklass = klass->generic_class->container_class;
8221
8222         mono_error_init (error);
8223
8224         if (!ensure_runtime_vtable (gklass, error))
8225                 return FALSE;
8226
8227         return fix_partial_generic_class (klass, error);
8228 }
8229
8230 /**
8231  * ensure_runtime_vtable:
8232  * @klass the class
8233  * @error set on error
8234  *
8235  * Ensures that @klass has a vtable and returns TRUE on success. On
8236  * error returns FALSE and sets @error.
8237  */
8238 static gboolean
8239 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
8240 {
8241         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
8242         int i, num, j;
8243
8244         mono_error_init (error);
8245
8246         if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
8247                 return TRUE;
8248         if (klass->parent)
8249                 if (!ensure_runtime_vtable (klass->parent, error))
8250                         return FALSE;
8251
8252         if (tb) {
8253                 num = tb->ctors? mono_array_length (tb->ctors): 0;
8254                 num += tb->num_methods;
8255                 klass->method.count = num;
8256                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
8257                 num = tb->ctors? mono_array_length (tb->ctors): 0;
8258                 for (i = 0; i < num; ++i) {
8259                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
8260                         if (!ctor)
8261                                 return FALSE;
8262                         klass->methods [i] = ctor;
8263                 }
8264                 num = tb->num_methods;
8265                 j = i;
8266                 for (i = 0; i < num; ++i) {
8267                         MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
8268                         if (!meth)
8269                                 return FALSE;
8270                         klass->methods [j++] = meth;
8271                 }
8272         
8273                 if (tb->interfaces) {
8274                         klass->interface_count = mono_array_length (tb->interfaces);
8275                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
8276                         for (i = 0; i < klass->interface_count; ++i) {
8277                                 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
8278                                 return_val_if_nok (error, FALSE);
8279                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
8280                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
8281                                         return FALSE;
8282                         }
8283                         klass->interfaces_inited = 1;
8284                 }
8285         } else if (klass->generic_class){
8286                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
8287                         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
8288                         return FALSE;
8289                 }
8290         }
8291
8292         if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
8293                 int slot_num = 0;
8294                 for (i = 0; i < klass->method.count; ++i) {
8295                         MonoMethod *im = klass->methods [i];
8296                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
8297                                 im->slot = slot_num++;
8298                 }
8299                 
8300                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
8301                 mono_class_setup_interface_offsets (klass);
8302                 mono_class_setup_interface_id (klass);
8303         }
8304
8305         /*
8306          * The generic vtable is needed even if image->run is not set since some
8307          * runtime code like ves_icall_Type_GetMethodsByName depends on 
8308          * method->slot being defined.
8309          */
8310
8311         /* 
8312          * tb->methods could not be freed since it is used for determining 
8313          * overrides during dynamic vtable construction.
8314          */
8315
8316         return TRUE;
8317 }
8318
8319 static MonoMethod*
8320 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
8321 {
8322         mono_error_init (error);
8323         MonoClass *klass = mono_object_class (method);
8324         if (is_sr_mono_method (klass) || is_sr_mono_generic_method (klass)) {
8325                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
8326                 return sr_method->method;
8327         }
8328         if (is_sre_method_builder (klass)) {
8329                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
8330                 return mb->mhandle;
8331         }
8332         if (mono_is_sre_method_on_tb_inst (klass)) {
8333                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
8334                 MonoMethod *result;
8335                 /*FIXME move this to a proper method and unify with resolve_object*/
8336                 if (m->method_args) {
8337                         result = mono_reflection_method_on_tb_inst_get_handle (m, error);
8338                 } else {
8339                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
8340                         return_val_if_nok (error, NULL);
8341                         MonoClass *inflated_klass = mono_class_from_mono_type (type);
8342                         MonoMethod *mono_method;
8343
8344                         if (is_sre_method_builder (mono_object_class (m->mb)))
8345                                 mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
8346                         else if (is_sr_mono_method (mono_object_class (m->mb)))
8347                                 mono_method = ((MonoReflectionMethod *)m->mb)->method;
8348                         else
8349                                 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)));
8350
8351                         result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
8352                 }
8353                 return result;
8354         }
8355
8356         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
8357         return NULL;
8358 }
8359
8360 void
8361 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
8362 {
8363         MonoReflectionTypeBuilder *tb;
8364         int i, j, onum;
8365         MonoReflectionMethod *m;
8366
8367         mono_error_init (error);
8368         *overrides = NULL;
8369         *num_overrides = 0;
8370
8371         g_assert (image_is_dynamic (klass->image));
8372
8373         if (!mono_class_get_ref_info (klass))
8374                 return;
8375
8376         g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
8377
8378         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
8379
8380         onum = 0;
8381         if (tb->methods) {
8382                 for (i = 0; i < tb->num_methods; ++i) {
8383                         MonoReflectionMethodBuilder *mb = 
8384                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
8385                         if (mb->override_methods)
8386                                 onum += mono_array_length (mb->override_methods);
8387                 }
8388         }
8389
8390         if (onum) {
8391                 *overrides = g_new0 (MonoMethod*, onum * 2);
8392
8393                 onum = 0;
8394                 for (i = 0; i < tb->num_methods; ++i) {
8395                         MonoReflectionMethodBuilder *mb = 
8396                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
8397                         if (mb->override_methods) {
8398                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
8399                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
8400
8401                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
8402                                         return_if_nok (error);
8403                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
8404
8405                                         g_assert (mb->mhandle);
8406
8407                                         onum ++;
8408                                 }
8409                         }
8410                 }
8411         }
8412
8413         *num_overrides = onum;
8414 }
8415
8416 static void
8417 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
8418 {
8419         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
8420         MonoReflectionFieldBuilder *fb;
8421         MonoClassField *field;
8422         MonoImage *image = klass->image;
8423         const char *p, *p2;
8424         int i;
8425         guint32 len, idx, real_size = 0;
8426
8427         klass->field.count = tb->num_fields;
8428         klass->field.first = 0;
8429
8430         mono_error_init (error);
8431
8432         if (tb->class_size) {
8433                 if ((tb->packing_size & 0xffffff00) != 0) {
8434                         char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
8435                         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
8436                         return;
8437                 }
8438                 klass->packing_size = tb->packing_size;
8439                 real_size = klass->instance_size + tb->class_size;
8440         }
8441
8442         if (!klass->field.count) {
8443                 klass->instance_size = MAX (klass->instance_size, real_size);
8444                 return;
8445         }
8446         
8447         klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
8448         mono_class_alloc_ext (klass);
8449         klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
8450         /*
8451         This is, guess what, a hack.
8452         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
8453         On the static path no field class is resolved, only types are built. This is the right thing to do
8454         but we suck.
8455         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
8456         */
8457         klass->size_inited = 1;
8458
8459         for (i = 0; i < klass->field.count; ++i) {
8460                 MonoArray *rva_data;
8461                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
8462                 field = &klass->fields [i];
8463                 field->name = mono_string_to_utf8_image (image, fb->name, error);
8464                 if (!mono_error_ok (error))
8465                         return;
8466                 if (fb->attrs) {
8467                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
8468                         return_if_nok (error);
8469                         field->type = mono_metadata_type_dup (klass->image, type);
8470                         field->type->attrs = fb->attrs;
8471                 } else {
8472                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
8473                         return_if_nok (error);
8474                 }
8475
8476                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
8477                         char *base = mono_array_addr (rva_data, char, 0);
8478                         size_t size = mono_array_length (rva_data);
8479                         char *data = (char *)mono_image_alloc (klass->image, size);
8480                         memcpy (data, base, size);
8481                         klass->ext->field_def_values [i].data = data;
8482                 }
8483                 if (fb->offset != -1)
8484                         field->offset = fb->offset;
8485                 field->parent = klass;
8486                 fb->handle = field;
8487                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
8488
8489                 if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
8490                         klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
8491                 }
8492                 if (fb->def_value) {
8493                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
8494                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
8495                         idx = encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
8496                         /* Copy the data from the blob since it might get realloc-ed */
8497                         p = assembly->blob.data + idx;
8498                         len = mono_metadata_decode_blob_size (p, &p2);
8499                         len += p2 - p;
8500                         klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
8501                         memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
8502                 }
8503         }
8504
8505         klass->instance_size = MAX (klass->instance_size, real_size);
8506         mono_class_layout_fields (klass, klass->instance_size);
8507 }
8508
8509 static void
8510 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
8511 {
8512         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
8513         MonoReflectionPropertyBuilder *pb;
8514         MonoImage *image = klass->image;
8515         MonoProperty *properties;
8516         int i;
8517
8518         mono_error_init (error);
8519
8520         if (!klass->ext)
8521                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
8522
8523         klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
8524         klass->ext->property.first = 0;
8525
8526         properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
8527         klass->ext->properties = properties;
8528         for (i = 0; i < klass->ext->property.count; ++i) {
8529                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
8530                 properties [i].parent = klass;
8531                 properties [i].attrs = pb->attrs;
8532                 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
8533                 if (!mono_error_ok (error))
8534                         return;
8535                 if (pb->get_method)
8536                         properties [i].get = pb->get_method->mhandle;
8537                 if (pb->set_method)
8538                         properties [i].set = pb->set_method->mhandle;
8539
8540                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
8541                 if (pb->def_value) {
8542                         guint32 len, idx;
8543                         const char *p, *p2;
8544                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
8545                         if (!klass->ext->prop_def_values)
8546                                 klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
8547                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
8548                         idx = encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
8549                         /* Copy the data from the blob since it might get realloc-ed */
8550                         p = assembly->blob.data + idx;
8551                         len = mono_metadata_decode_blob_size (p, &p2);
8552                         len += p2 - p;
8553                         klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
8554                         memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
8555                 }
8556         }
8557 }
8558
8559 static MonoReflectionEvent *
8560 reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb, MonoError *error)
8561 {
8562         mono_error_init (error);
8563
8564         MonoEvent *event = g_new0 (MonoEvent, 1);
8565         MonoClass *klass;
8566
8567         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
8568         if (!is_ok (error)) {
8569                 g_free (event);
8570                 return NULL;
8571         }
8572         klass = mono_class_from_mono_type (type);
8573
8574         event->parent = klass;
8575         event->attrs = eb->attrs;
8576         event->name = mono_string_to_utf8_checked (eb->name, error);
8577         if (!is_ok (error)) {
8578                 g_free (event);
8579                 return NULL;
8580         }
8581         if (eb->add_method)
8582                 event->add = eb->add_method->mhandle;
8583         if (eb->remove_method)
8584                 event->remove = eb->remove_method->mhandle;
8585         if (eb->raise_method)
8586                 event->raise = eb->raise_method->mhandle;
8587
8588 #ifndef MONO_SMALL_CONFIG
8589         if (eb->other_methods) {
8590                 int j;
8591                 event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
8592                 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
8593                         MonoReflectionMethodBuilder *mb = 
8594                                 mono_array_get (eb->other_methods,
8595                                                 MonoReflectionMethodBuilder*, j);
8596                         event->other [j] = mb->mhandle;
8597                 }
8598         }
8599 #endif
8600
8601         MonoReflectionEvent *ev_obj = mono_event_get_object_checked (mono_object_domain (tb), klass, event, error);
8602         if (!is_ok (error)) {
8603 #ifndef MONO_SMALL_CONFIG
8604                 g_free (event->other);
8605 #endif
8606                 g_free (event);
8607                 return NULL;
8608         }
8609         return ev_obj;
8610 }
8611
8612 MonoReflectionEvent *
8613 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
8614 {
8615         MonoError error;
8616         MonoReflectionEvent *result = reflection_event_builder_get_event_info (tb, eb, &error);
8617         mono_error_set_pending_exception (&error);
8618         return result;
8619 }
8620
8621 static void
8622 typebuilder_setup_events (MonoClass *klass, MonoError *error)
8623 {
8624         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
8625         MonoReflectionEventBuilder *eb;
8626         MonoImage *image = klass->image;
8627         MonoEvent *events;
8628         int i;
8629
8630         mono_error_init (error);
8631
8632         if (!klass->ext)
8633                 klass->ext = image_g_new0 (image, MonoClassExt, 1);
8634
8635         klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
8636         klass->ext->event.first = 0;
8637
8638         events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
8639         klass->ext->events = events;
8640         for (i = 0; i < klass->ext->event.count; ++i) {
8641                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
8642                 events [i].parent = klass;
8643                 events [i].attrs = eb->attrs;
8644                 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
8645                 if (!mono_error_ok (error))
8646                         return;
8647                 if (eb->add_method)
8648                         events [i].add = eb->add_method->mhandle;
8649                 if (eb->remove_method)
8650                         events [i].remove = eb->remove_method->mhandle;
8651                 if (eb->raise_method)
8652                         events [i].raise = eb->raise_method->mhandle;
8653
8654 #ifndef MONO_SMALL_CONFIG
8655                 if (eb->other_methods) {
8656                         int j;
8657                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
8658                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
8659                                 MonoReflectionMethodBuilder *mb = 
8660                                         mono_array_get (eb->other_methods,
8661                                                                         MonoReflectionMethodBuilder*, j);
8662                                 events [i].other [j] = mb->mhandle;
8663                         }
8664                 }
8665 #endif
8666                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
8667         }
8668 }
8669
8670 struct remove_instantiations_user_data
8671 {
8672         MonoClass *klass;
8673         MonoError *error;
8674 };
8675
8676 static gboolean
8677 remove_instantiations_of_and_ensure_contents (gpointer key,
8678                                                   gpointer value,
8679                                                   gpointer user_data)
8680 {
8681         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
8682         MonoType *type = (MonoType*)key;
8683         MonoClass *klass = data->klass;
8684         gboolean already_failed = !is_ok (data->error);
8685         MonoError lerror;
8686         MonoError *error = already_failed ? &lerror : data->error;
8687
8688         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
8689                 MonoClass *inst_klass = mono_class_from_mono_type (type);
8690                 //Ensure it's safe to use it.
8691                 if (!fix_partial_generic_class (inst_klass, error)) {
8692                         mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
8693                         // Marked the class with failure, but since some other instantiation already failed,
8694                         // just report that one, and swallow the error from this one.
8695                         if (already_failed)
8696                                 mono_error_cleanup (error);
8697                 }
8698                 return TRUE;
8699         } else
8700                 return FALSE;
8701 }
8702
8703 static void
8704 check_array_for_usertypes (MonoArray *arr, MonoError *error)
8705 {
8706         mono_error_init (error);
8707         int i;
8708
8709         if (!arr)
8710                 return;
8711
8712         for (i = 0; i < mono_array_length (arr); ++i) {
8713                 RESOLVE_ARRAY_TYPE_ELEMENT (arr, i, error);
8714                 if (!mono_error_ok (error))
8715                         break;
8716         }
8717 }
8718
8719 MonoReflectionType*
8720 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
8721 {
8722         MonoError error;
8723         MonoClass *klass;
8724         MonoDomain* domain;
8725         MonoReflectionType* res;
8726         int i, j;
8727
8728         mono_error_init (&error);
8729
8730         domain = mono_object_domain (tb);
8731         klass = mono_class_from_mono_type (tb->type.type);
8732
8733         /*
8734          * Check for user defined Type subclasses.
8735          */
8736         RESOLVE_TYPE (tb->parent, &error);
8737         if (!is_ok (&error))
8738                 goto failure_unlocked;
8739         check_array_for_usertypes (tb->interfaces, &error);
8740         if (!is_ok (&error))
8741                 goto failure_unlocked;
8742         if (tb->fields) {
8743                 for (i = 0; i < mono_array_length (tb->fields); ++i) {
8744                         MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
8745                         if (fb) {
8746                                 RESOLVE_TYPE (fb->type, &error);
8747                                 if (!is_ok (&error))
8748                                         goto failure_unlocked;
8749                                 check_array_for_usertypes (fb->modreq, &error);
8750                                 if (!is_ok (&error))
8751                                         goto failure_unlocked;
8752                                 check_array_for_usertypes (fb->modopt, &error);
8753                                 if (!is_ok (&error))
8754                                         goto failure_unlocked;
8755                                 if (fb->marshal_info && fb->marshal_info->marshaltyperef) {
8756                                         RESOLVE_TYPE (fb->marshal_info->marshaltyperef, &error);
8757                                         if (!is_ok (&error))
8758                                                 goto failure_unlocked;
8759                                 }
8760                         }
8761                 }
8762         }
8763         if (tb->methods) {
8764                 for (i = 0; i < mono_array_length (tb->methods); ++i) {
8765                         MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)mono_array_get (tb->methods, gpointer, i);
8766                         if (mb) {
8767                                 RESOLVE_TYPE (mb->rtype, &error);
8768                                 if (!is_ok (&error))
8769                                         goto failure_unlocked;
8770                                 check_array_for_usertypes (mb->return_modreq, &error);
8771                                 if (!is_ok (&error))
8772                                         goto failure_unlocked;
8773                                 check_array_for_usertypes (mb->return_modopt, &error);
8774                                 if (!is_ok (&error))
8775                                         goto failure_unlocked;
8776                                 check_array_for_usertypes (mb->parameters, &error);
8777                                 if (!is_ok (&error))
8778                                         goto failure_unlocked;
8779                                 if (mb->param_modreq)
8780                                         for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
8781                                                 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
8782                                                 if (!is_ok (&error))
8783                                                         goto failure_unlocked;
8784                                         }
8785                                 if (mb->param_modopt)
8786                                         for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
8787                                                 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
8788                                                 if (!is_ok (&error))
8789                                                         goto failure_unlocked;
8790                                         }
8791                         }
8792                 }
8793         }
8794         if (tb->ctors) {
8795                 for (i = 0; i < mono_array_length (tb->ctors); ++i) {
8796                         MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)mono_array_get (tb->ctors, gpointer, i);
8797                         if (mb) {
8798                                 check_array_for_usertypes (mb->parameters, &error);
8799                                 if (!is_ok (&error))
8800                                         goto failure_unlocked;
8801                                 if (mb->param_modreq)
8802                                         for (j = 0; j < mono_array_length (mb->param_modreq); ++j) {
8803                                                 check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j), &error);
8804                                                 if (!is_ok (&error))
8805                                                         goto failure_unlocked;
8806                                         }
8807                                 if (mb->param_modopt)
8808                                         for (j = 0; j < mono_array_length (mb->param_modopt); ++j) {
8809                                                 check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j), &error);
8810                                                 if (!is_ok (&error))
8811                                                         goto failure_unlocked;
8812                                         }
8813                         }
8814                 }
8815         }
8816
8817         mono_save_custom_attrs (klass->image, klass, tb->cattrs);
8818
8819         /* 
8820          * we need to lock the domain because the lock will be taken inside
8821          * So, we need to keep the locking order correct.
8822          */
8823         mono_loader_lock ();
8824         mono_domain_lock (domain);
8825         if (klass->wastypebuilder) {
8826                 mono_domain_unlock (domain);
8827                 mono_loader_unlock ();
8828
8829                 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
8830                 mono_error_set_pending_exception (&error);
8831
8832                 return res;
8833         }
8834         /*
8835          * Fields to set in klass:
8836          * the various flags: delegate/unicode/contextbound etc.
8837          */
8838         klass->flags = tb->attrs;
8839         klass->has_cctor = 1;
8840
8841         mono_class_setup_parent (klass, klass->parent);
8842         /* fool mono_class_setup_supertypes */
8843         klass->supertypes = NULL;
8844         mono_class_setup_supertypes (klass);
8845         mono_class_setup_mono_type (klass);
8846
8847 #if 0
8848         if (!((MonoDynamicImage*)klass->image)->run) {
8849                 if (klass->generic_container) {
8850                         /* FIXME: The code below can't handle generic classes */
8851                         klass->wastypebuilder = TRUE;
8852                         mono_loader_unlock ();
8853                         mono_domain_unlock (domain);
8854
8855                         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
8856                         mono_error_set_pending_exception (&error);
8857
8858                         return res;
8859                 }
8860         }
8861 #endif
8862
8863         /* enums are done right away */
8864         if (!klass->enumtype)
8865                 if (!ensure_runtime_vtable (klass, &error))
8866                         goto failure;
8867
8868         if (tb->subtypes) {
8869                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
8870                         MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
8871                         mono_class_alloc_ext (klass);
8872                         MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
8873                         if (!is_ok (&error)) goto failure;
8874                         klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
8875                 }
8876         }
8877
8878         klass->nested_classes_inited = TRUE;
8879
8880         /* fields and object layout */
8881         if (klass->parent) {
8882                 if (!klass->parent->size_inited)
8883                         mono_class_init (klass->parent);
8884                 klass->instance_size = klass->parent->instance_size;
8885                 klass->sizes.class_size = 0;
8886                 klass->min_align = klass->parent->min_align;
8887                 /* if the type has no fields we won't call the field_setup
8888                  * routine which sets up klass->has_references.
8889                  */
8890                 klass->has_references |= klass->parent->has_references;
8891         } else {
8892                 klass->instance_size = sizeof (MonoObject);
8893                 klass->min_align = 1;
8894         }
8895
8896         /* FIXME: handle packing_size and instance_size */
8897         typebuilder_setup_fields (klass, &error);
8898         if (!mono_error_ok (&error))
8899                 goto failure;
8900         typebuilder_setup_properties (klass, &error);
8901         if (!mono_error_ok (&error))
8902                 goto failure;
8903
8904         typebuilder_setup_events (klass, &error);
8905         if (!mono_error_ok (&error))
8906                 goto failure;
8907
8908         klass->wastypebuilder = TRUE;
8909
8910         /* 
8911          * If we are a generic TypeBuilder, there might be instantiations in the type cache
8912          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
8913          * we want to return normal System.MonoType objects, so clear these out from the cache.
8914          *
8915          * Together with this we must ensure the contents of all instances to match the created type.
8916          */
8917         if (domain->type_hash && klass->generic_container) {
8918                 struct remove_instantiations_user_data data;
8919                 data.klass = klass;
8920                 data.error = &error;
8921                 mono_error_assert_ok (&error);
8922                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
8923                 if (!is_ok (&error))
8924                         goto failure;
8925         }
8926
8927         mono_domain_unlock (domain);
8928         mono_loader_unlock ();
8929
8930         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
8931                 mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
8932                 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
8933                 goto failure_unlocked;
8934         }
8935
8936         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
8937         if (!is_ok (&error))
8938                 goto failure_unlocked;
8939
8940         g_assert (res != (MonoReflectionType*)tb);
8941
8942         return res;
8943
8944 failure:
8945         mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
8946         klass->wastypebuilder = TRUE;
8947         mono_domain_unlock (domain);
8948         mono_loader_unlock ();
8949 failure_unlocked:
8950         mono_error_set_pending_exception (&error);
8951         return NULL;
8952 }
8953
8954 static gboolean
8955 reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
8956 {
8957         MonoGenericParamFull *param;
8958         MonoImage *image;
8959         MonoClass *pklass;
8960
8961         mono_error_init (error);
8962
8963         image = &gparam->tbuilder->module->dynamic_image->image;
8964
8965         param = mono_image_new0 (image, MonoGenericParamFull, 1);
8966
8967         param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
8968         mono_error_assert_ok (error);
8969         param->param.num = gparam->index;
8970
8971         if (gparam->mbuilder) {
8972                 if (!gparam->mbuilder->generic_container) {
8973                         MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
8974                         return_val_if_nok (error, FALSE);
8975
8976                         MonoClass *klass = mono_class_from_mono_type (tb);
8977                         gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
8978                         gparam->mbuilder->generic_container->is_method = TRUE;
8979                         /* 
8980                          * Cannot set owner.method, since the MonoMethod is not created yet.
8981                          * Set the image field instead, so type_in_image () works.
8982                          */
8983                         gparam->mbuilder->generic_container->is_anonymous = TRUE;
8984                         gparam->mbuilder->generic_container->owner.image = klass->image;
8985                 }
8986                 param->param.owner = gparam->mbuilder->generic_container;
8987         } else if (gparam->tbuilder) {
8988                 if (!gparam->tbuilder->generic_container) {
8989                         MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
8990                         return_val_if_nok (error, FALSE);
8991                         MonoClass *klass = mono_class_from_mono_type (tb);
8992                         gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
8993                         gparam->tbuilder->generic_container->owner.klass = klass;
8994                 }
8995                 param->param.owner = gparam->tbuilder->generic_container;
8996         }
8997
8998         pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
8999
9000         gparam->type.type = &pklass->byval_arg;
9001
9002         mono_class_set_ref_info (pklass, gparam);
9003         mono_image_append_class_to_reflection_info_set (pklass);
9004
9005         return TRUE;
9006 }
9007
9008 void
9009 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
9010 {
9011         MonoError error;
9012         (void) reflection_initialize_generic_parameter (gparam, &error);
9013         mono_error_set_pending_exception (&error);
9014 }
9015
9016
9017 static MonoArray *
9018 reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig, MonoError *error)
9019 {
9020         MonoReflectionModuleBuilder *module = sig->module;
9021         MonoDynamicImage *assembly = module != NULL ? module->dynamic_image : NULL;
9022         guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
9023         guint32 buflen, i;
9024         MonoArray *result;
9025         SigBuffer buf;
9026
9027         mono_error_init (error);
9028
9029         check_array_for_usertypes (sig->arguments, error);
9030         return_val_if_nok (error, NULL);
9031
9032         sigbuffer_init (&buf, 32);
9033
9034         sigbuffer_add_value (&buf, 0x07);
9035         sigbuffer_add_value (&buf, na);
9036         if (assembly != NULL){
9037                 for (i = 0; i < na; ++i) {
9038                         MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
9039                         encode_reflection_type (assembly, type, &buf, error);
9040                         if (!is_ok (error)) goto fail;
9041                 }
9042         }
9043
9044         buflen = buf.p - buf.buf;
9045         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
9046         if (!is_ok (error)) goto fail;
9047         memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
9048         sigbuffer_free (&buf);
9049         return result;
9050 fail:
9051         sigbuffer_free (&buf);
9052         return NULL;
9053 }
9054
9055 MonoArray *
9056 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
9057 {
9058         MonoError error;
9059         MonoArray *result = reflection_sighelper_get_signature_local (sig, &error);
9060         mono_error_set_pending_exception (&error);
9061         return result;
9062 }
9063
9064 static MonoArray *
9065 reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig, MonoError *error)
9066 {
9067         MonoDynamicImage *assembly = sig->module->dynamic_image;
9068         guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
9069         guint32 buflen, i;
9070         MonoArray *result;
9071         SigBuffer buf;
9072
9073         mono_error_init (error);
9074
9075         check_array_for_usertypes (sig->arguments, error);
9076         return_val_if_nok (error, NULL);
9077
9078         sigbuffer_init (&buf, 32);
9079
9080         sigbuffer_add_value (&buf, 0x06);
9081         for (i = 0; i < na; ++i) {
9082                 MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
9083                 encode_reflection_type (assembly, type, &buf, error);
9084                 if (!is_ok (error))
9085                         goto fail;
9086         }
9087
9088         buflen = buf.p - buf.buf;
9089         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
9090         if (!is_ok (error)) goto fail;
9091         memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
9092         sigbuffer_free (&buf);
9093
9094         return result;
9095 fail:
9096         sigbuffer_free (&buf);
9097         return NULL;
9098 }
9099
9100 MonoArray *
9101 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
9102 {
9103         MonoError error;
9104         MonoArray *result = reflection_sighelper_get_signature_field (sig, &error);
9105         mono_error_set_pending_exception (&error);
9106         return result;
9107 }
9108
9109 typedef struct {
9110         MonoMethod *handle;
9111         MonoDomain *domain;
9112 } DynamicMethodReleaseData;
9113
9114 /*
9115  * The runtime automatically clean up those after finalization.
9116 */      
9117 static MonoReferenceQueue *dynamic_method_queue;
9118
9119 static void
9120 free_dynamic_method (void *dynamic_method)
9121 {
9122         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
9123         MonoDomain *domain = data->domain;
9124         MonoMethod *method = data->handle;
9125         guint32 dis_link;
9126
9127         mono_domain_lock (domain);
9128         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
9129         g_hash_table_remove (domain->method_to_dyn_method, method);
9130         mono_domain_unlock (domain);
9131         g_assert (dis_link);
9132         mono_gchandle_free (dis_link);
9133
9134         mono_runtime_free_method (domain, method);
9135         g_free (data);
9136 }
9137
9138 static gboolean
9139 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
9140 {
9141         MonoReferenceQueue *queue;
9142         MonoMethod *handle;
9143         DynamicMethodReleaseData *release_data;
9144         ReflectionMethodBuilder rmb;
9145         MonoMethodSignature *sig;
9146         MonoClass *klass;
9147         MonoDomain *domain;
9148         GSList *l;
9149         int i;
9150
9151         mono_error_init (error);
9152
9153         if (mono_runtime_is_shutting_down ()) {
9154                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
9155                 return FALSE;
9156         }
9157
9158         if (!(queue = dynamic_method_queue)) {
9159                 mono_loader_lock ();
9160                 if (!(queue = dynamic_method_queue))
9161                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
9162                 mono_loader_unlock ();
9163         }
9164
9165         sig = dynamic_method_to_signature (mb, error);
9166         return_val_if_nok (error, FALSE);
9167
9168         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
9169
9170         /*
9171          * Resolve references.
9172          */
9173         /* 
9174          * Every second entry in the refs array is reserved for storing handle_class,
9175          * which is needed by the ldtoken implementation in the JIT.
9176          */
9177         rmb.nrefs = mb->nrefs;
9178         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
9179         for (i = 0; i < mb->nrefs; i += 2) {
9180                 MonoClass *handle_class;
9181                 gpointer ref;
9182                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
9183
9184                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
9185                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
9186                         /*
9187                          * The referenced DynamicMethod should already be created by the managed
9188                          * code, except in the case of circular references. In that case, we store
9189                          * method in the refs array, and fix it up later when the referenced 
9190                          * DynamicMethod is created.
9191                          */
9192                         if (method->mhandle) {
9193                                 ref = method->mhandle;
9194                         } else {
9195                                 /* FIXME: GC object stored in unmanaged memory */
9196                                 ref = method;
9197
9198                                 /* FIXME: GC object stored in unmanaged memory */
9199                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
9200                         }
9201                         handle_class = mono_defaults.methodhandle_class;
9202                 } else {
9203                         MonoException *ex = NULL;
9204                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
9205                         if (!is_ok  (error)) {
9206                                 g_free (rmb.refs);
9207                                 return FALSE;
9208                         }
9209                         if (!ref)
9210                                 ex = mono_get_exception_type_load (NULL, NULL);
9211                         else if (mono_security_core_clr_enabled ())
9212                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
9213
9214                         if (ex) {
9215                                 g_free (rmb.refs);
9216                                 mono_error_set_exception_instance (error, ex);
9217                                 return FALSE;
9218                         }
9219                 }
9220
9221                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
9222                 rmb.refs [i + 1] = handle_class;
9223         }               
9224
9225         if (mb->owner) {
9226                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
9227                 if (!is_ok (error)) {
9228                         g_free (rmb.refs);
9229                         return FALSE;
9230                 }
9231                 klass = mono_class_from_mono_type (owner_type);
9232         } else {
9233                 klass = mono_defaults.object_class;
9234         }
9235
9236         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
9237         g_free (rmb.refs);
9238         return_val_if_nok (error, FALSE);
9239
9240         release_data = g_new (DynamicMethodReleaseData, 1);
9241         release_data->handle = handle;
9242         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
9243         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
9244                 g_free (release_data);
9245
9246         /* Fix up refs entries pointing at us */
9247         for (l = mb->referenced_by; l; l = l->next) {
9248                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
9249                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
9250                 gpointer *data;
9251                 
9252                 g_assert (method->mhandle);
9253
9254                 data = (gpointer*)wrapper->method_data;
9255                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
9256                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
9257                                 data [i + 1] = mb->mhandle;
9258                 }
9259         }
9260         g_slist_free (mb->referenced_by);
9261
9262         /* ilgen is no longer needed */
9263         mb->ilgen = NULL;
9264
9265         domain = mono_domain_get ();
9266         mono_domain_lock (domain);
9267         if (!domain->method_to_dyn_method)
9268                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
9269         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
9270         mono_domain_unlock (domain);
9271
9272         return TRUE;
9273 }
9274
9275 void
9276 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
9277 {
9278         MonoError error;
9279         (void) reflection_create_dynamic_method (mb, &error);
9280         mono_error_set_pending_exception (&error);
9281 }
9282
9283 #endif /* DISABLE_REFLECTION_EMIT */
9284
9285 MonoMethodSignature *
9286 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
9287 {
9288         MonoMethodSignature *sig;
9289         g_assert (image_is_dynamic (image));
9290
9291         mono_error_init (error);
9292
9293         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
9294         if (sig)
9295                 return sig;
9296
9297         return mono_method_signature_checked (method, error);
9298 }
9299
9300 #ifndef DISABLE_REFLECTION_EMIT
9301
9302 /*
9303  * ensure_complete_type:
9304  *
9305  *   Ensure that KLASS is completed if it is a dynamic type, or references
9306  * dynamic types.
9307  */
9308 static void
9309 ensure_complete_type (MonoClass *klass, MonoError *error)
9310 {
9311         mono_error_init (error);
9312
9313         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
9314                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
9315
9316                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
9317                 return_if_nok (error);
9318
9319                 // Asserting here could break a lot of code
9320                 //g_assert (klass->wastypebuilder);
9321         }
9322
9323         if (klass->generic_class) {
9324                 MonoGenericInst *inst = klass->generic_class->context.class_inst;
9325                 int i;
9326
9327                 for (i = 0; i < inst->type_argc; ++i) {
9328                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
9329                         return_if_nok (error);
9330                 }
9331         }
9332 }
9333
9334 gpointer
9335 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
9336 {
9337         gpointer result = NULL;
9338
9339         mono_error_init (error);
9340
9341         if (strcmp (obj->vtable->klass->name, "String") == 0) {
9342                 result = mono_string_intern_checked ((MonoString*)obj, error);
9343                 return_val_if_nok (error, NULL);
9344                 *handle_class = mono_defaults.string_class;
9345                 g_assert (result);
9346         } else if (strcmp (obj->vtable->klass->name, "RuntimeType") == 0) {
9347                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
9348                 return_val_if_nok (error, NULL);
9349                 MonoClass *mc = mono_class_from_mono_type (type);
9350                 if (!mono_class_init (mc)) {
9351                         mono_error_set_for_class_failure (error, mc);
9352                         return NULL;
9353                 }
9354
9355                 if (context) {
9356                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
9357                         return_val_if_nok (error, NULL);
9358
9359                         result = mono_class_from_mono_type (inflated);
9360                         mono_metadata_free_type (inflated);
9361                 } else {
9362                         result = mono_class_from_mono_type (type);
9363                 }
9364                 *handle_class = mono_defaults.typehandle_class;
9365                 g_assert (result);
9366         } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
9367                    strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
9368                    strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
9369                    strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
9370                 result = ((MonoReflectionMethod*)obj)->method;
9371                 if (context) {
9372                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
9373                         mono_error_assert_ok (error);
9374                 }
9375                 *handle_class = mono_defaults.methodhandle_class;
9376                 g_assert (result);
9377         } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
9378                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
9379                 result = mb->mhandle;
9380                 if (!result) {
9381                         /* Type is not yet created */
9382                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
9383
9384                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
9385                         return_val_if_nok (error, NULL);
9386
9387                         /*
9388                          * Hopefully this has been filled in by calling CreateType() on the
9389                          * TypeBuilder.
9390                          */
9391                         /*
9392                          * TODO: This won't work if the application finishes another 
9393                          * TypeBuilder instance instead of this one.
9394                          */
9395                         result = mb->mhandle;
9396                 }
9397                 if (context) {
9398                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
9399                         mono_error_assert_ok (error);
9400                 }
9401                 *handle_class = mono_defaults.methodhandle_class;
9402         } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
9403                 MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
9404
9405                 result = cb->mhandle;
9406                 if (!result) {
9407                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)cb->type;
9408
9409                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
9410                         return_val_if_nok (error, NULL);
9411                         result = cb->mhandle;
9412                 }
9413                 if (context) {
9414                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
9415                         mono_error_assert_ok (error);
9416                 }
9417                 *handle_class = mono_defaults.methodhandle_class;
9418         } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
9419                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
9420
9421                 ensure_complete_type (field->parent, error);
9422                 return_val_if_nok (error, NULL);
9423
9424                 if (context) {
9425                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
9426                         return_val_if_nok (error, NULL);
9427
9428                         MonoClass *klass = mono_class_from_mono_type (inflated);
9429                         MonoClassField *inflated_field;
9430                         gpointer iter = NULL;
9431                         mono_metadata_free_type (inflated);
9432                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
9433                                 if (!strcmp (field->name, inflated_field->name))
9434                                         break;
9435                         }
9436                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
9437                         result = inflated_field;
9438                 } else {
9439                         result = field;
9440                 }
9441                 *handle_class = mono_defaults.fieldhandle_class;
9442                 g_assert (result);
9443         } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
9444                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
9445                 result = fb->handle;
9446
9447                 if (!result) {
9448                         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)fb->typeb;
9449
9450                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
9451                         return_val_if_nok (error, NULL);
9452                         result = fb->handle;
9453                 }
9454
9455                 if (fb->handle && fb->handle->parent->generic_container) {
9456                         MonoClass *klass = fb->handle->parent;
9457                         MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, error);
9458                         return_val_if_nok (error, NULL);
9459
9460                         MonoClass *inflated = mono_class_from_mono_type (type);
9461
9462                         result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
9463                         g_assert (result);
9464                         mono_metadata_free_type (type);
9465                 }
9466                 *handle_class = mono_defaults.fieldhandle_class;
9467         } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
9468                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
9469                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
9470                 return_val_if_nok (error, NULL);
9471                 MonoClass *klass;
9472
9473                 klass = type->data.klass;
9474                 if (klass->wastypebuilder) {
9475                         /* Already created */
9476                         result = klass;
9477                 }
9478                 else {
9479                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
9480                         return_val_if_nok (error, NULL);
9481                         result = type->data.klass;
9482                         g_assert (result);
9483                 }
9484                 *handle_class = mono_defaults.typehandle_class;
9485         } else if (strcmp (obj->vtable->klass->name, "SignatureHelper") == 0) {
9486                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
9487                 MonoMethodSignature *sig;
9488                 int nargs, i;
9489
9490                 if (helper->arguments)
9491                         nargs = mono_array_length (helper->arguments);
9492                 else
9493                         nargs = 0;
9494
9495                 sig = mono_metadata_signature_alloc (image, nargs);
9496                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
9497                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
9498
9499                 if (helper->unmanaged_call_conv) { /* unmanaged */
9500                         sig->call_convention = helper->unmanaged_call_conv - 1;
9501                         sig->pinvoke = TRUE;
9502                 } else if (helper->call_conv & 0x02) {
9503                         sig->call_convention = MONO_CALL_VARARG;
9504                 } else {
9505                         sig->call_convention = MONO_CALL_DEFAULT;
9506                 }
9507
9508                 sig->param_count = nargs;
9509                 /* TODO: Copy type ? */
9510                 sig->ret = helper->return_type->type;
9511                 for (i = 0; i < nargs; ++i) {
9512                         sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
9513                         if (!is_ok (error)) {
9514                                 image_g_free (image, sig);
9515                                 return NULL;
9516                         }
9517                 }
9518
9519                 result = sig;
9520                 *handle_class = NULL;
9521         } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
9522                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
9523                 /* Already created by the managed code */
9524                 g_assert (method->mhandle);
9525                 result = method->mhandle;
9526                 *handle_class = mono_defaults.methodhandle_class;
9527         } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
9528                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
9529                 return_val_if_nok (error, NULL);
9530                 type = mono_class_inflate_generic_type_checked (type, context, error);
9531                 return_val_if_nok (error, NULL);
9532
9533                 result = mono_class_from_mono_type (type);
9534                 *handle_class = mono_defaults.typehandle_class;
9535                 g_assert (result);
9536                 mono_metadata_free_type (type);
9537         } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
9538                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
9539                 return_val_if_nok (error, NULL);
9540                 type = mono_class_inflate_generic_type_checked (type, context, error);
9541                 return_val_if_nok (error, NULL);
9542
9543                 result = mono_class_from_mono_type (type);
9544                 *handle_class = mono_defaults.typehandle_class;
9545                 g_assert (result);
9546                 mono_metadata_free_type (type);
9547         } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
9548                 MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
9549                 MonoClass *inflated;
9550                 MonoType *type;
9551                 MonoClassField *field;
9552
9553                 if (is_sre_field_builder (mono_object_class (f->fb)))
9554                         field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
9555                 else if (is_sr_mono_field (mono_object_class (f->fb)))
9556                         field = ((MonoReflectionField*)f->fb)->field;
9557                 else
9558                         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)));
9559
9560                 MonoType *finst = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst, error);
9561                 return_val_if_nok (error, NULL);
9562                 type = mono_class_inflate_generic_type_checked (finst, context, error);
9563                 return_val_if_nok (error, NULL);
9564
9565                 inflated = mono_class_from_mono_type (type);
9566
9567                 result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
9568                 ensure_complete_type (field->parent, error);
9569                 if (!is_ok (error)) {
9570                         mono_metadata_free_type (type);
9571                         return NULL;
9572                 }
9573
9574                 g_assert (result);
9575                 mono_metadata_free_type (type);
9576                 *handle_class = mono_defaults.fieldhandle_class;
9577         } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
9578                 MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
9579                 MonoType *cinst = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst, error);
9580                 return_val_if_nok (error, NULL);
9581                 MonoType *type = mono_class_inflate_generic_type_checked (cinst, context, error);
9582                 return_val_if_nok (error, NULL);
9583
9584                 MonoClass *inflated_klass = mono_class_from_mono_type (type);
9585                 MonoMethod *method;
9586
9587                 if (mono_is_sre_ctor_builder (mono_object_class (c->cb)))
9588                         method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
9589                 else if (mono_is_sr_mono_cmethod (mono_object_class (c->cb)))
9590                         method = ((MonoReflectionMethod *)c->cb)->method;
9591                 else
9592                         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)));
9593
9594                 result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
9595                 *handle_class = mono_defaults.methodhandle_class;
9596                 mono_metadata_free_type (type);
9597         } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
9598                 MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
9599                 if (m->method_args) {
9600                         result = mono_reflection_method_on_tb_inst_get_handle (m, error);
9601                         return_val_if_nok (error, NULL);
9602                         if (context) {
9603                                 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
9604                                 mono_error_assert_ok (error);
9605                         }
9606                 } else {
9607                         MonoType *minst = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst, error);
9608                         return_val_if_nok (error, NULL);
9609                         MonoType *type = mono_class_inflate_generic_type_checked (minst, context, error);
9610                         return_val_if_nok (error, NULL);
9611
9612                         MonoClass *inflated_klass = mono_class_from_mono_type (type);
9613                         MonoMethod *method;
9614
9615                         if (is_sre_method_builder (mono_object_class (m->mb)))
9616                                 method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
9617                         else if (is_sr_mono_method (mono_object_class (m->mb)))
9618                                 method = ((MonoReflectionMethod *)m->mb)->method;
9619                         else
9620                                 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)));
9621
9622                         result = inflate_mono_method (inflated_klass, method, (MonoObject*)m->mb);
9623                         mono_metadata_free_type (type);
9624                 }
9625                 *handle_class = mono_defaults.methodhandle_class;
9626         } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
9627                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
9628                 MonoType *mtype;
9629                 MonoClass *klass;
9630                 MonoMethod *method;
9631                 gpointer iter;
9632                 char *name;
9633
9634                 mtype = mono_reflection_type_get_handle (m->parent, error);
9635                 return_val_if_nok (error, NULL);
9636                 klass = mono_class_from_mono_type (mtype);
9637
9638                 /* Find the method */
9639
9640                 name = mono_string_to_utf8_checked (m->name, error);
9641                 return_val_if_nok (error, NULL);
9642                 iter = NULL;
9643                 while ((method = mono_class_get_methods (klass, &iter))) {
9644                         if (!strcmp (method->name, name))
9645                                 break;
9646                 }
9647                 g_free (name);
9648
9649                 // FIXME:
9650                 g_assert (method);
9651                 // FIXME: Check parameters/return value etc. match
9652
9653                 result = method;
9654                 *handle_class = mono_defaults.methodhandle_class;
9655         } else if (is_sre_array (mono_object_get_class(obj)) ||
9656                                 is_sre_byref (mono_object_get_class(obj)) ||
9657                                 is_sre_pointer (mono_object_get_class(obj))) {
9658                 MonoReflectionType *ref_type = (MonoReflectionType *)obj;
9659                 MonoType *type = mono_reflection_type_get_handle (ref_type, error);
9660                 return_val_if_nok (error, NULL);
9661
9662                 if (context) {
9663                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
9664                         return_val_if_nok (error, NULL);
9665
9666                         result = mono_class_from_mono_type (inflated);
9667                         mono_metadata_free_type (inflated);
9668                 } else {
9669                         result = mono_class_from_mono_type (type);
9670                 }
9671                 *handle_class = mono_defaults.typehandle_class;
9672         } else {
9673                 g_print ("%s\n", obj->vtable->klass->name);
9674                 g_assert_not_reached ();
9675         }
9676         return result;
9677 }
9678
9679 #else /* DISABLE_REFLECTION_EMIT */
9680
9681 MonoArray*
9682 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
9683 {
9684         g_assert_not_reached ();
9685         return NULL;
9686 }
9687
9688 void
9689 ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
9690 {
9691         g_assert_not_reached ();
9692 }
9693
9694 void
9695 ves_icall_TypeBuilder_setup_generic_class (MonoReflectionTypeBuilder *tb)
9696 {
9697         g_assert_not_reached ();
9698 }
9699
9700 gboolean
9701 mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
9702 {
9703         g_assert_not_reached ();
9704         return FALSE;
9705 }
9706
9707 void
9708 ves_icall_TypeBuilder_create_internal_class (MonoReflectionTypeBuilder *tb)
9709 {
9710         g_assert_not_reached ();
9711 }
9712
9713 static void
9714 mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
9715 {
9716         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
9717 }
9718
9719 static void
9720 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
9721 {
9722         g_assert_not_reached ();
9723 }
9724
9725 MonoReflectionModule *
9726 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName, MonoError *error)
9727 {
9728         g_assert_not_reached ();
9729         return NULL;
9730 }
9731
9732 guint32
9733 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
9734 {
9735         g_assert_not_reached ();
9736         return 0;
9737 }
9738
9739 guint32
9740 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
9741 {
9742         g_assert_not_reached ();
9743         return 0;
9744 }
9745
9746 guint32
9747 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
9748                          gboolean create_open_instance, gboolean register_token, MonoError *error)
9749 {
9750         g_assert_not_reached ();
9751         return 0;
9752 }
9753
9754 void
9755 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
9756 {
9757         g_assert_not_reached ();
9758 }
9759
9760 void
9761 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
9762 {
9763         mono_error_init (error);
9764         *overrides = NULL;
9765         *num_overrides = 0;
9766 }
9767
9768 MonoReflectionEvent *
9769 ves_icall_TypeBuilder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
9770 {
9771         g_assert_not_reached ();
9772         return NULL;
9773 }
9774
9775 MonoReflectionType*
9776 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
9777 {
9778         g_assert_not_reached ();
9779         return NULL;
9780 }
9781
9782 void
9783 ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
9784 {
9785         g_assert_not_reached ();
9786 }
9787
9788 MonoArray *
9789 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
9790 {
9791         g_assert_not_reached ();
9792         return NULL;
9793 }
9794
9795 MonoArray *
9796 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
9797 {
9798         g_assert_not_reached ();
9799         return NULL;
9800 }
9801
9802 void 
9803 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
9804 {
9805 }
9806
9807 MonoType*
9808 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
9809 {
9810         mono_error_init (error);
9811         if (!ref)
9812                 return NULL;
9813         return ref->type;
9814 }
9815
9816 void
9817 mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
9818 {
9819         g_assert_not_reached ();
9820 }
9821
9822 #endif /* DISABLE_REFLECTION_EMIT */
9823
9824 #ifndef DISABLE_REFLECTION_EMIT
9825 MonoMethod*
9826 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
9827 {
9828         MonoType *tb;
9829         MonoClass *klass;
9830
9831         tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
9832         return_val_if_nok (error, NULL);
9833         klass = mono_class_from_mono_type (tb);
9834
9835         return methodbuilder_to_mono_method (klass, mb, error);
9836 }
9837 #else /* DISABLE_REFLECTION_EMIT */
9838 MonoMethod*
9839 mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
9840 {
9841         g_assert_not_reached ();
9842         return NULL;
9843 }
9844 #endif /* DISABLE_REFLECTION_EMIT */
9845
9846 gint32
9847 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
9848 {
9849         MONO_CHECK_ARG_NULL (obj, 0);
9850
9851         MonoError error;
9852         gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
9853         mono_error_set_pending_exception (&error);
9854         return result;
9855 }
9856
9857 gint32
9858 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
9859                                         MonoReflectionMethod *method,
9860                                         MonoArray *opt_param_types)
9861 {
9862         MONO_CHECK_ARG_NULL (method, 0);
9863
9864         MonoError error;
9865         gint32 result = mono_image_create_method_token (
9866                 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
9867         mono_error_set_pending_exception (&error);
9868         return result;
9869 }
9870
9871 void
9872 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
9873 {
9874         MonoError error;
9875         mono_image_create_pefile (mb, file, &error);
9876         mono_error_set_pending_exception (&error);
9877 }
9878
9879 void
9880 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
9881 {
9882         MonoError error;
9883         mono_image_build_metadata (mb, &error);
9884         mono_error_set_pending_exception (&error);
9885 }
9886
9887 void
9888 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
9889 {
9890         mono_image_register_token (mb->dynamic_image, token, obj);
9891 }
9892
9893 MonoObject*
9894 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
9895 {
9896         MonoObject *obj;
9897
9898         mono_loader_lock ();
9899         obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
9900         mono_loader_unlock ();
9901
9902         return obj;
9903 }
9904
9905 MonoReflectionModule*
9906 ves_icall_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
9907 {
9908         MonoError error;
9909         MonoReflectionModule *result = mono_image_load_module_dynamic (ab, fileName, &error);
9910         mono_error_set_pending_exception (&error);
9911         return result;
9912 }
9913
9914 /**
9915  * ves_icall_TypeBuilder_create_generic_class:
9916  * @tb: a TypeBuilder object
9917  *
9918  * (icall)
9919  * Creates the generic class after all generic parameters have been added.
9920  */
9921 void
9922 ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
9923 {
9924         MonoError error;
9925         (void) mono_reflection_create_generic_class (tb, &error);
9926         mono_error_set_pending_exception (&error);
9927 }
9928
9929 #ifndef DISABLE_REFLECTION_EMIT
9930 MonoArray*
9931 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
9932 {
9933         MonoError error;
9934         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
9935         mono_error_set_pending_exception (&error);
9936         return result;
9937 }
9938 #endif
9939
9940 void
9941 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
9942 {
9943         mono_image_basic_init (assemblyb);
9944 }
9945
9946 MonoBoolean
9947 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
9948 {
9949         return mono_type_is_generic_parameter (tb->type.type);
9950 }
9951
9952 void
9953 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
9954                                                                            MonoReflectionType *t)
9955 {
9956         enumtype->type = t->type;
9957 }
9958
9959 MonoReflectionType*
9960 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
9961 {
9962         MonoError error;
9963         MonoReflectionType *ret;
9964         MonoClass *klass;
9965         int isbyref = 0, rank;
9966         char *p;
9967         char *str = mono_string_to_utf8_checked (smodifiers, &error);
9968         if (mono_error_set_pending_exception (&error))
9969                 return NULL;
9970
9971         klass = mono_class_from_mono_type (tb->type.type);
9972         p = str;
9973         /* logic taken from mono_reflection_parse_type(): keep in sync */
9974         while (*p) {
9975                 switch (*p) {
9976                 case '&':
9977                         if (isbyref) { /* only one level allowed by the spec */
9978                                 g_free (str);
9979                                 return NULL;
9980                         }
9981                         isbyref = 1;
9982                         p++;
9983
9984                         g_free (str);
9985
9986                         ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
9987                         mono_error_set_pending_exception (&error);
9988
9989                         return ret;
9990                 case '*':
9991                         klass = mono_ptr_class_get (&klass->byval_arg);
9992                         mono_class_init (klass);
9993                         p++;
9994                         break;
9995                 case '[':
9996                         rank = 1;
9997                         p++;
9998                         while (*p) {
9999                                 if (*p == ']')
10000                                         break;
10001                                 if (*p == ',')
10002                                         rank++;
10003                                 else if (*p != '*') { /* '*' means unknown lower bound */
10004                                         g_free (str);
10005                                         return NULL;
10006                                 }
10007                                 ++p;
10008                         }
10009                         if (*p != ']') {
10010                                 g_free (str);
10011                                 return NULL;
10012                         }
10013                         p++;
10014                         klass = mono_array_class_get (klass, rank);
10015                         mono_class_init (klass);
10016                         break;
10017                 default:
10018                         break;
10019                 }
10020         }
10021
10022         g_free (str);
10023
10024         ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
10025         mono_error_set_pending_exception (&error);
10026
10027         return ret;
10028 }
10029
10030 void
10031 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
10032 {
10033         mono_image_module_basic_init (moduleb);
10034 }
10035
10036 guint32
10037 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
10038 {
10039         return mono_image_insert_string (module, str);
10040 }
10041
10042 void
10043 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
10044 {
10045         MonoDynamicImage *image = moduleb->dynamic_image;
10046
10047         g_assert (type->type);
10048         image->wrappers_type = mono_class_from_mono_type (type->type);
10049 }