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