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