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