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