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