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