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