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