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