Merge pull request #4102 from marek-safar/bootstrap
[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 #include "mono/io-layer/io-layer.h"
38
39 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
40 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder);
41
42 #ifndef DISABLE_REFLECTION_EMIT
43 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
44 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
45 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
46 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
47 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error);
48 static gboolean reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error);
49
50
51 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
52 #endif
53
54 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
55 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error);
56 static gboolean is_sre_array (MonoClass *klass);
57 static gboolean is_sre_byref (MonoClass *klass);
58 static gboolean is_sre_pointer (MonoClass *klass);
59 static gboolean is_sre_generic_instance (MonoClass *klass);
60 static gboolean is_sre_type_builder (MonoClass *klass);
61 static gboolean is_sre_method_builder (MonoClass *klass);
62 static gboolean is_sre_field_builder (MonoClass *klass);
63 static gboolean is_sre_gparam_builder (MonoClass *klass);
64 static gboolean is_sre_enum_builder (MonoClass *klass);
65 static gboolean is_sr_mono_method (MonoClass *klass);
66 static gboolean is_sr_mono_field (MonoClass *klass);
67
68 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
69 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
70
71 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
72
73 static void mono_image_module_basic_init (MonoReflectionModuleBuilder *module);
74
75 void
76 mono_reflection_emit_init (void)
77 {
78         mono_dynamic_images_init ();
79 }
80
81 static char*
82 type_get_fully_qualified_name (MonoType *type)
83 {
84         MONO_REQ_GC_NEUTRAL_MODE;
85
86         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
87 }
88
89 static char*
90 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
91 {
92         MONO_REQ_GC_UNSAFE_MODE;
93
94         MonoClass *klass;
95         MonoAssembly *ta;
96
97         klass = mono_class_from_mono_type (type);
98         if (!klass) 
99                 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
100         ta = klass->image->assembly;
101         if (assembly_is_dynamic (ta) || (ta == ass)) {
102                 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
103                         /* For generic type definitions, we want T, while REFLECTION returns T<K> */
104                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
105                 else
106                         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
107         }
108
109         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
110 }
111
112 #ifndef DISABLE_REFLECTION_EMIT
113 /**
114  * mp_g_alloc:
115  *
116  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
117  * from the C heap.
118  */
119 static gpointer
120 image_g_malloc (MonoImage *image, guint size)
121 {
122         MONO_REQ_GC_NEUTRAL_MODE;
123
124         if (image)
125                 return mono_image_alloc (image, size);
126         else
127                 return g_malloc (size);
128 }
129 #endif /* !DISABLE_REFLECTION_EMIT */
130
131 /**
132  * image_g_alloc0:
133  *
134  * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
135  * from the C heap.
136  */
137 gpointer
138 mono_image_g_malloc0 (MonoImage *image, guint size)
139 {
140         MONO_REQ_GC_NEUTRAL_MODE;
141
142         if (image)
143                 return mono_image_alloc0 (image, size);
144         else
145                 return g_malloc0 (size);
146 }
147
148 /**
149  * image_g_free:
150  * @image: a MonoImage
151  * @ptr: pointer
152  *
153  * If @image is NULL, free @ptr, otherwise do nothing.
154  */
155 static void
156 image_g_free (MonoImage *image, gpointer ptr)
157 {
158         if (image == NULL)
159                 g_free (ptr);
160 }
161
162 #ifndef DISABLE_REFLECTION_EMIT
163 static char*
164 image_strdup (MonoImage *image, const char *s)
165 {
166         MONO_REQ_GC_NEUTRAL_MODE;
167
168         if (image)
169                 return mono_image_strdup (image, s);
170         else
171                 return g_strdup (s);
172 }
173 #endif
174
175 #define image_g_new(image,struct_type, n_structs)               \
176     ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
177
178 #define image_g_new0(image,struct_type, n_structs)              \
179     ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
180
181
182 static void
183 alloc_table (MonoDynamicTable *table, guint nrows)
184 {
185         mono_dynimage_alloc_table (table, nrows);
186 }
187
188 static guint32
189 string_heap_insert (MonoDynamicStream *sh, const char *str)
190 {
191         return mono_dynstream_insert_string (sh, str);
192 }
193
194 static guint32
195 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
196 {
197         return mono_dynstream_add_data (stream, data, len);
198 }
199
200 /*
201  * Despite the name, we handle also TypeSpec (with the above helper).
202  */
203 static guint32
204 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
205 {
206         return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
207 }
208
209 /*
210  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
211  * dest may be misaligned.
212  */
213 static void
214 swap_with_size (char *dest, const char* val, int len, int nelem) {
215         MONO_REQ_GC_NEUTRAL_MODE;
216 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
217         int elem;
218
219         for (elem = 0; elem < nelem; ++elem) {
220                 switch (len) {
221                 case 1:
222                         *dest = *val;
223                         break;
224                 case 2:
225                         dest [0] = val [1];
226                         dest [1] = val [0];
227                         break;
228                 case 4:
229                         dest [0] = val [3];
230                         dest [1] = val [2];
231                         dest [2] = val [1];
232                         dest [3] = val [0];
233                         break;
234                 case 8:
235                         dest [0] = val [7];
236                         dest [1] = val [6];
237                         dest [2] = val [5];
238                         dest [3] = val [4];
239                         dest [4] = val [3];
240                         dest [5] = val [2];
241                         dest [6] = val [1];
242                         dest [7] = val [0];
243                         break;
244                 default:
245                         g_assert_not_reached ();
246                 }
247                 dest += len;
248                 val += len;
249         }
250 #else
251         memcpy (dest, val, len * nelem);
252 #endif
253 }
254
255 guint32
256 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
257 {
258         MONO_REQ_GC_UNSAFE_MODE;
259
260         guint32 num_clauses = 0;
261         int i;
262
263         MonoILExceptionInfo *ex_info;
264         for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
265                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
266                 if (ex_info->handlers)
267                         num_clauses += mono_array_length (ex_info->handlers);
268                 else
269                         num_clauses++;
270         }
271
272         return num_clauses;
273 }
274
275 #ifndef DISABLE_REFLECTION_EMIT
276 static MonoExceptionClause*
277 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
278 {
279         MONO_REQ_GC_UNSAFE_MODE;
280
281         mono_error_init (error);
282
283         MonoExceptionClause *clauses;
284         MonoExceptionClause *clause;
285         MonoILExceptionInfo *ex_info;
286         MonoILExceptionBlock *ex_block;
287         guint32 finally_start;
288         int i, j, clause_index;;
289
290         clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
291
292         clause_index = 0;
293         for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
294                 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
295                 finally_start = ex_info->start + ex_info->len;
296                 if (!ex_info->handlers)
297                         continue;
298                 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
299                         ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
300                         clause = &(clauses [clause_index]);
301
302                         clause->flags = ex_block->type;
303                         clause->try_offset = ex_info->start;
304
305                         if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
306                                 clause->try_len = finally_start - ex_info->start;
307                         else
308                                 clause->try_len = ex_info->len;
309                         clause->handler_offset = ex_block->start;
310                         clause->handler_len = ex_block->len;
311                         if (ex_block->extype) {
312                                 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
313
314                                 if (!is_ok (error)) {
315                                         image_g_free (image, clauses);
316                                         return NULL;
317                                 }
318                                 clause->data.catch_class = mono_class_from_mono_type (extype);
319                         } else {
320                                 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
321                                         clause->data.filter_offset = ex_block->filter_offset;
322                                 else
323                                         clause->data.filter_offset = 0;
324                         }
325                         finally_start = ex_block->start + ex_block->len;
326
327                         clause_index ++;
328                 }
329         }
330
331         return clauses;
332 }
333 #endif /* !DISABLE_REFLECTION_EMIT */
334
335 #ifndef DISABLE_REFLECTION_EMIT
336 /*
337  * LOCKING: Acquires the loader lock. 
338  */
339 static void
340 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
341 {
342         MONO_REQ_GC_UNSAFE_MODE;
343
344         MonoCustomAttrInfo *ainfo, *tmp;
345
346         if (!cattrs || !mono_array_length (cattrs))
347                 return;
348
349         ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
350
351         mono_loader_lock ();
352         tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
353         if (tmp)
354                 mono_custom_attrs_free (tmp);
355         mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
356         mono_loader_unlock ();
357
358 }
359 #endif
360
361 guint32
362 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
363 {
364         MONO_REQ_GC_UNSAFE_MODE;
365
366         MonoDynamicTable *table;
367         guint32 token;
368         guint32 *values;
369         guint32 cols [MONO_ASSEMBLY_SIZE];
370         const char *pubkey;
371         guint32 publen;
372
373         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
374                 return token;
375
376         if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
377                 table = &assembly->tables [MONO_TABLE_MODULEREF];
378                 token = table->next_idx ++;
379                 table->rows ++;
380                 alloc_table (table, table->rows);
381                 values = table->values + token * MONO_MODULEREF_SIZE;
382                 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
383
384                 token <<= MONO_RESOLUTION_SCOPE_BITS;
385                 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
386                 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
387
388                 return token;
389         }
390         
391         if (assembly_is_dynamic (image->assembly))
392                 /* FIXME: */
393                 memset (cols, 0, sizeof (cols));
394         else {
395                 /* image->assembly->image is the manifest module */
396                 image = image->assembly->image;
397                 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
398         }
399
400         table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
401         token = table->next_idx ++;
402         table->rows ++;
403         alloc_table (table, table->rows);
404         values = table->values + token * MONO_ASSEMBLYREF_SIZE;
405         values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
406         values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
407         values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
408         values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
409         values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
410         values [MONO_ASSEMBLYREF_FLAGS] = 0;
411         values [MONO_ASSEMBLYREF_CULTURE] = 0;
412         values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
413
414         if (strcmp ("", image->assembly->aname.culture)) {
415                 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
416                                 image->assembly->aname.culture);
417         }
418
419         if ((pubkey = mono_image_get_public_key (image, &publen))) {
420                 guchar pubtoken [9];
421                 pubtoken [0] = 8;
422                 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
423                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
424         } else {
425                 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
426         }
427         token <<= MONO_RESOLUTION_SCOPE_BITS;
428         token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
429         g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
430         return token;
431 }
432
433 #ifndef DISABLE_REFLECTION_EMIT
434 gboolean
435 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
436 {
437         MONO_REQ_GC_UNSAFE_MODE;
438
439         mono_error_init (error);
440         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
441
442         rmb->ilgen = mb->ilgen;
443         rmb->rtype = (MonoReflectionType*)mb->rtype;
444         return_val_if_nok (error, FALSE);
445         rmb->parameters = mb->parameters;
446         rmb->generic_params = mb->generic_params;
447         rmb->generic_container = mb->generic_container;
448         rmb->opt_types = NULL;
449         rmb->pinfo = mb->pinfo;
450         rmb->attrs = mb->attrs;
451         rmb->iattrs = mb->iattrs;
452         rmb->call_conv = mb->call_conv;
453         rmb->code = mb->code;
454         rmb->type = mb->type;
455         rmb->name = mb->name;
456         rmb->table_idx = &mb->table_idx;
457         rmb->init_locals = mb->init_locals;
458         rmb->skip_visibility = FALSE;
459         rmb->return_modreq = mb->return_modreq;
460         rmb->return_modopt = mb->return_modopt;
461         rmb->param_modreq = mb->param_modreq;
462         rmb->param_modopt = mb->param_modopt;
463         rmb->permissions = mb->permissions;
464         rmb->mhandle = mb->mhandle;
465         rmb->nrefs = 0;
466         rmb->refs = NULL;
467
468         if (mb->dll) {
469                 rmb->charset = mb->charset;
470                 rmb->extra_flags = mb->extra_flags;
471                 rmb->native_cc = mb->native_cc;
472                 rmb->dllentry = mb->dllentry;
473                 rmb->dll = mb->dll;
474         }
475
476         return TRUE;
477 }
478
479 gboolean
480 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
481 {
482         MONO_REQ_GC_UNSAFE_MODE;
483
484         const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
485
486         mono_error_init (error);
487
488         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
489
490         rmb->ilgen = mb->ilgen;
491         rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
492         return_val_if_nok (error, FALSE);
493         rmb->parameters = mb->parameters;
494         rmb->generic_params = NULL;
495         rmb->generic_container = NULL;
496         rmb->opt_types = NULL;
497         rmb->pinfo = mb->pinfo;
498         rmb->attrs = mb->attrs;
499         rmb->iattrs = mb->iattrs;
500         rmb->call_conv = mb->call_conv;
501         rmb->code = NULL;
502         rmb->type = mb->type;
503         rmb->name = mono_string_new (mono_domain_get (), name);
504         rmb->table_idx = &mb->table_idx;
505         rmb->init_locals = mb->init_locals;
506         rmb->skip_visibility = FALSE;
507         rmb->return_modreq = NULL;
508         rmb->return_modopt = NULL;
509         rmb->param_modreq = mb->param_modreq;
510         rmb->param_modopt = mb->param_modopt;
511         rmb->permissions = mb->permissions;
512         rmb->mhandle = mb->mhandle;
513         rmb->nrefs = 0;
514         rmb->refs = NULL;
515
516         return TRUE;
517 }
518
519 static void
520 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
521 {
522         MONO_REQ_GC_UNSAFE_MODE;
523
524         memset (rmb, 0, sizeof (ReflectionMethodBuilder));
525
526         rmb->ilgen = mb->ilgen;
527         rmb->rtype = mb->rtype;
528         rmb->parameters = mb->parameters;
529         rmb->generic_params = NULL;
530         rmb->generic_container = NULL;
531         rmb->opt_types = NULL;
532         rmb->pinfo = NULL;
533         rmb->attrs = mb->attrs;
534         rmb->iattrs = 0;
535         rmb->call_conv = mb->call_conv;
536         rmb->code = NULL;
537         rmb->type = (MonoObject *) mb->owner;
538         rmb->name = mb->name;
539         rmb->table_idx = NULL;
540         rmb->init_locals = mb->init_locals;
541         rmb->skip_visibility = mb->skip_visibility;
542         rmb->return_modreq = NULL;
543         rmb->return_modopt = NULL;
544         rmb->param_modreq = NULL;
545         rmb->param_modopt = NULL;
546         rmb->permissions = NULL;
547         rmb->mhandle = mb->mhandle;
548         rmb->nrefs = 0;
549         rmb->refs = NULL;
550 }       
551 #else /* DISABLE_REFLECTION_EMIT */
552 gboolean
553 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
554         g_assert_not_reached ();
555         return FALSE;
556 }
557 gboolean
558 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
559 {
560         g_assert_not_reached ();
561         return FALSE;
562 }
563 #endif /* DISABLE_REFLECTION_EMIT */
564
565 #ifndef DISABLE_REFLECTION_EMIT
566 static guint32
567 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
568 {
569         MONO_REQ_GC_NEUTRAL_MODE;
570
571         MonoDynamicTable *table;
572         guint32 *values;
573         guint32 token, pclass;
574
575         switch (parent & MONO_TYPEDEFORREF_MASK) {
576         case MONO_TYPEDEFORREF_TYPEREF:
577                 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
578                 break;
579         case MONO_TYPEDEFORREF_TYPESPEC:
580                 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
581                 break;
582         case MONO_TYPEDEFORREF_TYPEDEF:
583                 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
584                 break;
585         default:
586                 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
587                 return 0;
588         }
589         /* extract the index */
590         parent >>= MONO_TYPEDEFORREF_BITS;
591
592         table = &assembly->tables [MONO_TABLE_MEMBERREF];
593
594         if (assembly->save) {
595                 alloc_table (table, table->rows + 1);
596                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
597                 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
598                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
599                 values [MONO_MEMBERREF_SIGNATURE] = sig;
600         }
601
602         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
603         table->next_idx ++;
604
605         return token;
606 }
607
608 /*
609  * Insert a memberef row into the metadata: the token that point to the memberref
610  * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
611  * mono_image_get_fieldref_token()).
612  * The sig param is an index to an already built signature.
613  */
614 static guint32
615 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
616 {
617         MONO_REQ_GC_NEUTRAL_MODE;
618
619         guint32 parent = mono_image_typedef_or_ref (assembly, type);
620         return mono_image_add_memberef_row (assembly, parent, name, sig);
621 }
622
623
624 static guint32
625 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
626 {
627         MONO_REQ_GC_NEUTRAL_MODE;
628
629         guint32 token;
630         MonoMethodSignature *sig;
631         
632         create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
633
634         if (create_typespec) {
635                 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
636                 if (token)
637                         return token;
638         } 
639
640         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
641         if (token && !create_typespec)
642                 return token;
643
644         g_assert (!method->is_inflated);
645         if (!token) {
646                 /*
647                  * A methodref signature can't contain an unmanaged calling convention.
648                  */
649                 sig = mono_metadata_signature_dup (mono_method_signature (method));
650                 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
651                         sig->call_convention = MONO_CALL_DEFAULT;
652                 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
653                         method->name,  mono_dynimage_encode_method_signature (assembly, sig));
654                 g_free (sig);
655                 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
656         }
657
658         if (create_typespec) {
659                 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
660                 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
661                 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
662
663                 if (assembly->save) {
664                         guint32 *values;
665
666                         alloc_table (table, table->rows + 1);
667                         values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
668                         values [MONO_METHODSPEC_METHOD] = token;
669                         values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
670                 }
671
672                 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
673                 table->next_idx ++;
674                 /*methodspec and memberef tokens are diferent, */
675                 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
676                 return token;
677         }
678         return token;
679 }
680
681 static guint32
682 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
683                                      const gchar *name, guint32 sig)
684 {
685         MonoDynamicTable *table;
686         guint32 token;
687         guint32 *values;
688         
689         table = &assembly->tables [MONO_TABLE_MEMBERREF];
690
691         if (assembly->save) {
692                 alloc_table (table, table->rows + 1);
693                 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
694                 values [MONO_MEMBERREF_CLASS] = original;
695                 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
696                 values [MONO_MEMBERREF_SIGNATURE] = sig;
697         }
698
699         token = MONO_TOKEN_MEMBER_REF | table->next_idx;
700         table->next_idx ++;
701
702         return token;
703 }
704
705 #endif
706
707 static gboolean
708 is_field_on_inst (MonoClassField *field)
709 {
710         return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
711 }
712
713 #ifndef DISABLE_REFLECTION_EMIT
714 static guint32
715 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
716 {
717         MonoType *type;
718         guint32 token;
719
720         g_assert (field);
721         g_assert (field->parent);
722
723         token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
724         if (token)
725                 return token;
726
727         if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
728                 int index = field - field->parent->fields;
729                 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
730         } else {
731                 type = mono_field_get_type (field);
732         }
733         token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
734                                                                                         mono_field_get_name (field),
735                                                                                         mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
736         mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
737         return token;
738 }
739
740 static guint32
741 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
742 {
743         MonoDynamicTable *table;
744         guint32 *values;
745         guint32 token, mtoken = 0, sig;
746         MonoMethodInflated *imethod;
747         MonoMethod *declaring;
748
749         table = &assembly->tables [MONO_TABLE_METHODSPEC];
750
751         g_assert (method->is_inflated);
752         imethod = (MonoMethodInflated *) method;
753         declaring = imethod->declaring;
754
755         sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
756         mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
757
758         if (!mono_method_signature (declaring)->generic_param_count)
759                 return mtoken;
760
761         switch (mono_metadata_token_table (mtoken)) {
762         case MONO_TABLE_MEMBERREF:
763                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
764                 break;
765         case MONO_TABLE_METHOD:
766                 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
767                 break;
768         default:
769                 g_assert_not_reached ();
770         }
771
772         sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
773
774         if (assembly->save) {
775                 alloc_table (table, table->rows + 1);
776                 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
777                 values [MONO_METHODSPEC_METHOD] = mtoken;
778                 values [MONO_METHODSPEC_SIGNATURE] = sig;
779         }
780
781         token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
782         table->next_idx ++;
783
784         return token;
785 }
786
787 static guint32
788 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
789 {
790         MonoMethodInflated *imethod;
791         guint32 token;
792         
793         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
794         if (token)
795                 return token;
796
797         g_assert (method->is_inflated);
798         imethod = (MonoMethodInflated *) method;
799
800         if (mono_method_signature (imethod->declaring)->generic_param_count) {
801                 token = method_encode_methodspec (assembly, method);
802         } else {
803                 guint32 sig = mono_dynimage_encode_method_signature (
804                         assembly, mono_method_signature (imethod->declaring));
805                 token = mono_image_get_memberref_token (
806                         assembly, &method->klass->byval_arg, method->name, sig);
807         }
808
809         g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
810         return token;
811 }
812
813 static guint32
814 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
815 {
816         MonoMethodInflated *imethod = (MonoMethodInflated *) m;
817         guint32 sig, token;
818
819         sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
820         token = mono_image_get_memberref_token (
821                 assembly, &m->klass->byval_arg, m->name, sig);
822
823         return token;
824 }
825
826 static guint32 
827 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
828 {
829         guint32 idx;
830         MonoDynamicTable *table;
831         guint32 *values;
832
833         mono_error_init (error);
834
835         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
836         idx = table->next_idx ++;
837         table->rows ++;
838         alloc_table (table, table->rows);
839         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
840
841         values [MONO_STAND_ALONE_SIGNATURE] =
842                 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
843         return_val_if_nok (error, 0);
844         
845         return idx;
846 }
847
848 static int
849 reflection_cc_to_file (int call_conv) {
850         switch (call_conv & 0x3) {
851         case 0:
852         case 1: return MONO_CALL_DEFAULT;
853         case 2: return MONO_CALL_VARARG;
854         default:
855                 g_assert_not_reached ();
856         }
857         return 0;
858 }
859 #endif /* !DISABLE_REFLECTION_EMIT */
860
861 struct _ArrayMethod {
862         MonoType *parent;
863         MonoMethodSignature *sig;
864         char *name;
865         guint32 token;
866 };
867
868 void
869 mono_sre_array_method_free (ArrayMethod *am)
870 {
871         g_free (am->sig);
872         g_free (am->name);
873         g_free (am);
874 }
875
876 #ifndef DISABLE_REFLECTION_EMIT
877 static guint32
878 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m, MonoError *error)
879 {
880         guint32 nparams, i;
881         GList *tmp;
882         char *name = NULL;
883         MonoMethodSignature *sig;
884         ArrayMethod *am = NULL;
885         MonoType *mtype;
886
887         mono_error_init (error);
888
889         nparams = mono_array_length (m->parameters);
890         sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
891         sig->hasthis = 1;
892         sig->sentinelpos = -1;
893         sig->call_convention = reflection_cc_to_file (m->call_conv);
894         sig->param_count = nparams;
895         if (m->ret) {
896                 sig->ret = mono_reflection_type_get_handle (m->ret, error);
897                 if (!is_ok (error))
898                         goto fail;
899         } else
900                 sig->ret = &mono_defaults.void_class->byval_arg;
901
902         mtype = mono_reflection_type_get_handle (m->parent, error);
903         if (!is_ok (error))
904                 goto fail;
905
906         for (i = 0; i < nparams; ++i) {
907                 sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i, error);
908                 if (!is_ok (error))
909                         goto fail;
910         }
911
912         name = mono_string_to_utf8_checked (m->name, error);
913         if (!is_ok (error))
914                 goto fail;
915         for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
916                 am = (ArrayMethod *)tmp->data;
917                 if (strcmp (name, am->name) == 0 && 
918                                 mono_metadata_type_equal (am->parent, mtype) &&
919                                 mono_metadata_signature_equal (am->sig, sig)) {
920                         g_free (name);
921                         g_free (sig);
922                         m->table_idx = am->token & 0xffffff;
923                         return am->token;
924                 }
925         }
926         am = g_new0 (ArrayMethod, 1);
927         am->name = name;
928         am->sig = sig;
929         am->parent = mtype;
930         am->token = mono_image_get_memberref_token (assembly, am->parent, name,
931                 mono_dynimage_encode_method_signature (assembly, sig));
932         assembly->array_methods = g_list_prepend (assembly->array_methods, am);
933         m->table_idx = am->token & 0xffffff;
934         return am->token;
935 fail:
936         g_free (am);
937         g_free (name);
938         g_free (sig);
939         return 0;
940
941 }
942 #endif
943
944 #ifndef DISABLE_REFLECTION_EMIT
945
946 /*
947  * mono_image_insert_string:
948  * @module: module builder object
949  * @str: a string
950  *
951  * Insert @str into the user string stream of @module.
952  */
953 guint32
954 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
955 {
956         MonoDynamicImage *assembly;
957         guint32 idx;
958         char buf [16];
959         char *b = buf;
960         
961         if (!module->dynamic_image)
962                 mono_image_module_basic_init (module);
963
964         assembly = module->dynamic_image;
965         
966         if (assembly->save) {
967                 mono_metadata_encode_value (1 | (str->length * 2), b, &b);
968                 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
969 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
970         {
971                 char *swapped = g_malloc (2 * mono_string_length (str));
972                 const char *p = (const char*)mono_string_chars (str);
973
974                 swap_with_size (swapped, p, 2, mono_string_length (str));
975                 mono_image_add_stream_data (&assembly->us, swapped, str->length * 2);
976                 g_free (swapped);
977         }
978 #else
979                 mono_image_add_stream_data (&assembly->us, (const char*)mono_string_chars (str), str->length * 2);
980 #endif
981                 mono_image_add_stream_data (&assembly->us, "", 1);
982         } else {
983                 idx = assembly->us.index ++;
984         }
985
986         mono_dynamic_image_register_token (assembly, MONO_TOKEN_STRING | idx, (MonoObject*)str);
987
988         return MONO_TOKEN_STRING | idx;
989 }
990
991 guint32
992 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
993 {
994         MonoClass *klass;
995         guint32 token = 0;
996         MonoMethodSignature *sig;
997
998         mono_error_init (error);
999
1000         klass = obj->vtable->klass;
1001         if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1002                 MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
1003                 MonoMethodSignature *old;
1004                 guint32 sig_token, parent;
1005                 int nargs, i;
1006
1007                 g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));
1008
1009                 nargs = mono_array_length (opt_param_types);
1010                 old = mono_method_signature (method);
1011                 sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1012
1013                 sig->hasthis = old->hasthis;
1014                 sig->explicit_this = old->explicit_this;
1015                 sig->call_convention = old->call_convention;
1016                 sig->generic_param_count = old->generic_param_count;
1017                 sig->param_count = old->param_count + nargs;
1018                 sig->sentinelpos = old->param_count;
1019                 sig->ret = old->ret;
1020
1021                 for (i = 0; i < old->param_count; i++)
1022                         sig->params [i] = old->params [i];
1023
1024                 for (i = 0; i < nargs; i++) {
1025                         MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1026                         sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt, error);
1027                         if (!is_ok (error)) goto fail;
1028                 }
1029
1030                 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1031                 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1032                 parent >>= MONO_TYPEDEFORREF_BITS;
1033
1034                 parent <<= MONO_MEMBERREF_PARENT_BITS;
1035                 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1036
1037                 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1038                 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1039         } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1040                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
1041                 ReflectionMethodBuilder rmb;
1042                 guint32 parent, sig_token;
1043                 int nopt_args, nparams, ngparams, i;
1044
1045                 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
1046                         goto fail;
1047                 
1048                 rmb.opt_types = opt_param_types;
1049                 nopt_args = mono_array_length (opt_param_types);
1050
1051                 nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
1052                 ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
1053                 sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
1054
1055                 sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
1056                 sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
1057                 sig->call_convention = rmb.call_conv;
1058                 sig->generic_param_count = ngparams;
1059                 sig->param_count = nparams + nopt_args;
1060                 sig->sentinelpos = nparams;
1061                 sig->ret = mono_reflection_type_get_handle (rmb.rtype, error);
1062                 if (!is_ok (error)) goto fail;
1063
1064                 for (i = 0; i < nparams; i++) {
1065                         MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
1066                         sig->params [i] = mono_reflection_type_get_handle (rt, error);
1067                         if (!is_ok (error)) goto fail;
1068                 }
1069
1070                 for (i = 0; i < nopt_args; i++) {
1071                         MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
1072                         sig->params [nparams + i] = mono_reflection_type_get_handle (rt, error);
1073                         if (!is_ok (error)) goto fail;
1074                 }
1075
1076                 // FIXME: This doesn't work, we don't use 'sig' for anything
1077                 // The token fixup doesn't work either
1078                 g_assert_not_reached ();
1079
1080                 sig_token = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
1081                 if (!is_ok (error))
1082                         goto fail;
1083
1084                 parent = mono_image_create_token (assembly, obj, TRUE, TRUE, error);
1085                 if (!mono_error_ok (error))
1086                         goto fail;
1087                 g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
1088
1089                 parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
1090                 parent |= MONO_MEMBERREF_PARENT_METHODDEF;
1091
1092                 char *name = mono_string_to_utf8_checked (rmb.name, error);
1093                 if (!is_ok (error)) goto fail;
1094                 token = mono_image_get_varargs_method_token (
1095                         assembly, parent, name, sig_token);
1096                 g_free (name);
1097         } else {
1098                 g_error ("requested method token for %s\n", klass->name);
1099         }
1100
1101         g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1102         mono_dynamic_image_register_token (assembly, token, obj);
1103         return token;
1104 fail:
1105         g_assert (!mono_error_ok (error));
1106         return 0;
1107 }
1108
1109 /*
1110  * mono_image_create_token:
1111  * @assembly: a dynamic assembly
1112  * @obj:
1113  * @register_token: Whenever to register the token in the assembly->tokens hash. 
1114  *
1115  * Get a token to insert in the IL code stream for the given MemberInfo.
1116  * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, 
1117  * the table_idx-es were recomputed, so registering the token would overwrite an existing 
1118  * entry.
1119  */
1120 guint32
1121 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
1122                          gboolean create_open_instance, gboolean register_token,
1123                          MonoError *error)
1124 {
1125         MonoClass *klass;
1126         guint32 token = 0;
1127
1128         mono_error_init (error);
1129
1130         klass = obj->vtable->klass;
1131
1132         /* Check for user defined reflection objects */
1133         /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1134         if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1135                 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1136                 return 0;
1137         }
1138
1139         if (strcmp (klass->name, "RuntimeType") == 0) {
1140                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1141                 return_val_if_nok (error, 0);
1142                 MonoClass *mc = mono_class_from_mono_type (type);
1143                 token = mono_metadata_token_from_dor (
1144                         mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1145         } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1146                            strcmp (klass->name, "MonoMethod") == 0) {
1147                 MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
1148                 if (m->method->is_inflated) {
1149                         if (create_open_instance)
1150                                 token = mono_image_get_methodspec_token (assembly, m->method);
1151                         else
1152                                 token = mono_image_get_inflated_method_token (assembly, m->method);
1153                 } else if ((m->method->klass->image == &assembly->image) &&
1154                          !mono_class_is_ginst (m->method->klass)) {
1155                         static guint32 method_table_idx = 0xffffff;
1156                         if (m->method->klass->wastypebuilder) {
1157                                 /* we use the same token as the one that was assigned
1158                                  * to the Methodbuilder.
1159                                  * FIXME: do the equivalent for Fields.
1160                                  */
1161                                 token = m->method->token;
1162                         } else {
1163                                 /*
1164                                  * Each token should have a unique index, but the indexes are
1165                                  * assigned by managed code, so we don't know about them. An
1166                                  * easy solution is to count backwards...
1167                                  */
1168                                 method_table_idx --;
1169                                 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1170                         }
1171                 } else {
1172                         token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
1173                 }
1174                 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1175         } else if (strcmp (klass->name, "MonoField") == 0) {
1176                 MonoReflectionField *f = (MonoReflectionField *)obj;
1177                 if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
1178                         static guint32 field_table_idx = 0xffffff;
1179                         field_table_idx --;
1180                         token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1181                 } else {
1182                         token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
1183                 }
1184                 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1185         } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1186                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod *)obj;
1187                 token = mono_image_get_array_token (assembly, m, error);
1188                 return_val_if_nok (error, 0);
1189         } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1190                 MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
1191                 token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1192                 return_val_if_nok (error, 0);
1193         } else if (strcmp (klass->name, "EnumBuilder") == 0) {
1194                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
1195                 return_val_if_nok (error, 0);
1196                 token = mono_metadata_token_from_dor (
1197                         mono_image_typedef_or_ref (assembly, type));
1198         } else {
1199                 g_error ("requested token for %s\n", klass->name);
1200         }
1201
1202         if (register_token)
1203                 mono_image_register_token (assembly, token, obj);
1204
1205         return token;
1206 }
1207
1208
1209 #endif
1210
1211 #ifndef DISABLE_REFLECTION_EMIT
1212
1213 /*
1214  * mono_reflection_dynimage_basic_init:
1215  * @assembly: an assembly builder object
1216  *
1217  * Create the MonoImage that represents the assembly builder and setup some
1218  * of the helper hash table and the basic metadata streams.
1219  */
1220 void
1221 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1222 {
1223         MonoError error;
1224         MonoDynamicAssembly *assembly;
1225         MonoDynamicImage *image;
1226         MonoDomain *domain = mono_object_domain (assemblyb);
1227         
1228         if (assemblyb->dynamic_assembly)
1229                 return;
1230
1231 #if HAVE_BOEHM_GC
1232         /* assembly->assembly.image might be GC allocated */
1233         assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
1234 #else
1235         assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1236 #endif
1237
1238         mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
1239         
1240         assembly->assembly.ref_count = 1;
1241         assembly->assembly.dynamic = TRUE;
1242         assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1243         assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1244         assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1245         if (mono_error_set_pending_exception (&error))
1246                 return;
1247         if (assemblyb->culture) {
1248                 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1249                 if (mono_error_set_pending_exception (&error))
1250                         return;
1251         } else
1252                 assembly->assembly.aname.culture = g_strdup ("");
1253
1254         if (assemblyb->version) {
1255                         char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1256                         if (mono_error_set_pending_exception (&error))
1257                                 return;
1258                         char **version = g_strsplit (vstr, ".", 4);
1259                         char **parts = version;
1260                         assembly->assembly.aname.major = atoi (*parts++);
1261                         assembly->assembly.aname.minor = atoi (*parts++);
1262                         assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1263                         assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1264
1265                         g_strfreev (version);
1266                         g_free (vstr);
1267         } else {
1268                         assembly->assembly.aname.major = 0;
1269                         assembly->assembly.aname.minor = 0;
1270                         assembly->assembly.aname.build = 0;
1271                         assembly->assembly.aname.revision = 0;
1272         }
1273
1274         assembly->run = assemblyb->access != 2;
1275         assembly->save = assemblyb->access != 1;
1276         assembly->domain = domain;
1277
1278         char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1279         if (mono_error_set_pending_exception (&error))
1280                 return;
1281         image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1282         image->initial_image = TRUE;
1283         assembly->assembly.aname.name = image->image.name;
1284         assembly->assembly.image = &image->image;
1285         if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1286                 /* -1 to correct for the trailing NULL byte */
1287                 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1288                         g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1289                 }
1290                 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);           
1291         }
1292
1293         mono_domain_assemblies_lock (domain);
1294         domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1295         mono_domain_assemblies_unlock (domain);
1296
1297         register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1298         
1299         mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
1300         
1301         mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1302 }
1303
1304 #endif /* !DISABLE_REFLECTION_EMIT */
1305
1306 #ifndef DISABLE_REFLECTION_EMIT
1307 static gpointer
1308 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1309 {
1310         return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1311 }
1312
1313 static gpointer
1314 register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
1315 {
1316         return CACHE_OBJECT (MonoReflectionModuleBuilder *, module, &res->module.obj, NULL);
1317 }
1318
1319 static gboolean
1320 image_module_basic_init (MonoReflectionModuleBuilder *moduleb, MonoError *error)
1321 {
1322         MonoDynamicImage *image = moduleb->dynamic_image;
1323         MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
1324         mono_error_init (error);
1325         if (!image) {
1326                 int module_count;
1327                 MonoImage **new_modules;
1328                 MonoImage *ass;
1329                 char *name, *fqname;
1330                 /*
1331                  * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1332                  * we don't know which module it belongs to, since that is only 
1333                  * determined at assembly save time.
1334                  */
1335                 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1336                 name = mono_string_to_utf8_checked (ab->name, error);
1337                 return_val_if_nok (error, FALSE);
1338                 fqname = mono_string_to_utf8_checked (moduleb->module.fqname, error);
1339                 if (!is_ok (error)) {
1340                         g_free (name);
1341                         return FALSE;
1342                 }
1343                 image = mono_dynamic_image_create (ab->dynamic_assembly, name, fqname);
1344
1345                 moduleb->module.image = &image->image;
1346                 moduleb->dynamic_image = image;
1347                 register_module (mono_object_domain (moduleb), moduleb, image);
1348
1349                 /* register the module with the assembly */
1350                 ass = ab->dynamic_assembly->assembly.image;
1351                 module_count = ass->module_count;
1352                 new_modules = g_new0 (MonoImage *, module_count + 1);
1353
1354                 if (ass->modules)
1355                         memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1356                 new_modules [module_count] = &image->image;
1357                 mono_image_addref (&image->image);
1358
1359                 g_free (ass->modules);
1360                 ass->modules = new_modules;
1361                 ass->module_count ++;
1362         }
1363         return TRUE;
1364 }
1365
1366 static void
1367 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
1368 {
1369         MonoError error;
1370         (void) image_module_basic_init (moduleb, &error);
1371         mono_error_set_pending_exception (&error);
1372 }
1373
1374 #endif
1375
1376 static gboolean
1377 is_corlib_type (MonoClass *klass)
1378 {
1379         return klass->image == mono_defaults.corlib;
1380 }
1381
1382 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1383         static MonoClass *cached_class; \
1384         if (cached_class) \
1385                 return cached_class == _class; \
1386         if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1387                 cached_class = _class; \
1388                 return TRUE; \
1389         } \
1390         return FALSE; \
1391 } while (0) \
1392
1393
1394
1395 #ifndef DISABLE_REFLECTION_EMIT
1396 static gboolean
1397 is_sre_array (MonoClass *klass)
1398 {
1399         check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1400 }
1401
1402 static gboolean
1403 is_sre_byref (MonoClass *klass)
1404 {
1405         check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1406 }
1407
1408 static gboolean
1409 is_sre_pointer (MonoClass *klass)
1410 {
1411         check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1412 }
1413
1414 static gboolean
1415 is_sre_generic_instance (MonoClass *klass)
1416 {
1417         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1418 }
1419
1420 static gboolean
1421 is_sre_type_builder (MonoClass *klass)
1422 {
1423         check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1424 }
1425
1426 static gboolean
1427 is_sre_method_builder (MonoClass *klass)
1428 {
1429         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1430 }
1431
1432 gboolean
1433 mono_is_sre_ctor_builder (MonoClass *klass)
1434 {
1435         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1436 }
1437
1438 static gboolean
1439 is_sre_field_builder (MonoClass *klass)
1440 {
1441         check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1442 }
1443
1444 static gboolean
1445 is_sre_gparam_builder (MonoClass *klass)
1446 {
1447         check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1448 }
1449
1450 static gboolean
1451 is_sre_enum_builder (MonoClass *klass)
1452 {
1453         check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1454 }
1455
1456 gboolean
1457 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1458 {
1459         check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1460 }
1461
1462 gboolean
1463 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1464 {
1465         check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1466 }
1467
1468 static MonoReflectionType*
1469 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t, MonoError *error)
1470 {
1471         static MonoMethod *method_get_underlying_system_type = NULL;
1472         MonoReflectionType *rt;
1473         MonoMethod *usertype_method;
1474
1475         mono_error_init (error);
1476
1477         if (!method_get_underlying_system_type)
1478                 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1479
1480         usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
1481
1482         rt = (MonoReflectionType *) mono_runtime_invoke_checked (usertype_method, t, NULL, error);
1483
1484         return rt;
1485 }
1486
1487 MonoType*
1488 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
1489 {
1490         MonoClass *klass;
1491         mono_error_init (error);
1492
1493         if (!ref)
1494                 return NULL;
1495         if (ref->type)
1496                 return ref->type;
1497
1498         if (mono_reflection_is_usertype (ref)) {
1499                 ref = mono_reflection_type_get_underlying_system_type (ref, error);
1500                 if (ref == NULL || mono_reflection_is_usertype (ref) || !is_ok (error))
1501                         return NULL;
1502                 if (ref->type)
1503                         return ref->type;
1504         }
1505
1506         klass = mono_object_class (ref);
1507
1508         if (is_sre_array (klass)) {
1509                 MonoType *res;
1510                 MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
1511                 MonoType *base = mono_reflection_type_get_handle (sre_array->element_type, error);
1512                 return_val_if_nok (error, NULL);
1513                 g_assert (base);
1514                 if (sre_array->rank == 0) //single dimentional array
1515                         res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
1516                 else
1517                         res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
1518                 sre_array->type.type = res;
1519                 return res;
1520         } else if (is_sre_byref (klass)) {
1521                 MonoType *res;
1522                 MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
1523                 MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type, error);
1524                 return_val_if_nok (error, NULL);
1525                 g_assert (base);
1526                 res = &mono_class_from_mono_type (base)->this_arg;
1527                 sre_byref->type.type = res;
1528                 return res;
1529         } else if (is_sre_pointer (klass)) {
1530                 MonoType *res;
1531                 MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
1532                 MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type, error);
1533                 return_val_if_nok (error, NULL);
1534                 g_assert (base);
1535                 res = &mono_ptr_class_get (base)->byval_arg;
1536                 sre_pointer->type.type = res;
1537                 return res;
1538         } else if (is_sre_generic_instance (klass)) {
1539                 MonoType *res, **types;
1540                 MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
1541                 int i, count;
1542
1543                 count = mono_array_length (gclass->type_arguments);
1544                 types = g_new0 (MonoType*, count);
1545                 for (i = 0; i < count; ++i) {
1546                         MonoReflectionType *t = (MonoReflectionType *)mono_array_get (gclass->type_arguments, gpointer, i);
1547                         types [i] = mono_reflection_type_get_handle (t, error);
1548                         if (!types[i] || !is_ok (error)) {
1549                                 g_free (types);
1550                                 return NULL;
1551                         }
1552                 }
1553                 /* Need to resolve the generic_type in order for it to create its generic context. */
1554                 MonoType *gtd = mono_reflection_type_get_handle (gclass->generic_type, error);
1555                 if (!is_ok (error)) {
1556                         g_free (types);
1557                         return NULL;
1558                 }
1559                 MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
1560                 if (is_sre_type_builder (mono_object_class (gclass->generic_type))) {
1561                         reflection_create_generic_class ((MonoReflectionTypeBuilder*)gclass->generic_type, error);
1562                         if (!is_ok (error)) {
1563                                 g_free (types);
1564                                 return NULL;
1565                         }
1566                 }
1567                 g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1568                 res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error);
1569                 g_free (types);
1570                 g_assert (res);
1571                 gclass->type.type = res;
1572                 return res;
1573         } else if (is_sre_gparam_builder (klass)) {
1574                 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)ref;
1575                 MonoGenericParamFull *param;
1576                 MonoImage *image;
1577                 MonoClass *pklass;
1578
1579                 image = &gparam->tbuilder->module->dynamic_image->image;
1580
1581                 param = mono_image_new0 (image, MonoGenericParamFull, 1);
1582
1583                 param->info.name = mono_string_to_utf8_image (image, gparam->name, error);
1584                 mono_error_assert_ok (error);
1585                 param->param.num = gparam->index;
1586
1587                 if (gparam->mbuilder) {
1588                         if (!gparam->mbuilder->generic_container) {
1589                                 gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1590                                 gparam->mbuilder->generic_container->is_method = TRUE;
1591                                 /*
1592                                  * Cannot set owner.method, since the MonoMethod is not created yet.
1593                                  * Set the image field instead, so type_in_image () works.
1594                                  */
1595                                 gparam->mbuilder->generic_container->is_anonymous = TRUE;
1596                                 gparam->mbuilder->generic_container->owner.image = image;
1597                         }
1598                         param->param.owner = gparam->mbuilder->generic_container;
1599                 } else if (gparam->tbuilder) {
1600                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)(gparam->tbuilder), error);
1601                         mono_error_assert_ok (error);
1602                         MonoClass *owner = mono_class_from_mono_type (type);
1603                         g_assert (mono_class_is_gtd (owner));
1604                         param->param.owner = mono_class_get_generic_container (owner);
1605                 }
1606
1607                 pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1608
1609                 gparam->type.type = &pklass->byval_arg;
1610
1611                 mono_class_set_ref_info (pklass, gparam);
1612                 mono_image_append_class_to_reflection_info_set (pklass);
1613
1614                 return &pklass->byval_arg;
1615         } else if (is_sre_enum_builder (klass)) {
1616                 MonoReflectionEnumBuilder *ebuilder = (MonoReflectionEnumBuilder *)ref;
1617
1618                 return mono_reflection_type_get_handle ((MonoReflectionType*)ebuilder->tb, error);
1619         } else if (is_sre_type_builder (klass)) {
1620                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)ref;
1621
1622                 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1623                 reflection_setup_internal_class (tb, error);
1624                 mono_error_assert_ok (error);
1625                 g_assert (ref->type);
1626                 return ref->type;
1627         }
1628
1629         g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1630         return NULL;
1631 }
1632
1633 /**
1634  * LOCKING: Assumes the loader lock is held.
1635  */
1636 static MonoMethodSignature*
1637 parameters_to_signature (MonoImage *image, MonoArray *parameters, MonoError *error) {
1638         MonoMethodSignature *sig;
1639         int count, i;
1640
1641         mono_error_init (error);
1642
1643         count = parameters? mono_array_length (parameters): 0;
1644
1645         sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1646         sig->param_count = count;
1647         sig->sentinelpos = -1; /* FIXME */
1648         for (i = 0; i < count; ++i) {
1649                 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1650                 if (!is_ok (error)) {
1651                         image_g_free (image, sig);
1652                         return NULL;
1653                 }
1654         }
1655         return sig;
1656 }
1657
1658 /**
1659  * LOCKING: Assumes the loader lock is held.
1660  */
1661 static MonoMethodSignature*
1662 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor, MonoError *error) {
1663         MonoMethodSignature *sig;
1664
1665         mono_error_init (error);
1666
1667         sig = parameters_to_signature (image, ctor->parameters, error);
1668         return_val_if_nok (error, NULL);
1669         sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1670         sig->ret = &mono_defaults.void_class->byval_arg;
1671         return sig;
1672 }
1673
1674 /**
1675  * LOCKING: Assumes the loader lock is held.
1676  */
1677 static MonoMethodSignature*
1678 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method, MonoError *error) {
1679         MonoMethodSignature *sig;
1680
1681         mono_error_init (error);
1682
1683         sig = parameters_to_signature (image, method->parameters, error);
1684         return_val_if_nok (error, NULL);
1685         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1686         if (method->rtype) {
1687                 sig->ret = mono_reflection_type_get_handle ((MonoReflectionType*)method->rtype, error);
1688                 if (!is_ok (error)) {
1689                         image_g_free (image, sig);
1690                         return NULL;
1691                 }
1692         } else {
1693                 sig->ret = &mono_defaults.void_class->byval_arg;
1694         }
1695         sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
1696         return sig;
1697 }
1698
1699 static MonoMethodSignature*
1700 dynamic_method_to_signature (MonoReflectionDynamicMethod *method, MonoError *error) {
1701         MonoMethodSignature *sig;
1702
1703         mono_error_init (error);
1704
1705         sig = parameters_to_signature (NULL, method->parameters, error);
1706         return_val_if_nok (error, NULL);
1707         sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
1708         if (method->rtype) {
1709                 sig->ret = mono_reflection_type_get_handle (method->rtype, error);
1710                 if (!is_ok (error)) {
1711                         g_free (sig);
1712                         return NULL;
1713                 }
1714         } else {
1715                 sig->ret = &mono_defaults.void_class->byval_arg;
1716         }
1717         sig->generic_param_count = 0;
1718         return sig;
1719 }
1720
1721 static void
1722 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1723 {
1724         mono_error_init (error);
1725         MonoClass *klass = mono_object_class (prop);
1726         if (strcmp (klass->name, "PropertyBuilder") == 0) {
1727                 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1728                 *name = mono_string_to_utf8_checked (pb->name, error);
1729                 return_if_nok (error);
1730                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1731         } else {
1732                 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1733                 *name = g_strdup (p->property->name);
1734                 if (p->property->get)
1735                         *type = mono_method_signature (p->property->get)->ret;
1736                 else
1737                         *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1738         }
1739 }
1740
1741 static void
1742 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1743 {
1744         mono_error_init (error);
1745         MonoClass *klass = mono_object_class (field);
1746         if (strcmp (klass->name, "FieldBuilder") == 0) {
1747                 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1748                 *name = mono_string_to_utf8_checked (fb->name, error);
1749                 return_if_nok (error);
1750                 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1751         } else {
1752                 MonoReflectionField *f = (MonoReflectionField *)field;
1753                 *name = g_strdup (mono_field_get_name (f->field));
1754                 *type = f->field->type;
1755         }
1756 }
1757
1758 #else /* DISABLE_REFLECTION_EMIT */
1759
1760 static gboolean
1761 is_sre_type_builder (MonoClass *klass)
1762 {
1763         return FALSE;
1764 }
1765
1766 static gboolean
1767 is_sre_generic_instance (MonoClass *klass)
1768 {
1769         return FALSE;
1770 }
1771
1772 gboolean
1773 mono_is_sre_ctor_builder (MonoClass *klass)
1774 {
1775         return FALSE;
1776 }
1777
1778 gboolean
1779 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1780 {
1781         return FALSE;
1782 }
1783
1784 gboolean
1785 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1786 {
1787         return FALSE;
1788 }
1789
1790 #endif /* !DISABLE_REFLECTION_EMIT */
1791
1792
1793 static gboolean
1794 is_sr_mono_field (MonoClass *klass)
1795 {
1796         check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1797 }
1798
1799 gboolean
1800 mono_is_sr_mono_property (MonoClass *klass)
1801 {
1802         check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1803 }
1804
1805 static gboolean
1806 is_sr_mono_method (MonoClass *klass)
1807 {
1808         check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1809 }
1810
1811 gboolean
1812 mono_is_sr_mono_cmethod (MonoClass *klass)
1813 {
1814         check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1815 }
1816
1817 gboolean
1818 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1819 {
1820         return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1821 }
1822
1823 gboolean
1824 mono_is_sre_type_builder (MonoClass *klass)
1825 {
1826         return is_sre_type_builder (klass);
1827 }
1828
1829 gboolean
1830 mono_is_sre_generic_instance (MonoClass *klass)
1831 {
1832         return is_sre_generic_instance (klass);
1833 }
1834
1835
1836
1837 /**
1838  * encode_cattr_value:
1839  * Encode a value in a custom attribute stream of bytes.
1840  * The value to encode is either supplied as an object in argument val
1841  * (valuetypes are boxed), or as a pointer to the data in the
1842  * argument argval.
1843  * @type represents the type of the value
1844  * @buffer is the start of the buffer
1845  * @p the current position in the buffer
1846  * @buflen contains the size of the buffer and is used to return the new buffer size
1847  * if this needs to be realloced.
1848  * @retbuffer and @retp return the start and the position of the buffer
1849  * @error set on error.
1850  */
1851 static void
1852 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
1853 {
1854         MonoTypeEnum simple_type;
1855         
1856         mono_error_init (error);
1857         if ((p-buffer) + 10 >= *buflen) {
1858                 char *newbuf;
1859                 *buflen *= 2;
1860                 newbuf = (char *)g_realloc (buffer, *buflen);
1861                 p = newbuf + (p-buffer);
1862                 buffer = newbuf;
1863         }
1864         if (!argval)
1865                 argval = ((char*)arg + sizeof (MonoObject));
1866         simple_type = type->type;
1867 handle_enum:
1868         switch (simple_type) {
1869         case MONO_TYPE_BOOLEAN:
1870         case MONO_TYPE_U1:
1871         case MONO_TYPE_I1:
1872                 *p++ = *argval;
1873                 break;
1874         case MONO_TYPE_CHAR:
1875         case MONO_TYPE_U2:
1876         case MONO_TYPE_I2:
1877                 swap_with_size (p, argval, 2, 1);
1878                 p += 2;
1879                 break;
1880         case MONO_TYPE_U4:
1881         case MONO_TYPE_I4:
1882         case MONO_TYPE_R4:
1883                 swap_with_size (p, argval, 4, 1);
1884                 p += 4;
1885                 break;
1886         case MONO_TYPE_R8:
1887                 swap_with_size (p, argval, 8, 1);
1888                 p += 8;
1889                 break;
1890         case MONO_TYPE_U8:
1891         case MONO_TYPE_I8:
1892                 swap_with_size (p, argval, 8, 1);
1893                 p += 8;
1894                 break;
1895         case MONO_TYPE_VALUETYPE:
1896                 if (type->data.klass->enumtype) {
1897                         simple_type = mono_class_enum_basetype (type->data.klass)->type;
1898                         goto handle_enum;
1899                 } else {
1900                         g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
1901                 }
1902                 break;
1903         case MONO_TYPE_STRING: {
1904                 char *str;
1905                 guint32 slen;
1906                 if (!arg) {
1907                         *p++ = 0xFF;
1908                         break;
1909                 }
1910                 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
1911                 return_if_nok (error);
1912                 slen = strlen (str);
1913                 if ((p-buffer) + 10 + slen >= *buflen) {
1914                         char *newbuf;
1915                         *buflen *= 2;
1916                         *buflen += slen;
1917                         newbuf = (char *)g_realloc (buffer, *buflen);
1918                         p = newbuf + (p-buffer);
1919                         buffer = newbuf;
1920                 }
1921                 mono_metadata_encode_value (slen, p, &p);
1922                 memcpy (p, str, slen);
1923                 p += slen;
1924                 g_free (str);
1925                 break;
1926         }
1927         case MONO_TYPE_CLASS: {
1928                 char *str;
1929                 guint32 slen;
1930                 MonoType *arg_type;
1931                 if (!arg) {
1932                         *p++ = 0xFF;
1933                         break;
1934                 }
1935 handle_type:
1936                 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
1937                 return_if_nok (error);
1938
1939                 str = type_get_qualified_name (arg_type, NULL);
1940                 slen = strlen (str);
1941                 if ((p-buffer) + 10 + slen >= *buflen) {
1942                         char *newbuf;
1943                         *buflen *= 2;
1944                         *buflen += slen;
1945                         newbuf = (char *)g_realloc (buffer, *buflen);
1946                         p = newbuf + (p-buffer);
1947                         buffer = newbuf;
1948                 }
1949                 mono_metadata_encode_value (slen, p, &p);
1950                 memcpy (p, str, slen);
1951                 p += slen;
1952                 g_free (str);
1953                 break;
1954         }
1955         case MONO_TYPE_SZARRAY: {
1956                 int len, i;
1957                 MonoClass *eclass, *arg_eclass;
1958
1959                 if (!arg) {
1960                         *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
1961                         break;
1962                 }
1963                 len = mono_array_length ((MonoArray*)arg);
1964                 *p++ = len & 0xff;
1965                 *p++ = (len >> 8) & 0xff;
1966                 *p++ = (len >> 16) & 0xff;
1967                 *p++ = (len >> 24) & 0xff;
1968                 *retp = p;
1969                 *retbuffer = buffer;
1970                 eclass = type->data.klass;
1971                 arg_eclass = mono_object_class (arg)->element_class;
1972
1973                 if (!eclass) {
1974                         /* Happens when we are called from the MONO_TYPE_OBJECT case below */
1975                         eclass = mono_defaults.object_class;
1976                 }
1977                 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
1978                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
1979                         int elsize = mono_class_array_element_size (arg_eclass);
1980                         for (i = 0; i < len; ++i) {
1981                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
1982                                 return_if_nok (error);
1983                                 elptr += elsize;
1984                         }
1985                 } else if (eclass->valuetype && arg_eclass->valuetype) {
1986                         char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
1987                         int elsize = mono_class_array_element_size (eclass);
1988                         for (i = 0; i < len; ++i) {
1989                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
1990                                 return_if_nok (error);
1991                                 elptr += elsize;
1992                         }
1993                 } else {
1994                         for (i = 0; i < len; ++i) {
1995                                 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
1996                                 return_if_nok (error);
1997                         }
1998                 }
1999                 break;
2000         }
2001         case MONO_TYPE_OBJECT: {
2002                 MonoClass *klass;
2003                 char *str;
2004                 guint32 slen;
2005
2006                 /*
2007                  * The parameter type is 'object' but the type of the actual
2008                  * argument is not. So we have to add type information to the blob
2009                  * too. This is completely undocumented in the spec.
2010                  */
2011
2012                 if (arg == NULL) {
2013                         *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
2014                         *p++ = 0xFF;
2015                         break;
2016                 }
2017                 
2018                 klass = mono_object_class (arg);
2019
2020                 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2021                         *p++ = 0x50;
2022                         goto handle_type;
2023                 } else {
2024                         return_if_nok (error);
2025                 }
2026
2027                 if (klass->enumtype) {
2028                         *p++ = 0x55;
2029                 } else if (klass == mono_defaults.string_class) {
2030                         simple_type = MONO_TYPE_STRING;
2031                         *p++ = 0x0E;
2032                         goto handle_enum;
2033                 } else if (klass->rank == 1) {
2034                         *p++ = 0x1D;
2035                         if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2036                                 /* See Partition II, Appendix B3 */
2037                                 *p++ = 0x51;
2038                         else
2039                                 *p++ = klass->element_class->byval_arg.type;
2040                         encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2041                         return_if_nok (error);
2042                         break;
2043                 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2044                         *p++ = simple_type = klass->byval_arg.type;
2045                         goto handle_enum;
2046                 } else {
2047                         g_error ("unhandled type in custom attr");
2048                 }
2049                 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2050                 slen = strlen (str);
2051                 if ((p-buffer) + 10 + slen >= *buflen) {
2052                         char *newbuf;
2053                         *buflen *= 2;
2054                         *buflen += slen;
2055                         newbuf = (char *)g_realloc (buffer, *buflen);
2056                         p = newbuf + (p-buffer);
2057                         buffer = newbuf;
2058                 }
2059                 mono_metadata_encode_value (slen, p, &p);
2060                 memcpy (p, str, slen);
2061                 p += slen;
2062                 g_free (str);
2063                 simple_type = mono_class_enum_basetype (klass)->type;
2064                 goto handle_enum;
2065         }
2066         default:
2067                 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2068         }
2069         *retp = p;
2070         *retbuffer = buffer;
2071 }
2072
2073 static void
2074 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2075 {
2076         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2077                 char *str = type_get_qualified_name (type, NULL);
2078                 int slen = strlen (str);
2079
2080                 *p++ = 0x55;
2081                 /*
2082                  * This seems to be optional...
2083                  * *p++ = 0x80;
2084                  */
2085                 mono_metadata_encode_value (slen, p, &p);
2086                 memcpy (p, str, slen);
2087                 p += slen;
2088                 g_free (str);
2089         } else if (type->type == MONO_TYPE_OBJECT) {
2090                 *p++ = 0x51;
2091         } else if (type->type == MONO_TYPE_CLASS) {
2092                 /* it should be a type: encode_cattr_value () has the check */
2093                 *p++ = 0x50;
2094         } else {
2095                 mono_metadata_encode_value (type->type, p, &p);
2096                 if (type->type == MONO_TYPE_SZARRAY)
2097                         /* See the examples in Partition VI, Annex B */
2098                         encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2099         }
2100
2101         *retp = p;
2102 }
2103
2104 #ifndef DISABLE_REFLECTION_EMIT
2105 static void
2106 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2107 {
2108         int len;
2109
2110         mono_error_init (error);
2111
2112         /* Preallocate a large enough buffer */
2113         if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2114                 char *str = type_get_qualified_name (type, NULL);
2115                 len = strlen (str);
2116                 g_free (str);
2117         } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2118                 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2119                 len = strlen (str);
2120                 g_free (str);
2121         } else {
2122                 len = 0;
2123         }
2124         len += strlen (name);
2125
2126         if ((p-buffer) + 20 + len >= *buflen) {
2127                 char *newbuf;
2128                 *buflen *= 2;
2129                 *buflen += len;
2130                 newbuf = (char *)g_realloc (buffer, *buflen);
2131                 p = newbuf + (p-buffer);
2132                 buffer = newbuf;
2133         }
2134
2135         encode_field_or_prop_type (type, p, &p);
2136
2137         len = strlen (name);
2138         mono_metadata_encode_value (len, p, &p);
2139         memcpy (p, name, len);
2140         p += len;
2141         encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2142         return_if_nok (error);
2143         *retp = p;
2144         *retbuffer = buffer;
2145 }
2146
2147 /**
2148  * mono_reflection_get_custom_attrs_blob:
2149  * @ctor: custom attribute constructor
2150  * @ctorArgs: arguments o the constructor
2151  * @properties:
2152  * @propValues:
2153  * @fields:
2154  * @fieldValues:
2155  * 
2156  * Creates the blob of data that needs to be saved in the metadata and that represents
2157  * the custom attributed described by @ctor, @ctorArgs etc.
2158  * Returns: a Byte array representing the blob of data.
2159  */
2160 MonoArray*
2161 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
2162 {
2163         MonoError error;
2164         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2165         mono_error_cleanup (&error);
2166         return result;
2167 }
2168
2169 /**
2170  * mono_reflection_get_custom_attrs_blob_checked:
2171  * @ctor: custom attribute constructor
2172  * @ctorArgs: arguments o the constructor
2173  * @properties:
2174  * @propValues:
2175  * @fields:
2176  * @fieldValues:
2177  * @error: set on error
2178  * 
2179  * Creates the blob of data that needs to be saved in the metadata and that represents
2180  * the custom attributed described by @ctor, @ctorArgs etc.
2181  * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
2182  */
2183 MonoArray*
2184 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
2185 {
2186         MonoArray *result = NULL;
2187         MonoMethodSignature *sig;
2188         MonoObject *arg;
2189         char *buffer, *p;
2190         guint32 buflen, i;
2191
2192         mono_error_init (error);
2193
2194         if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2195                 /* sig is freed later so allocate it in the heap */
2196                 sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor, error);
2197                 if (!is_ok (error)) {
2198                         g_free (sig);
2199                         return NULL;
2200                 }
2201         } else {
2202                 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2203         }
2204
2205         g_assert (mono_array_length (ctorArgs) == sig->param_count);
2206         buflen = 256;
2207         p = buffer = (char *)g_malloc (buflen);
2208         /* write the prolog */
2209         *p++ = 1;
2210         *p++ = 0;
2211         for (i = 0; i < sig->param_count; ++i) {
2212                 arg = mono_array_get (ctorArgs, MonoObject*, i);
2213                 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2214                 if (!is_ok (error)) goto leave;
2215         }
2216         i = 0;
2217         if (properties)
2218                 i += mono_array_length (properties);
2219         if (fields)
2220                 i += mono_array_length (fields);
2221         *p++ = i & 0xff;
2222         *p++ = (i >> 8) & 0xff;
2223         if (properties) {
2224                 MonoObject *prop;
2225                 for (i = 0; i < mono_array_length (properties); ++i) {
2226                         MonoType *ptype;
2227                         char *pname;
2228
2229                         prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2230                         get_prop_name_and_type (prop, &pname, &ptype, error);
2231                         if (!is_ok (error)) goto leave;
2232                         *p++ = 0x54; /* PROPERTY signature */
2233                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2234                         g_free (pname);
2235                         if (!is_ok (error)) goto leave;
2236                 }
2237         }
2238
2239         if (fields) {
2240                 MonoObject *field;
2241                 for (i = 0; i < mono_array_length (fields); ++i) {
2242                         MonoType *ftype;
2243                         char *fname;
2244
2245                         field = (MonoObject *)mono_array_get (fields, gpointer, i);
2246                         get_field_name_and_type (field, &fname, &ftype, error);
2247                         if (!is_ok (error)) goto leave;
2248                         *p++ = 0x53; /* FIELD signature */
2249                         encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2250                         g_free (fname);
2251                         if (!is_ok (error)) goto leave;
2252                 }
2253         }
2254
2255         g_assert (p - buffer <= buflen);
2256         buflen = p - buffer;
2257         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2258         if (!is_ok (error))
2259                 goto leave;
2260         p = mono_array_addr (result, char, 0);
2261         memcpy (p, buffer, buflen);
2262 leave:
2263         g_free (buffer);
2264         if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2265                 g_free (sig);
2266         return result;
2267 }
2268
2269 /**
2270  * reflection_setup_internal_class:
2271  * @tb: a TypeBuilder object
2272  * @error: set on error
2273  *
2274  * Creates a MonoClass that represents the TypeBuilder.
2275  * This is a trick that lets us simplify a lot of reflection code
2276  * (and will allow us to support Build and Run assemblies easier).
2277  *
2278  * Returns TRUE on success. On failure, returns FALSE and sets @error.
2279  */
2280 static gboolean
2281 reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2282 {
2283         MonoClass *klass, *parent;
2284
2285         mono_error_init (error);
2286
2287         mono_loader_lock ();
2288
2289         if (tb->parent) {
2290                 MonoType *parent_type = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent, error);
2291                 if (!is_ok (error)) {
2292                         mono_loader_unlock ();
2293                         return FALSE;
2294                 }
2295                 /* check so we can compile corlib correctly */
2296                 if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
2297                         /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2298                         parent = parent_type->data.klass;
2299                 } else {
2300                         parent = mono_class_from_mono_type (parent_type);
2301                 }
2302         } else {
2303                 parent = NULL;
2304         }
2305         
2306         /* the type has already being created: it means we just have to change the parent */
2307         if (tb->type.type) {
2308                 klass = mono_class_from_mono_type (tb->type.type);
2309                 klass->parent = NULL;
2310                 /* fool mono_class_setup_parent */
2311                 klass->supertypes = NULL;
2312                 mono_class_setup_parent (klass, parent);
2313                 mono_class_setup_mono_type (klass);
2314                 mono_loader_unlock ();
2315                 return TRUE;
2316         }
2317
2318         /*
2319          * The size calculation here warrants some explaining. 
2320          * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2321          * meaning we need to alloc enough space to morth a def into a gtd.
2322          */
2323         klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2324         klass->class_kind = MONO_CLASS_DEF;
2325
2326         klass->image = &tb->module->dynamic_image->image;
2327
2328         klass->inited = 1; /* we lie to the runtime */
2329         klass->name = mono_string_to_utf8_image (klass->image, tb->name, error);
2330         if (!is_ok (error))
2331                 goto failure;
2332         klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, error);
2333         if (!is_ok (error))
2334                 goto failure;
2335         klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
2336         mono_class_set_flags (klass, tb->attrs);
2337         
2338         mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
2339
2340         klass->element_class = klass;
2341
2342         if (mono_class_get_ref_info (klass) == NULL) {
2343                 mono_class_set_ref_info (klass, tb);
2344
2345                 /* Put into cache so mono_class_get_checked () will find it.
2346                 Skip nested types as those should not be available on the global scope. */
2347                 if (!tb->nesting_type)
2348                         mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
2349
2350                 /*
2351                 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2352                 by performing a mono_class_get which does the full resolution.
2353
2354                 Working around this semantics would require us to write a lot of code for no clear advantage.
2355                 */
2356                 mono_image_append_class_to_reflection_info_set (klass);
2357         } else {
2358                 g_assert (mono_class_get_ref_info (klass) == tb);
2359         }
2360
2361         mono_dynamic_image_register_token (tb->module->dynamic_image, MONO_TOKEN_TYPE_DEF | tb->table_idx, (MonoObject*)tb);
2362
2363         if (parent != NULL) {
2364                 mono_class_setup_parent (klass, parent);
2365         } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
2366                 const char *old_n = klass->name;
2367                 /* trick to get relative numbering right when compiling corlib */
2368                 klass->name = "BuildingObject";
2369                 mono_class_setup_parent (klass, mono_defaults.object_class);
2370                 klass->name = old_n;
2371         }
2372
2373         if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2374                         (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2375                         (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2376                 klass->instance_size = sizeof (MonoObject);
2377                 klass->size_inited = 1;
2378                 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2379         }
2380
2381         mono_class_setup_mono_type (klass);
2382
2383         mono_class_setup_supertypes (klass);
2384
2385         /*
2386          * FIXME: handle interfaces.
2387          */
2388
2389         tb->type.type = &klass->byval_arg;
2390
2391         if (tb->nesting_type) {
2392                 reflection_setup_internal_class ((MonoReflectionTypeBuilder*)tb->nesting_type, error);
2393                 g_assert (tb->nesting_type->type);
2394                 MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
2395                 if (!is_ok (error)) goto failure;
2396                 klass->nested_in = mono_class_from_mono_type (nesting_type);
2397         }
2398
2399         /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2400
2401         mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
2402         
2403         mono_loader_unlock ();
2404         return TRUE;
2405
2406 failure:
2407         mono_loader_unlock ();
2408         return FALSE;
2409 }
2410
2411 /**
2412  * reflection_create_generic_class:
2413  * @tb: a TypeBuilder object
2414  * @error: set on error
2415  *
2416  * Creates the generic class after all generic parameters have been added.
2417  * On success returns TRUE, on failure returns FALSE and sets @error.
2418  */
2419 static gboolean
2420 reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
2421 {
2422         MonoClass *klass;
2423         int count, i;
2424
2425         mono_error_init (error);
2426
2427         reflection_setup_internal_class (tb, error);
2428         return_val_if_nok (error, FALSE);
2429
2430         klass = mono_class_from_mono_type (tb->type.type);
2431
2432         count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
2433
2434         if (count == 0)
2435                 return TRUE;
2436
2437         if (mono_class_try_get_generic_container (klass) != NULL)
2438                 return TRUE; /* already setup */
2439
2440         MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2441
2442         generic_container->owner.klass = klass;
2443         generic_container->type_argc = count;
2444         generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2445
2446         klass->class_kind = MONO_CLASS_GTD;
2447         mono_class_set_generic_container (klass, generic_container);
2448
2449
2450         for (i = 0; i < count; i++) {
2451                 MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
2452                 MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
2453                 return_val_if_nok (error, FALSE);
2454                 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2455                 generic_container->type_params [i] = *param;
2456                 /*Make sure we are a diferent type instance */
2457                 generic_container->type_params [i].param.owner = generic_container;
2458                 generic_container->type_params [i].info.pklass = NULL;
2459                 generic_container->type_params [i].info.flags = gparam->attrs;
2460
2461                 g_assert (generic_container->type_params [i].param.owner);
2462         }
2463
2464         generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2465         return TRUE;
2466 }
2467
2468 static MonoMarshalSpec*
2469 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2470                                 MonoReflectionMarshal *minfo, MonoError *error)
2471 {
2472         MonoMarshalSpec *res;
2473
2474         mono_error_init (error);
2475
2476         res = image_g_new0 (image, MonoMarshalSpec, 1);
2477         res->native = (MonoMarshalNative)minfo->type;
2478
2479         switch (minfo->type) {
2480         case MONO_NATIVE_LPARRAY:
2481                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2482                 if (minfo->has_size) {
2483                         res->data.array_data.param_num = minfo->param_num;
2484                         res->data.array_data.num_elem = minfo->count;
2485                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2486                 }
2487                 else {
2488                         res->data.array_data.param_num = -1;
2489                         res->data.array_data.num_elem = -1;
2490                         res->data.array_data.elem_mult = -1;
2491                 }
2492                 break;
2493
2494         case MONO_NATIVE_BYVALTSTR:
2495         case MONO_NATIVE_BYVALARRAY:
2496                 res->data.array_data.num_elem = minfo->count;
2497                 break;
2498
2499         case MONO_NATIVE_CUSTOM:
2500                 if (minfo->marshaltyperef) {
2501                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2502                         if (!is_ok (error)) {
2503                                 image_g_free (image, res);
2504                                 return NULL;
2505                         }
2506                         res->data.custom_data.custom_name =
2507                                 type_get_fully_qualified_name (marshaltyperef);
2508                 }
2509                 if (minfo->mcookie) {
2510                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2511                         if (!is_ok (error)) {
2512                                 image_g_free (image, res);
2513                                 return NULL;
2514                         }
2515                 }
2516                 break;
2517
2518         default:
2519                 break;
2520         }
2521
2522         return res;
2523 }
2524 #endif /* !DISABLE_REFLECTION_EMIT */
2525
2526 MonoReflectionMarshalAsAttribute*
2527 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2528                                                         MonoMarshalSpec *spec, MonoError *error)
2529 {
2530         MonoReflectionType *rt;
2531         MonoReflectionMarshalAsAttribute *minfo;
2532         MonoType *mtype;
2533
2534         mono_error_init (error);
2535         
2536         minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error);
2537         if (!minfo)
2538                 return NULL;
2539         minfo->utype = spec->native;
2540
2541         switch (minfo->utype) {
2542         case MONO_NATIVE_LPARRAY:
2543                 minfo->array_subtype = spec->data.array_data.elem_type;
2544                 minfo->size_const = spec->data.array_data.num_elem;
2545                 if (spec->data.array_data.param_num != -1)
2546                         minfo->size_param_index = spec->data.array_data.param_num;
2547                 break;
2548
2549         case MONO_NATIVE_BYVALTSTR:
2550         case MONO_NATIVE_BYVALARRAY:
2551                 minfo->size_const = spec->data.array_data.num_elem;
2552                 break;
2553
2554         case MONO_NATIVE_CUSTOM:
2555                 if (spec->data.custom_data.custom_name) {
2556                         mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2557                         return_val_if_nok  (error, NULL);
2558
2559                         if (mtype) {
2560                                 rt = mono_type_get_object_checked (domain, mtype, error);
2561                                 if (!rt)
2562                                         return NULL;
2563
2564                                 MONO_OBJECT_SETREF (minfo, marshal_type_ref, rt);
2565                         }
2566
2567                         MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
2568                 }
2569                 if (spec->data.custom_data.cookie)
2570                         MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
2571                 break;
2572
2573         default:
2574                 break;
2575         }
2576
2577         return minfo;
2578 }
2579
2580 #ifndef DISABLE_REFLECTION_EMIT
2581 static MonoMethod*
2582 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2583                                          ReflectionMethodBuilder *rmb,
2584                                          MonoMethodSignature *sig,
2585                                          MonoError *error)
2586 {
2587         MonoMethod *m;
2588         MonoMethodWrapper *wrapperm;
2589         MonoMarshalSpec **specs;
2590         MonoReflectionMethodAux *method_aux;
2591         MonoImage *image;
2592         gboolean dynamic;
2593         int i;
2594
2595         mono_error_init (error);
2596         /*
2597          * Methods created using a MethodBuilder should have their memory allocated
2598          * inside the image mempool, while dynamic methods should have their memory
2599          * malloc'd.
2600          */
2601         dynamic = rmb->refs != NULL;
2602         image = dynamic ? NULL : klass->image;
2603
2604         if (!dynamic)
2605                 g_assert (!mono_class_is_ginst (klass));
2606
2607         mono_loader_lock ();
2608
2609         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2610                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2611                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2612         else
2613                 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
2614
2615         wrapperm = (MonoMethodWrapper*)m;
2616
2617         m->dynamic = dynamic;
2618         m->slot = -1;
2619         m->flags = rmb->attrs;
2620         m->iflags = rmb->iattrs;
2621         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2622         m->klass = klass;
2623         m->signature = sig;
2624         m->sre_method = TRUE;
2625         m->skip_visibility = rmb->skip_visibility;
2626         if (rmb->table_idx)
2627                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2628
2629         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2630                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2631                         m->string_ctor = 1;
2632
2633                 m->signature->pinvoke = 1;
2634         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2635                 m->signature->pinvoke = 1;
2636
2637                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2638
2639                 method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, error) : image_strdup (image, m->name);
2640                 mono_error_assert_ok (error);
2641                 method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, error);
2642                 mono_error_assert_ok (error);
2643                 
2644                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2645
2646                 if (image_is_dynamic (klass->image))
2647                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2648
2649                 mono_loader_unlock ();
2650
2651                 return m;
2652         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2653                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2654                 MonoMethodHeader *header;
2655                 guint32 code_size;
2656                 gint32 max_stack, i;
2657                 gint32 num_locals = 0;
2658                 gint32 num_clauses = 0;
2659                 guint8 *code;
2660
2661                 if (rmb->ilgen) {
2662                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2663                         code_size = rmb->ilgen->code_len;
2664                         max_stack = rmb->ilgen->max_stack;
2665                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2666                         if (rmb->ilgen->ex_handlers)
2667                                 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2668                 } else {
2669                         if (rmb->code) {
2670                                 code = mono_array_addr (rmb->code, guint8, 0);
2671                                 code_size = mono_array_length (rmb->code);
2672                                 /* we probably need to run a verifier on the code... */
2673                                 max_stack = 8; 
2674                         }
2675                         else {
2676                                 code = NULL;
2677                                 code_size = 0;
2678                                 max_stack = 8;
2679                         }
2680                 }
2681
2682                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2683                 header->code_size = code_size;
2684                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2685                 memcpy ((char*)header->code, code, code_size);
2686                 header->max_stack = max_stack;
2687                 header->init_locals = rmb->init_locals;
2688                 header->num_locals = num_locals;
2689
2690                 for (i = 0; i < num_locals; ++i) {
2691                         MonoReflectionLocalBuilder *lb = 
2692                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2693
2694                         header->locals [i] = image_g_new0 (image, MonoType, 1);
2695                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2696                         mono_error_assert_ok (error);
2697                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2698                 }
2699
2700                 header->num_clauses = num_clauses;
2701                 if (num_clauses) {
2702                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2703                                                                  rmb->ilgen, num_clauses, error);
2704                         mono_error_assert_ok (error);
2705                 }
2706
2707                 wrapperm->header = header;
2708         }
2709
2710         if (rmb->generic_params) {
2711                 int count = mono_array_length (rmb->generic_params);
2712                 MonoGenericContainer *container;
2713
2714                 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2715                 container->is_method = TRUE;
2716                 container->is_anonymous = FALSE;
2717                 container->type_argc = count;
2718                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2719                 container->owner.method = m;
2720
2721                 m->is_generic = TRUE;
2722                 mono_method_set_generic_container (m, container);
2723
2724                 for (i = 0; i < count; i++) {
2725                         MonoReflectionGenericParam *gp =
2726                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2727                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2728                         mono_error_assert_ok (error);
2729                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2730                         container->type_params [i] = *param;
2731                         container->type_params [i].param.owner = container;
2732
2733                         gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2734
2735                         MonoClass *gklass = mono_class_from_mono_type (gp_type);
2736                         gklass->wastypebuilder = TRUE;
2737                 }
2738
2739                 /*
2740                  * The method signature might have pointers to generic parameters that belong to other methods.
2741                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2742                  * generic parameters.
2743                  */
2744                 for (i = 0; i < m->signature->param_count; ++i) {
2745                         MonoType *t = m->signature->params [i];
2746                         if (t->type == MONO_TYPE_MVAR) {
2747                                 MonoGenericParam *gparam =  t->data.generic_param;
2748                                 if (gparam->num < count) {
2749                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2750                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2751                                 }
2752
2753                         }
2754                 }
2755
2756                 if (mono_class_is_gtd (klass)) {
2757                         container->parent = mono_class_get_generic_container (klass);
2758                         container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2759                 }
2760                 container->context.method_inst = mono_get_shared_generic_inst (container);
2761         }
2762
2763         if (rmb->refs) {
2764                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2765                 int i;
2766                 void **data;
2767
2768                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2769
2770                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2771                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2772                 for (i = 0; i < rmb->nrefs; ++i)
2773                         data [i + 1] = rmb->refs [i];
2774         }
2775
2776         method_aux = NULL;
2777
2778         /* Parameter info */
2779         if (rmb->pinfo) {
2780                 if (!method_aux)
2781                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2782                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2783                 for (i = 0; i <= m->signature->param_count; ++i) {
2784                         MonoReflectionParamBuilder *pb;
2785                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2786                                 if ((i > 0) && (pb->attrs)) {
2787                                         /* Make a copy since it might point to a shared type structure */
2788                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2789                                         m->signature->params [i - 1]->attrs = pb->attrs;
2790                                 }
2791
2792                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2793                                         MonoDynamicImage *assembly;
2794                                         guint32 idx, len;
2795                                         MonoTypeEnum def_type;
2796                                         char *p;
2797                                         const char *p2;
2798
2799                                         if (!method_aux->param_defaults) {
2800                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2801                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2802                                         }
2803                                         assembly = (MonoDynamicImage*)klass->image;
2804                                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
2805                                         /* Copy the data from the blob since it might get realloc-ed */
2806                                         p = assembly->blob.data + idx;
2807                                         len = mono_metadata_decode_blob_size (p, &p2);
2808                                         len += p2 - p;
2809                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
2810                                         method_aux->param_default_types [i] = def_type;
2811                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
2812                                 }
2813
2814                                 if (pb->name) {
2815                                         method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, error);
2816                                         mono_error_assert_ok (error);
2817                                 }
2818                                 if (pb->cattrs) {
2819                                         if (!method_aux->param_cattr)
2820                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
2821                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
2822                                 }
2823                         }
2824                 }
2825         }
2826
2827         /* Parameter marshalling */
2828         specs = NULL;
2829         if (rmb->pinfo)         
2830                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
2831                         MonoReflectionParamBuilder *pb;
2832                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2833                                 if (pb->marshal_info) {
2834                                         if (specs == NULL)
2835                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
2836                                         specs [pb->position] = 
2837                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
2838                                         if (!is_ok (error)) {
2839                                                 mono_loader_unlock ();
2840                                                 image_g_free (image, specs);
2841                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2842                                                 return NULL;
2843                                         }
2844                                 }
2845                         }
2846                 }
2847         if (specs != NULL) {
2848                 if (!method_aux)
2849                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2850                 method_aux->param_marshall = specs;
2851         }
2852
2853         if (image_is_dynamic (klass->image) && method_aux)
2854                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2855
2856         mono_loader_unlock ();
2857
2858         return m;
2859 }       
2860
2861 static MonoMethod*
2862 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
2863 {
2864         ReflectionMethodBuilder rmb;
2865         MonoMethodSignature *sig;
2866
2867         mono_loader_lock ();
2868
2869         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
2870                 return NULL;
2871
2872         g_assert (klass->image != NULL);
2873         sig = ctor_builder_to_signature (klass->image, mb, error);
2874         mono_loader_unlock ();
2875         return_val_if_nok (error, NULL);
2876
2877         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2878         return_val_if_nok (error, NULL);
2879         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2880
2881         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
2882                 /* ilgen is no longer needed */
2883                 mb->ilgen = NULL;
2884         }
2885
2886         return mb->mhandle;
2887 }
2888
2889 static MonoMethod*
2890 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, MonoError *error)
2891 {
2892         ReflectionMethodBuilder rmb;
2893         MonoMethodSignature *sig;
2894
2895         mono_error_init (error);
2896
2897         mono_loader_lock ();
2898
2899         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
2900                 return NULL;
2901
2902         g_assert (klass->image != NULL);
2903         sig = method_builder_to_signature (klass->image, mb, error);
2904         mono_loader_unlock ();
2905         return_val_if_nok (error, NULL);
2906
2907         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
2908         return_val_if_nok (error, NULL);
2909         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
2910
2911         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
2912                 /* ilgen is no longer needed */
2913                 mb->ilgen = NULL;
2914         return mb->mhandle;
2915 }
2916 #endif
2917
2918 #ifndef DISABLE_REFLECTION_EMIT
2919
2920 /**
2921  * fix_partial_generic_class:
2922  * @klass: a generic instantiation MonoClass
2923  * @error: set on error
2924  *
2925  * Assumes that the generic container of @klass has its vtable
2926  * initialized, and updates the parent class, interfaces, methods and
2927  * fields of @klass by inflating the types using the generic context.
2928  *
2929  * On success returns TRUE, on failure returns FALSE and sets @error.
2930  *
2931  */
2932 static gboolean
2933 fix_partial_generic_class (MonoClass *klass, MonoError *error)
2934 {
2935         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
2936         int i;
2937
2938         mono_error_init (error);
2939
2940         if (klass->wastypebuilder)
2941                 return TRUE;
2942
2943         if (klass->parent != gklass->parent) {
2944                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
2945                 if (mono_error_ok (error)) {
2946                         MonoClass *parent = mono_class_from_mono_type (parent_type);
2947                         mono_metadata_free_type (parent_type);
2948                         if (parent != klass->parent) {
2949                                 /*fool mono_class_setup_parent*/
2950                                 klass->supertypes = NULL;
2951                                 mono_class_setup_parent (klass, parent);
2952                         }
2953                 } else {
2954                         if (gklass->wastypebuilder)
2955                                 klass->wastypebuilder = TRUE;
2956                         return FALSE;
2957                 }
2958         }
2959
2960         if (!mono_class_get_generic_class (klass)->need_sync)
2961                 return TRUE;
2962
2963         int mcount = mono_class_get_method_count (klass);
2964         int gmcount = mono_class_get_method_count (gklass);
2965         if (mcount != gmcount) {
2966                 mono_class_set_method_count (klass, gmcount);
2967                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
2968
2969                 for (i = 0; i < gmcount; i++) {
2970                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
2971                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
2972                         mono_error_assert_ok (error);
2973                 }
2974         }
2975
2976         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
2977                 klass->interface_count = gklass->interface_count;
2978                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
2979                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
2980
2981                 for (i = 0; i < gklass->interface_count; ++i) {
2982                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
2983                         return_val_if_nok (error, FALSE);
2984
2985                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
2986                         mono_metadata_free_type (iface_type);
2987
2988                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
2989                                 return FALSE;
2990                 }
2991                 klass->interfaces_inited = 1;
2992         }
2993
2994         int fcount = mono_class_get_field_count (klass);
2995         int gfcount = mono_class_get_field_count (gklass);
2996         if (fcount != gfcount) {
2997                 mono_class_set_field_count (klass, gfcount);
2998                 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
2999
3000                 for (i = 0; i < gfcount; i++) {
3001                         klass->fields [i] = gklass->fields [i];
3002                         klass->fields [i].parent = klass;
3003                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3004                         return_val_if_nok (error, FALSE);
3005                 }
3006         }
3007
3008         /*We can only finish with this klass once it's parent has as well*/
3009         if (gklass->wastypebuilder)
3010                 klass->wastypebuilder = TRUE;
3011         return TRUE;
3012 }
3013
3014 /**
3015  * ensure_generic_class_runtime_vtable:
3016  * @klass a generic class
3017  * @error set on error
3018  *
3019  * Ensures that the generic container of @klass has a vtable and
3020  * returns TRUE on success.  On error returns FALSE and sets @error.
3021  */
3022 static gboolean
3023 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3024 {
3025         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3026
3027         mono_error_init (error);
3028
3029         if (!ensure_runtime_vtable (gklass, error))
3030                 return FALSE;
3031
3032         return fix_partial_generic_class (klass, error);
3033 }
3034
3035 /**
3036  * ensure_runtime_vtable:
3037  * @klass the class
3038  * @error set on error
3039  *
3040  * Ensures that @klass has a vtable and returns TRUE on success. On
3041  * error returns FALSE and sets @error.
3042  */
3043 static gboolean
3044 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3045 {
3046         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3047         int i, num, j;
3048
3049         mono_error_init (error);
3050
3051         if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3052                 return TRUE;
3053         if (klass->parent)
3054                 if (!ensure_runtime_vtable (klass->parent, error))
3055                         return FALSE;
3056
3057         if (tb) {
3058                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3059                 num += tb->num_methods;
3060                 mono_class_set_method_count (klass, num);
3061                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3062                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3063                 for (i = 0; i < num; ++i) {
3064                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3065                         if (!ctor)
3066                                 return FALSE;
3067                         klass->methods [i] = ctor;
3068                 }
3069                 num = tb->num_methods;
3070                 j = i;
3071                 for (i = 0; i < num; ++i) {
3072                         MonoMethod *meth = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error);
3073                         if (!meth)
3074                                 return FALSE;
3075                         klass->methods [j++] = meth;
3076                 }
3077         
3078                 if (tb->interfaces) {
3079                         klass->interface_count = mono_array_length (tb->interfaces);
3080                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3081                         for (i = 0; i < klass->interface_count; ++i) {
3082                                 MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i, error);
3083                                 return_val_if_nok (error, FALSE);
3084                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
3085                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3086                                         return FALSE;
3087                         }
3088                         klass->interfaces_inited = 1;
3089                 }
3090         } else if (mono_class_is_ginst (klass)){
3091                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3092                         mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3093                         return FALSE;
3094                 }
3095         }
3096
3097         if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3098                 int slot_num = 0;
3099                 int mcount = mono_class_get_method_count (klass);
3100                 for (i = 0; i < mcount; ++i) {
3101                         MonoMethod *im = klass->methods [i];
3102                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3103                                 im->slot = slot_num++;
3104                 }
3105                 
3106                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3107                 mono_class_setup_interface_offsets (klass);
3108                 mono_class_setup_interface_id (klass);
3109         }
3110
3111         /*
3112          * The generic vtable is needed even if image->run is not set since some
3113          * runtime code like ves_icall_Type_GetMethodsByName depends on 
3114          * method->slot being defined.
3115          */
3116
3117         /* 
3118          * tb->methods could not be freed since it is used for determining 
3119          * overrides during dynamic vtable construction.
3120          */
3121
3122         return TRUE;
3123 }
3124
3125 static MonoMethod*
3126 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3127 {
3128         mono_error_init (error);
3129         MonoClass *klass = mono_object_class (method);
3130         if (is_sr_mono_method (klass)) {
3131                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3132                 return sr_method->method;
3133         }
3134         if (is_sre_method_builder (klass)) {
3135                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3136                 return mb->mhandle;
3137         }
3138         if (mono_is_sre_method_on_tb_inst (klass)) {
3139                 MonoClass *handle_class;
3140
3141                 MonoMethod *result =  mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3142                 return_val_if_nok (error, NULL);
3143
3144                 return result;
3145         }
3146
3147         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3148         return NULL;
3149 }
3150
3151 void
3152 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3153 {
3154         MonoReflectionTypeBuilder *tb;
3155         int i, j, onum;
3156         MonoReflectionMethod *m;
3157
3158         mono_error_init (error);
3159         *overrides = NULL;
3160         *num_overrides = 0;
3161
3162         g_assert (image_is_dynamic (klass->image));
3163
3164         if (!mono_class_get_ref_info (klass))
3165                 return;
3166
3167         g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
3168
3169         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
3170
3171         onum = 0;
3172         if (tb->methods) {
3173                 for (i = 0; i < tb->num_methods; ++i) {
3174                         MonoReflectionMethodBuilder *mb = 
3175                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3176                         if (mb->override_methods)
3177                                 onum += mono_array_length (mb->override_methods);
3178                 }
3179         }
3180
3181         if (onum) {
3182                 *overrides = g_new0 (MonoMethod*, onum * 2);
3183
3184                 onum = 0;
3185                 for (i = 0; i < tb->num_methods; ++i) {
3186                         MonoReflectionMethodBuilder *mb = 
3187                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3188                         if (mb->override_methods) {
3189                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3190                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3191
3192                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3193                                         return_if_nok (error);
3194                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
3195
3196                                         g_assert (mb->mhandle);
3197
3198                                         onum ++;
3199                                 }
3200                         }
3201                 }
3202         }
3203
3204         *num_overrides = onum;
3205 }
3206
3207 /* This initializes the same data as mono_class_setup_fields () */
3208 static void
3209 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3210 {
3211         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3212         MonoReflectionFieldBuilder *fb;
3213         MonoClassField *field;
3214         MonoFieldDefaultValue *def_values;
3215         MonoImage *image = klass->image;
3216         const char *p, *p2;
3217         int i, instance_size, packing_size = 0;
3218         guint32 len, idx;
3219
3220         if (klass->parent) {
3221                 if (!klass->parent->size_inited)
3222                         mono_class_init (klass->parent);
3223                 instance_size = klass->parent->instance_size;
3224         } else {
3225                 instance_size = sizeof (MonoObject);
3226         }
3227
3228         int fcount = tb->num_fields;
3229         mono_class_set_field_count (klass, fcount);
3230
3231         mono_error_init (error);
3232
3233         if (tb->class_size) {
3234                 packing_size = tb->packing_size;
3235                 instance_size += tb->class_size;
3236         }
3237         
3238         klass->fields = image_g_new0 (image, MonoClassField, fcount);
3239         def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3240         mono_class_set_field_def_values (klass, def_values);
3241         /*
3242         This is, guess what, a hack.
3243         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3244         On the static path no field class is resolved, only types are built. This is the right thing to do
3245         but we suck.
3246         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3247         */
3248         klass->size_inited = 1;
3249
3250         for (i = 0; i < fcount; ++i) {
3251                 MonoArray *rva_data;
3252                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3253                 field = &klass->fields [i];
3254                 field->parent = klass;
3255                 field->name = mono_string_to_utf8_image (image, fb->name, error);
3256                 if (!mono_error_ok (error))
3257                         return;
3258                 if (fb->attrs) {
3259                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3260                         return_if_nok (error);
3261                         field->type = mono_metadata_type_dup (klass->image, type);
3262                         field->type->attrs = fb->attrs;
3263                 } else {
3264                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3265                         return_if_nok (error);
3266                 }
3267
3268                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3269                         char *base = mono_array_addr (rva_data, char, 0);
3270                         size_t size = mono_array_length (rva_data);
3271                         char *data = (char *)mono_image_alloc (klass->image, size);
3272                         memcpy (data, base, size);
3273                         def_values [i].data = data;
3274                 }
3275                 if (fb->offset != -1)
3276                         field->offset = fb->offset;
3277                 fb->handle = field;
3278                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3279
3280                 if (fb->def_value) {
3281                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3282                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3283                         idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3284                         /* Copy the data from the blob since it might get realloc-ed */
3285                         p = assembly->blob.data + idx;
3286                         len = mono_metadata_decode_blob_size (p, &p2);
3287                         len += p2 - p;
3288                         def_values [i].data = (const char *)mono_image_alloc (image, len);
3289                         memcpy ((gpointer)def_values [i].data, p, len);
3290                 }
3291         }
3292
3293         mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3294 }
3295
3296 static void
3297 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3298 {
3299         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3300         MonoReflectionPropertyBuilder *pb;
3301         MonoImage *image = klass->image;
3302         MonoProperty *properties;
3303         MonoClassPropertyInfo *info;
3304         int i;
3305
3306         mono_error_init (error);
3307
3308         info = mono_class_get_property_info (klass);
3309         if (!info) {
3310                 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3311                 mono_class_set_property_info (klass, info);
3312         }
3313
3314         info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3315         info->first = 0;
3316
3317         properties = image_g_new0 (image, MonoProperty, info->count);
3318         info->properties = properties;
3319         for (i = 0; i < info->count; ++i) {
3320                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3321                 properties [i].parent = klass;
3322                 properties [i].attrs = pb->attrs;
3323                 properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
3324                 if (!mono_error_ok (error))
3325                         return;
3326                 if (pb->get_method)
3327                         properties [i].get = pb->get_method->mhandle;
3328                 if (pb->set_method)
3329                         properties [i].set = pb->set_method->mhandle;
3330
3331                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3332                 if (pb->def_value) {
3333                         guint32 len, idx;
3334                         const char *p, *p2;
3335                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3336                         if (!info->def_values)
3337                                 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3338                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3339                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3340                         /* Copy the data from the blob since it might get realloc-ed */
3341                         p = assembly->blob.data + idx;
3342                         len = mono_metadata_decode_blob_size (p, &p2);
3343                         len += p2 - p;
3344                         info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3345                         memcpy ((gpointer)info->def_values [i].data, p, len);
3346                 }
3347         }
3348 }
3349
3350 static void
3351 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3352 {
3353         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3354         MonoReflectionEventBuilder *eb;
3355         MonoImage *image = klass->image;
3356         MonoEvent *events;
3357         MonoClassEventInfo *info;
3358         int i;
3359
3360         mono_error_init (error);
3361
3362         info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3363         mono_class_set_event_info (klass, info);
3364
3365         info->count = tb->events ? mono_array_length (tb->events) : 0;
3366         info->first = 0;
3367
3368         events = image_g_new0 (image, MonoEvent, info->count);
3369         info->events = events;
3370         for (i = 0; i < info->count; ++i) {
3371                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3372                 events [i].parent = klass;
3373                 events [i].attrs = eb->attrs;
3374                 events [i].name = mono_string_to_utf8_image (image, eb->name, error);
3375                 if (!mono_error_ok (error))
3376                         return;
3377                 if (eb->add_method)
3378                         events [i].add = eb->add_method->mhandle;
3379                 if (eb->remove_method)
3380                         events [i].remove = eb->remove_method->mhandle;
3381                 if (eb->raise_method)
3382                         events [i].raise = eb->raise_method->mhandle;
3383
3384 #ifndef MONO_SMALL_CONFIG
3385                 if (eb->other_methods) {
3386                         int j;
3387                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3388                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3389                                 MonoReflectionMethodBuilder *mb = 
3390                                         mono_array_get (eb->other_methods,
3391                                                                         MonoReflectionMethodBuilder*, j);
3392                                 events [i].other [j] = mb->mhandle;
3393                         }
3394                 }
3395 #endif
3396                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3397         }
3398 }
3399
3400 struct remove_instantiations_user_data
3401 {
3402         MonoClass *klass;
3403         MonoError *error;
3404 };
3405
3406 static gboolean
3407 remove_instantiations_of_and_ensure_contents (gpointer key,
3408                                                   gpointer value,
3409                                                   gpointer user_data)
3410 {
3411         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3412         MonoType *type = (MonoType*)key;
3413         MonoClass *klass = data->klass;
3414         gboolean already_failed = !is_ok (data->error);
3415         MonoError lerror;
3416         MonoError *error = already_failed ? &lerror : data->error;
3417
3418         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3419                 MonoClass *inst_klass = mono_class_from_mono_type (type);
3420                 //Ensure it's safe to use it.
3421                 if (!fix_partial_generic_class (inst_klass, error)) {
3422                         mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3423                         // Marked the class with failure, but since some other instantiation already failed,
3424                         // just report that one, and swallow the error from this one.
3425                         if (already_failed)
3426                                 mono_error_cleanup (error);
3427                 }
3428                 return TRUE;
3429         } else
3430                 return FALSE;
3431 }
3432
3433 MonoReflectionType*
3434 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
3435 {
3436         MonoError error;
3437         MonoClass *klass;
3438         MonoDomain* domain;
3439         MonoReflectionType* res;
3440         int i;
3441
3442         mono_error_init (&error);
3443
3444         reflection_create_generic_class (tb, &error);
3445         mono_error_assert_ok (&error);
3446
3447         domain = mono_object_domain (tb);
3448         klass = mono_class_from_mono_type (tb->type.type);
3449
3450         mono_save_custom_attrs (klass->image, klass, tb->cattrs);
3451
3452         /* 
3453          * we need to lock the domain because the lock will be taken inside
3454          * So, we need to keep the locking order correct.
3455          */
3456         mono_loader_lock ();
3457         mono_domain_lock (domain);
3458         if (klass->wastypebuilder) {
3459                 mono_domain_unlock (domain);
3460                 mono_loader_unlock ();
3461
3462                 res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3463                 mono_error_set_pending_exception (&error);
3464
3465                 return res;
3466         }
3467         /*
3468          * Fields to set in klass:
3469          * the various flags: delegate/unicode/contextbound etc.
3470          */
3471         mono_class_set_flags (klass, tb->attrs);
3472         klass->has_cctor = 1;
3473
3474         mono_class_setup_parent (klass, klass->parent);
3475         /* fool mono_class_setup_supertypes */
3476         klass->supertypes = NULL;
3477         mono_class_setup_supertypes (klass);
3478         mono_class_setup_mono_type (klass);
3479
3480         /* enums are done right away */
3481         if (!klass->enumtype)
3482                 if (!ensure_runtime_vtable (klass, &error))
3483                         goto failure;
3484
3485         if (tb->subtypes) {
3486                 GList *nested = NULL;
3487                 for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
3488                         MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
3489
3490                         if (!subtb->type.type) {
3491                                 reflection_setup_internal_class (subtb, &error);
3492                                 mono_error_assert_ok (&error);
3493                         }
3494
3495                         MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
3496                         if (!is_ok (&error)) goto failure;
3497                         nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3498                 }
3499                 mono_class_set_nested_classes_property (klass, nested);
3500         }
3501
3502         klass->nested_classes_inited = TRUE;
3503
3504         typebuilder_setup_fields (klass, &error);
3505         if (!mono_error_ok (&error))
3506                 goto failure;
3507         typebuilder_setup_properties (klass, &error);
3508         if (!mono_error_ok (&error))
3509                 goto failure;
3510
3511         typebuilder_setup_events (klass, &error);
3512         if (!mono_error_ok (&error))
3513                 goto failure;
3514
3515         klass->wastypebuilder = TRUE;
3516
3517         if (tb->generic_params) {
3518                 for (i = 0; i < mono_array_length (tb->generic_params); i++) {
3519                         MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
3520                         MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error);
3521                         MonoClass *gklass = mono_class_from_mono_type (param_type);
3522
3523                         gklass->wastypebuilder = TRUE;
3524                 }
3525         }
3526
3527         /* 
3528          * If we are a generic TypeBuilder, there might be instantiations in the type cache
3529          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
3530          * we want to return normal System.MonoType objects, so clear these out from the cache.
3531          *
3532          * Together with this we must ensure the contents of all instances to match the created type.
3533          */
3534         if (domain->type_hash && mono_class_is_gtd (klass)) {
3535                 struct remove_instantiations_user_data data;
3536                 data.klass = klass;
3537                 data.error = &error;
3538                 mono_error_assert_ok (&error);
3539                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3540                 if (!is_ok (&error))
3541                         goto failure;
3542         }
3543
3544         mono_domain_unlock (domain);
3545         mono_loader_unlock ();
3546
3547         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3548                 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3549                 mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
3550                 goto failure_unlocked;
3551         }
3552
3553         res = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
3554         if (!is_ok (&error))
3555                 goto failure_unlocked;
3556
3557         g_assert (res != (MonoReflectionType*)tb);
3558
3559         return res;
3560
3561 failure:
3562         mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
3563         klass->wastypebuilder = TRUE;
3564         mono_domain_unlock (domain);
3565         mono_loader_unlock ();
3566 failure_unlocked:
3567         mono_error_set_pending_exception (&error);
3568         return NULL;
3569 }
3570
3571 typedef struct {
3572         MonoMethod *handle;
3573         MonoDomain *domain;
3574 } DynamicMethodReleaseData;
3575
3576 /*
3577  * The runtime automatically clean up those after finalization.
3578 */      
3579 static MonoReferenceQueue *dynamic_method_queue;
3580
3581 static void
3582 free_dynamic_method (void *dynamic_method)
3583 {
3584         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3585         MonoDomain *domain = data->domain;
3586         MonoMethod *method = data->handle;
3587         guint32 dis_link;
3588
3589         mono_domain_lock (domain);
3590         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3591         g_hash_table_remove (domain->method_to_dyn_method, method);
3592         mono_domain_unlock (domain);
3593         g_assert (dis_link);
3594         mono_gchandle_free (dis_link);
3595
3596         mono_runtime_free_method (domain, method);
3597         g_free (data);
3598 }
3599
3600 static gboolean
3601 reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb, MonoError *error)
3602 {
3603         MonoReferenceQueue *queue;
3604         MonoMethod *handle;
3605         DynamicMethodReleaseData *release_data;
3606         ReflectionMethodBuilder rmb;
3607         MonoMethodSignature *sig;
3608         MonoClass *klass;
3609         MonoDomain *domain;
3610         GSList *l;
3611         int i;
3612
3613         mono_error_init (error);
3614
3615         if (mono_runtime_is_shutting_down ()) {
3616                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3617                 return FALSE;
3618         }
3619
3620         if (!(queue = dynamic_method_queue)) {
3621                 mono_loader_lock ();
3622                 if (!(queue = dynamic_method_queue))
3623                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3624                 mono_loader_unlock ();
3625         }
3626
3627         sig = dynamic_method_to_signature (mb, error);
3628         return_val_if_nok (error, FALSE);
3629
3630         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3631
3632         /*
3633          * Resolve references.
3634          */
3635         /* 
3636          * Every second entry in the refs array is reserved for storing handle_class,
3637          * which is needed by the ldtoken implementation in the JIT.
3638          */
3639         rmb.nrefs = mb->nrefs;
3640         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3641         for (i = 0; i < mb->nrefs; i += 2) {
3642                 MonoClass *handle_class;
3643                 gpointer ref;
3644                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3645
3646                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3647                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3648                         /*
3649                          * The referenced DynamicMethod should already be created by the managed
3650                          * code, except in the case of circular references. In that case, we store
3651                          * method in the refs array, and fix it up later when the referenced 
3652                          * DynamicMethod is created.
3653                          */
3654                         if (method->mhandle) {
3655                                 ref = method->mhandle;
3656                         } else {
3657                                 /* FIXME: GC object stored in unmanaged memory */
3658                                 ref = method;
3659
3660                                 /* FIXME: GC object stored in unmanaged memory */
3661                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
3662                         }
3663                         handle_class = mono_defaults.methodhandle_class;
3664                 } else {
3665                         MonoException *ex = NULL;
3666                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3667                         if (!is_ok  (error)) {
3668                                 g_free (rmb.refs);
3669                                 return FALSE;
3670                         }
3671                         if (!ref)
3672                                 ex = mono_get_exception_type_load (NULL, NULL);
3673                         else if (mono_security_core_clr_enabled ())
3674                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3675
3676                         if (ex) {
3677                                 g_free (rmb.refs);
3678                                 mono_error_set_exception_instance (error, ex);
3679                                 return FALSE;
3680                         }
3681                 }
3682
3683                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3684                 rmb.refs [i + 1] = handle_class;
3685         }               
3686
3687         if (mb->owner) {
3688                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3689                 if (!is_ok (error)) {
3690                         g_free (rmb.refs);
3691                         return FALSE;
3692                 }
3693                 klass = mono_class_from_mono_type (owner_type);
3694         } else {
3695                 klass = mono_defaults.object_class;
3696         }
3697
3698         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3699         g_free (rmb.refs);
3700         return_val_if_nok (error, FALSE);
3701
3702         release_data = g_new (DynamicMethodReleaseData, 1);
3703         release_data->handle = handle;
3704         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3705         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3706                 g_free (release_data);
3707
3708         /* Fix up refs entries pointing at us */
3709         for (l = mb->referenced_by; l; l = l->next) {
3710                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3711                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3712                 gpointer *data;
3713                 
3714                 g_assert (method->mhandle);
3715
3716                 data = (gpointer*)wrapper->method_data;
3717                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3718                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3719                                 data [i + 1] = mb->mhandle;
3720                 }
3721         }
3722         g_slist_free (mb->referenced_by);
3723
3724         /* ilgen is no longer needed */
3725         mb->ilgen = NULL;
3726
3727         domain = mono_domain_get ();
3728         mono_domain_lock (domain);
3729         if (!domain->method_to_dyn_method)
3730                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3731         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3732         mono_domain_unlock (domain);
3733
3734         return TRUE;
3735 }
3736
3737 void
3738 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
3739 {
3740         MonoError error;
3741         (void) reflection_create_dynamic_method (mb, &error);
3742         mono_error_set_pending_exception (&error);
3743 }
3744
3745 #endif /* DISABLE_REFLECTION_EMIT */
3746
3747 MonoMethodSignature *
3748 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3749 {
3750         MonoMethodSignature *sig;
3751         g_assert (image_is_dynamic (image));
3752
3753         mono_error_init (error);
3754
3755         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
3756         if (sig)
3757                 return sig;
3758
3759         return mono_method_signature_checked (method, error);
3760 }
3761
3762 #ifndef DISABLE_REFLECTION_EMIT
3763
3764 /*
3765  * ensure_complete_type:
3766  *
3767  *   Ensure that KLASS is completed if it is a dynamic type, or references
3768  * dynamic types.
3769  */
3770 static void
3771 ensure_complete_type (MonoClass *klass, MonoError *error)
3772 {
3773         mono_error_init (error);
3774
3775         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
3776                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
3777
3778                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3779                 return_if_nok (error);
3780
3781                 // Asserting here could break a lot of code
3782                 //g_assert (klass->wastypebuilder);
3783         }
3784
3785         if (mono_class_is_ginst (klass)) {
3786                 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
3787                 int i;
3788
3789                 for (i = 0; i < inst->type_argc; ++i) {
3790                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
3791                         return_if_nok (error);
3792                 }
3793         }
3794 }
3795
3796 gpointer
3797 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
3798 {
3799         MonoClass *oklass = obj->vtable->klass;
3800         gpointer result = NULL;
3801
3802         mono_error_init (error);
3803
3804         if (strcmp (oklass->name, "String") == 0) {
3805                 result = mono_string_intern_checked ((MonoString*)obj, error);
3806                 return_val_if_nok (error, NULL);
3807                 *handle_class = mono_defaults.string_class;
3808                 g_assert (result);
3809         } else if (strcmp (oklass->name, "RuntimeType") == 0) {
3810                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
3811                 return_val_if_nok (error, NULL);
3812                 MonoClass *mc = mono_class_from_mono_type (type);
3813                 if (!mono_class_init (mc)) {
3814                         mono_error_set_for_class_failure (error, mc);
3815                         return NULL;
3816                 }
3817
3818                 if (context) {
3819                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
3820                         return_val_if_nok (error, NULL);
3821
3822                         result = mono_class_from_mono_type (inflated);
3823                         mono_metadata_free_type (inflated);
3824                 } else {
3825                         result = mono_class_from_mono_type (type);
3826                 }
3827                 *handle_class = mono_defaults.typehandle_class;
3828                 g_assert (result);
3829         } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
3830                            strcmp (oklass->name, "MonoCMethod") == 0) {
3831                 result = ((MonoReflectionMethod*)obj)->method;
3832                 if (context) {
3833                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
3834                         mono_error_assert_ok (error);
3835                 }
3836                 *handle_class = mono_defaults.methodhandle_class;
3837                 g_assert (result);
3838         } else if (strcmp (oklass->name, "MonoField") == 0) {
3839                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
3840
3841                 ensure_complete_type (field->parent, error);
3842                 return_val_if_nok (error, NULL);
3843
3844                 if (context) {
3845                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
3846                         return_val_if_nok (error, NULL);
3847
3848                         MonoClass *klass = mono_class_from_mono_type (inflated);
3849                         MonoClassField *inflated_field;
3850                         gpointer iter = NULL;
3851                         mono_metadata_free_type (inflated);
3852                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
3853                                 if (!strcmp (field->name, inflated_field->name))
3854                                         break;
3855                         }
3856                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
3857                         result = inflated_field;
3858                 } else {
3859                         result = field;
3860                 }
3861                 *handle_class = mono_defaults.fieldhandle_class;
3862                 g_assert (result);
3863         } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
3864                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
3865                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
3866                 return_val_if_nok (error, NULL);
3867                 MonoClass *klass;
3868
3869                 klass = type->data.klass;
3870                 if (klass->wastypebuilder) {
3871                         /* Already created */
3872                         result = klass;
3873                 }
3874                 else {
3875                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3876                         return_val_if_nok (error, NULL);
3877                         result = type->data.klass;
3878                         g_assert (result);
3879                 }
3880                 *handle_class = mono_defaults.typehandle_class;
3881         } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
3882                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
3883                 MonoMethodSignature *sig;
3884                 int nargs, i;
3885
3886                 if (helper->arguments)
3887                         nargs = mono_array_length (helper->arguments);
3888                 else
3889                         nargs = 0;
3890
3891                 sig = mono_metadata_signature_alloc (image, nargs);
3892                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
3893                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
3894
3895                 if (helper->unmanaged_call_conv) { /* unmanaged */
3896                         sig->call_convention = helper->unmanaged_call_conv - 1;
3897                         sig->pinvoke = TRUE;
3898                 } else if (helper->call_conv & 0x02) {
3899                         sig->call_convention = MONO_CALL_VARARG;
3900                 } else {
3901                         sig->call_convention = MONO_CALL_DEFAULT;
3902                 }
3903
3904                 sig->param_count = nargs;
3905                 /* TODO: Copy type ? */
3906                 sig->ret = helper->return_type->type;
3907                 for (i = 0; i < nargs; ++i) {
3908                         sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i, error);
3909                         if (!is_ok (error)) {
3910                                 image_g_free (image, sig);
3911                                 return NULL;
3912                         }
3913                 }
3914
3915                 result = sig;
3916                 *handle_class = NULL;
3917         } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
3918                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3919                 /* Already created by the managed code */
3920                 g_assert (method->mhandle);
3921                 result = method->mhandle;
3922                 *handle_class = mono_defaults.methodhandle_class;
3923         } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
3924                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
3925                 MonoType *mtype;
3926                 MonoClass *klass;
3927                 MonoMethod *method;
3928                 gpointer iter;
3929                 char *name;
3930
3931                 mtype = mono_reflection_type_get_handle (m->parent, error);
3932                 return_val_if_nok (error, NULL);
3933                 klass = mono_class_from_mono_type (mtype);
3934
3935                 /* Find the method */
3936
3937                 name = mono_string_to_utf8_checked (m->name, error);
3938                 return_val_if_nok (error, NULL);
3939                 iter = NULL;
3940                 while ((method = mono_class_get_methods (klass, &iter))) {
3941                         if (!strcmp (method->name, name))
3942                                 break;
3943                 }
3944                 g_free (name);
3945
3946                 // FIXME:
3947                 g_assert (method);
3948                 // FIXME: Check parameters/return value etc. match
3949
3950                 result = method;
3951                 *handle_class = mono_defaults.methodhandle_class;
3952         } else if (is_sre_method_builder (oklass) ||
3953                            mono_is_sre_ctor_builder (oklass) ||
3954                            is_sre_field_builder (oklass) ||
3955                            is_sre_gparam_builder (oklass) ||
3956                            is_sre_generic_instance (oklass) ||
3957                            is_sre_array (oklass) ||
3958                            is_sre_byref (oklass) ||
3959                            is_sre_pointer (oklass) ||
3960                            !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
3961                            !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
3962                            !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
3963                 static MonoMethod *resolve_method;
3964                 if (!resolve_method) {
3965                         MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
3966                         g_assert (m);
3967                         mono_memory_barrier ();
3968                         resolve_method = m;
3969                 }
3970                 void *args [16];
3971                 args [0] = obj;
3972                 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
3973                 mono_error_assert_ok (error);
3974                 g_assert (obj);
3975                 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
3976         } else {
3977                 g_print ("%s\n", obj->vtable->klass->name);
3978                 g_assert_not_reached ();
3979         }
3980         return result;
3981 }
3982
3983 #else /* DISABLE_REFLECTION_EMIT */
3984
3985 MonoArray*
3986 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
3987 {
3988         g_assert_not_reached ();
3989         return NULL;
3990 }
3991
3992 void
3993 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
3994 {
3995         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
3996 }
3997
3998 static void
3999 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
4000 {
4001         g_assert_not_reached ();
4002 }
4003
4004 guint32
4005 mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
4006 {
4007         g_assert_not_reached ();
4008         return 0;
4009 }
4010
4011 guint32
4012 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types, MonoError *error)
4013 {
4014         g_assert_not_reached ();
4015         return 0;
4016 }
4017
4018 guint32
4019 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
4020                          gboolean create_open_instance, gboolean register_token, MonoError *error)
4021 {
4022         g_assert_not_reached ();
4023         return 0;
4024 }
4025
4026 void
4027 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4028 {
4029         mono_error_init (error);
4030         *overrides = NULL;
4031         *num_overrides = 0;
4032 }
4033
4034 MonoReflectionType*
4035 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
4036 {
4037         g_assert_not_reached ();
4038         return NULL;
4039 }
4040
4041 void 
4042 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
4043 {
4044 }
4045
4046 MonoType*
4047 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4048 {
4049         mono_error_init (error);
4050         if (!ref)
4051                 return NULL;
4052         return ref->type;
4053 }
4054
4055 #endif /* DISABLE_REFLECTION_EMIT */
4056
4057 void
4058 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4059 {
4060         mono_gc_deregister_root ((char*) &entry->gparam);
4061         g_free (entry);
4062 }
4063
4064 gint32
4065 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
4066 {
4067         MONO_CHECK_ARG_NULL (obj, 0);
4068
4069         MonoError error;
4070         gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
4071         mono_error_set_pending_exception (&error);
4072         return result;
4073 }
4074
4075 gint32
4076 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
4077                                         MonoReflectionMethod *method,
4078                                         MonoArray *opt_param_types)
4079 {
4080         MONO_CHECK_ARG_NULL (method, 0);
4081
4082         MonoError error;
4083         gint32 result = mono_image_create_method_token (
4084                 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
4085         mono_error_set_pending_exception (&error);
4086         return result;
4087 }
4088
4089 void
4090 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4091 {
4092         MonoError error;
4093         mono_image_create_pefile (mb, file, &error);
4094         mono_error_set_pending_exception (&error);
4095 }
4096
4097 void
4098 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4099 {
4100         MonoError error;
4101         mono_image_build_metadata (mb, &error);
4102         mono_error_set_pending_exception (&error);
4103 }
4104
4105 void
4106 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
4107 {
4108         mono_image_register_token (mb->dynamic_image, token, obj);
4109 }
4110
4111 MonoObject*
4112 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
4113 {
4114         MonoObject *obj;
4115
4116         mono_loader_lock ();
4117         obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
4118         mono_loader_unlock ();
4119
4120         return obj;
4121 }
4122
4123 #ifndef DISABLE_REFLECTION_EMIT
4124 MonoArray*
4125 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4126 {
4127         MonoError error;
4128         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4129         mono_error_set_pending_exception (&error);
4130         return result;
4131 }
4132 #endif
4133
4134 void
4135 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4136 {
4137         mono_reflection_dynimage_basic_init (assemblyb);
4138 }
4139
4140 void
4141 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
4142                                                                            MonoReflectionType *t)
4143 {
4144         enumtype->type = t->type;
4145 }
4146
4147 void
4148 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder *moduleb)
4149 {
4150         mono_image_module_basic_init (moduleb);
4151 }
4152
4153 guint32
4154 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder *module, MonoString *str)
4155 {
4156         return mono_image_insert_string (module, str);
4157 }
4158
4159 void
4160 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
4161 {
4162         MonoDynamicImage *image = moduleb->dynamic_image;
4163
4164         g_assert (type->type);
4165         image->wrappers_type = mono_class_from_mono_type (type->type);
4166 }