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