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