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