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