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