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