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