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