Merge branch 'master' into config-checks-ipv6
[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         MonoGenericContext* context = &generic_container->context;
2585         MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
2586         canonical_inst->type = MONO_TYPE_GENERICINST;
2587         canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
2588
2589 leave:
2590         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2591 }
2592
2593 static MonoMarshalSpec*
2594 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2595                                 MonoReflectionMarshal *minfo, MonoError *error)
2596 {
2597         MonoMarshalSpec *res;
2598
2599         error_init (error);
2600
2601         res = image_g_new0 (image, MonoMarshalSpec, 1);
2602         res->native = (MonoMarshalNative)minfo->type;
2603
2604         switch (minfo->type) {
2605         case MONO_NATIVE_LPARRAY:
2606                 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2607                 if (minfo->has_size) {
2608                         res->data.array_data.param_num = minfo->param_num;
2609                         res->data.array_data.num_elem = minfo->count;
2610                         res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2611                 }
2612                 else {
2613                         res->data.array_data.param_num = -1;
2614                         res->data.array_data.num_elem = -1;
2615                         res->data.array_data.elem_mult = -1;
2616                 }
2617                 break;
2618
2619         case MONO_NATIVE_BYVALTSTR:
2620         case MONO_NATIVE_BYVALARRAY:
2621                 res->data.array_data.num_elem = minfo->count;
2622                 break;
2623
2624         case MONO_NATIVE_CUSTOM:
2625                 if (minfo->marshaltyperef) {
2626                         MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2627                         if (!is_ok (error)) {
2628                                 image_g_free (image, res);
2629                                 return NULL;
2630                         }
2631                         res->data.custom_data.custom_name =
2632                                 type_get_fully_qualified_name (marshaltyperef);
2633                 }
2634                 if (minfo->mcookie) {
2635                         res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2636                         if (!is_ok (error)) {
2637                                 image_g_free (image, res);
2638                                 return NULL;
2639                         }
2640                 }
2641                 break;
2642
2643         default:
2644                 break;
2645         }
2646
2647         return res;
2648 }
2649 #endif /* !DISABLE_REFLECTION_EMIT */
2650
2651 MonoReflectionMarshalAsAttributeHandle
2652 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2653                                                         MonoMarshalSpec *spec, MonoError *error)
2654 {
2655         error_init (error);
2656         
2657         MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
2658         if (!is_ok (error))
2659                 goto fail;
2660         guint32 utype = spec->native;
2661         MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2662
2663         switch (utype) {
2664         case MONO_NATIVE_LPARRAY:
2665                 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2666                 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2667                 if (spec->data.array_data.param_num != -1)
2668                         MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2669                 break;
2670
2671         case MONO_NATIVE_BYVALTSTR:
2672         case MONO_NATIVE_BYVALARRAY:
2673                 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2674                 break;
2675
2676         case MONO_NATIVE_CUSTOM:
2677                 if (spec->data.custom_data.custom_name) {
2678                         MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2679                         if (!is_ok (error))
2680                                 goto fail;
2681
2682                         if (mtype) {
2683                                 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2684                                 if (!is_ok (error))
2685                                         goto fail;
2686
2687                                 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2688                         }
2689
2690                         MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2691                         if (!is_ok (error))
2692                                 goto fail;
2693                         MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2694                 }
2695                 if (spec->data.custom_data.cookie) {
2696                         MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2697                         if (!is_ok (error))
2698                                 goto fail;
2699                         MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2700                 }
2701                 break;
2702
2703         default:
2704                 break;
2705         }
2706
2707         return minfo;
2708 fail:
2709         return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
2710 }
2711
2712 #ifndef DISABLE_REFLECTION_EMIT
2713 static MonoMethod*
2714 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2715                                          ReflectionMethodBuilder *rmb,
2716                                          MonoMethodSignature *sig,
2717                                          MonoError *error)
2718 {
2719         MonoMethod *m;
2720         MonoMethodWrapper *wrapperm;
2721         MonoMarshalSpec **specs;
2722         MonoReflectionMethodAux *method_aux;
2723         MonoImage *image;
2724         gboolean dynamic;
2725         int i;
2726
2727         error_init (error);
2728         /*
2729          * Methods created using a MethodBuilder should have their memory allocated
2730          * inside the image mempool, while dynamic methods should have their memory
2731          * malloc'd.
2732          */
2733         dynamic = rmb->refs != NULL;
2734         image = dynamic ? NULL : klass->image;
2735
2736         if (!dynamic)
2737                 g_assert (!mono_class_is_ginst (klass));
2738
2739         mono_loader_lock ();
2740
2741         if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2742                         (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2743                 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2744         else
2745                 m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
2746
2747         wrapperm = (MonoMethodWrapper*)m;
2748
2749         m->dynamic = dynamic;
2750         m->slot = -1;
2751         m->flags = rmb->attrs;
2752         m->iflags = rmb->iattrs;
2753         m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2754         m->klass = klass;
2755         m->signature = sig;
2756         m->sre_method = TRUE;
2757         m->skip_visibility = rmb->skip_visibility;
2758         if (rmb->table_idx)
2759                 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2760
2761         if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2762                 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2763                         m->string_ctor = 1;
2764
2765                 m->signature->pinvoke = 1;
2766         } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2767                 m->signature->pinvoke = 1;
2768
2769                 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2770
2771                 method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
2772                 mono_error_assert_ok (error);
2773                 method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
2774                 mono_error_assert_ok (error);
2775                 
2776                 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2777
2778                 if (image_is_dynamic (klass->image))
2779                         g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2780
2781                 mono_loader_unlock ();
2782
2783                 return m;
2784         } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2785                            !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2786                 MonoMethodHeader *header;
2787                 guint32 code_size;
2788                 gint32 max_stack, i;
2789                 gint32 num_locals = 0;
2790                 gint32 num_clauses = 0;
2791                 guint8 *code;
2792
2793                 if (rmb->ilgen) {
2794                         code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2795                         code_size = rmb->ilgen->code_len;
2796                         max_stack = rmb->ilgen->max_stack;
2797                         num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2798                         if (rmb->ilgen->ex_handlers)
2799                                 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2800                 } else {
2801                         if (rmb->code) {
2802                                 code = mono_array_addr (rmb->code, guint8, 0);
2803                                 code_size = mono_array_length (rmb->code);
2804                                 /* we probably need to run a verifier on the code... */
2805                                 max_stack = 8; 
2806                         }
2807                         else {
2808                                 code = NULL;
2809                                 code_size = 0;
2810                                 max_stack = 8;
2811                         }
2812                 }
2813
2814                 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2815                 header->code_size = code_size;
2816                 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2817                 memcpy ((char*)header->code, code, code_size);
2818                 header->max_stack = max_stack;
2819                 header->init_locals = rmb->init_locals;
2820                 header->num_locals = num_locals;
2821
2822                 for (i = 0; i < num_locals; ++i) {
2823                         MonoReflectionLocalBuilder *lb = 
2824                                 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2825
2826                         header->locals [i] = image_g_new0 (image, MonoType, 1);
2827                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2828                         mono_error_assert_ok (error);
2829                         memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2830                 }
2831
2832                 header->num_clauses = num_clauses;
2833                 if (num_clauses) {
2834                         header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2835                                                                  rmb->ilgen, num_clauses, error);
2836                         mono_error_assert_ok (error);
2837                 }
2838
2839                 wrapperm->header = header;
2840         }
2841
2842         if (rmb->generic_params) {
2843                 int count = mono_array_length (rmb->generic_params);
2844                 MonoGenericContainer *container;
2845
2846                 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2847                 container->is_method = TRUE;
2848                 container->is_anonymous = FALSE;
2849                 container->type_argc = count;
2850                 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2851                 container->owner.method = m;
2852
2853                 m->is_generic = TRUE;
2854                 mono_method_set_generic_container (m, container);
2855
2856                 for (i = 0; i < count; i++) {
2857                         MonoReflectionGenericParam *gp =
2858                                 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2859                         MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2860                         mono_error_assert_ok (error);
2861                         MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2862                         container->type_params [i] = *param;
2863                         container->type_params [i].param.owner = container;
2864
2865                         gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2866
2867                         MonoClass *gklass = mono_class_from_mono_type (gp_type);
2868                         gklass->wastypebuilder = TRUE;
2869                 }
2870
2871                 /*
2872                  * The method signature might have pointers to generic parameters that belong to other methods.
2873                  * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2874                  * generic parameters.
2875                  */
2876                 for (i = 0; i < m->signature->param_count; ++i) {
2877                         MonoType *t = m->signature->params [i];
2878                         if (t->type == MONO_TYPE_MVAR) {
2879                                 MonoGenericParam *gparam =  t->data.generic_param;
2880                                 if (gparam->num < count) {
2881                                         m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2882                                         m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2883                                 }
2884
2885                         }
2886                 }
2887
2888                 if (mono_class_is_gtd (klass)) {
2889                         container->parent = mono_class_get_generic_container (klass);
2890                         container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2891                 }
2892                 container->context.method_inst = mono_get_shared_generic_inst (container);
2893         }
2894
2895         if (rmb->refs) {
2896                 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2897                 int i;
2898                 void **data;
2899
2900                 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2901
2902                 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2903                 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2904                 for (i = 0; i < rmb->nrefs; ++i)
2905                         data [i + 1] = rmb->refs [i];
2906         }
2907
2908         method_aux = NULL;
2909
2910         /* Parameter info */
2911         if (rmb->pinfo) {
2912                 if (!method_aux)
2913                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2914                 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2915                 for (i = 0; i <= m->signature->param_count; ++i) {
2916                         MonoReflectionParamBuilder *pb;
2917                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2918                                 if ((i > 0) && (pb->attrs)) {
2919                                         /* Make a copy since it might point to a shared type structure */
2920                                         m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2921                                         m->signature->params [i - 1]->attrs = pb->attrs;
2922                                 }
2923
2924                                 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2925                                         MonoDynamicImage *assembly;
2926                                         guint32 idx, len;
2927                                         MonoTypeEnum def_type;
2928                                         char *p;
2929                                         const char *p2;
2930
2931                                         if (!method_aux->param_defaults) {
2932                                                 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2933                                                 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2934                                         }
2935                                         assembly = (MonoDynamicImage*)klass->image;
2936                                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
2937                                         /* Copy the data from the blob since it might get realloc-ed */
2938                                         p = assembly->blob.data + idx;
2939                                         len = mono_metadata_decode_blob_size (p, &p2);
2940                                         len += p2 - p;
2941                                         method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
2942                                         method_aux->param_default_types [i] = def_type;
2943                                         memcpy ((gpointer)method_aux->param_defaults [i], p, len);
2944                                 }
2945
2946                                 if (pb->name) {
2947                                         method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
2948                                         mono_error_assert_ok (error);
2949                                 }
2950                                 if (pb->cattrs) {
2951                                         if (!method_aux->param_cattr)
2952                                                 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
2953                                         method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
2954                                 }
2955                         }
2956                 }
2957         }
2958
2959         /* Parameter marshalling */
2960         specs = NULL;
2961         if (rmb->pinfo)         
2962                 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
2963                         MonoReflectionParamBuilder *pb;
2964                         if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2965                                 if (pb->marshal_info) {
2966                                         if (specs == NULL)
2967                                                 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
2968                                         specs [pb->position] = 
2969                                                 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
2970                                         if (!is_ok (error)) {
2971                                                 mono_loader_unlock ();
2972                                                 image_g_free (image, specs);
2973                                                 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2974                                                 return NULL;
2975                                         }
2976                                 }
2977                         }
2978                 }
2979         if (specs != NULL) {
2980                 if (!method_aux)
2981                         method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2982                 method_aux->param_marshall = specs;
2983         }
2984
2985         if (image_is_dynamic (klass->image) && method_aux)
2986                 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2987
2988         mono_loader_unlock ();
2989
2990         return m;
2991 }       
2992
2993 static MonoMethod*
2994 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
2995 {
2996         ReflectionMethodBuilder rmb;
2997         MonoMethodSignature *sig;
2998
2999         mono_loader_lock ();
3000
3001         if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3002                 return NULL;
3003
3004         g_assert (klass->image != NULL);
3005         sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
3006         mono_loader_unlock ();
3007         return_val_if_nok (error, NULL);
3008
3009         mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3010         return_val_if_nok (error, NULL);
3011         mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3012
3013         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
3014                 /* ilgen is no longer needed */
3015                 mb->ilgen = NULL;
3016         }
3017
3018         return mb->mhandle;
3019 }
3020
3021 static MonoMethod*
3022 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
3023 {
3024         ReflectionMethodBuilder rmb;
3025         MonoMethodSignature *sig;
3026
3027         error_init (error);
3028
3029         mono_loader_lock ();
3030
3031         MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
3032         if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3033                 return NULL;
3034
3035         g_assert (klass->image != NULL);
3036         sig = method_builder_to_signature (klass->image, ref_mb, error);
3037         mono_loader_unlock ();
3038         return_val_if_nok (error, NULL);
3039
3040         MonoMethod *method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3041         return_val_if_nok (error, NULL);
3042         MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
3043         mono_save_custom_attrs (klass->image, method, mb->cattrs);
3044
3045         if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
3046                 /* ilgen is no longer needed */
3047                 mb->ilgen = NULL;
3048         return method;
3049 }
3050
3051 static MonoMethod*
3052 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
3053 {
3054         HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3055         error_init (error);
3056         MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
3057         MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
3058         HANDLE_FUNCTION_RETURN_VAL (result);
3059 }
3060
3061 #endif
3062
3063 #ifndef DISABLE_REFLECTION_EMIT
3064
3065 /**
3066  * fix_partial_generic_class:
3067  * @klass: a generic instantiation MonoClass
3068  * @error: set on error
3069  *
3070  * Assumes that the generic container of @klass has its vtable
3071  * initialized, and updates the parent class, interfaces, methods and
3072  * fields of @klass by inflating the types using the generic context.
3073  *
3074  * On success returns TRUE, on failure returns FALSE and sets @error.
3075  *
3076  */
3077 static gboolean
3078 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3079 {
3080         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3081         int i;
3082
3083         error_init (error);
3084
3085         if (klass->wastypebuilder)
3086                 return TRUE;
3087
3088         if (klass->parent != gklass->parent) {
3089                 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
3090                 if (mono_error_ok (error)) {
3091                         MonoClass *parent = mono_class_from_mono_type (parent_type);
3092                         mono_metadata_free_type (parent_type);
3093                         if (parent != klass->parent) {
3094                                 /*fool mono_class_setup_parent*/
3095                                 klass->supertypes = NULL;
3096                                 mono_class_setup_parent (klass, parent);
3097                         }
3098                 } else {
3099                         if (gklass->wastypebuilder)
3100                                 klass->wastypebuilder = TRUE;
3101                         return FALSE;
3102                 }
3103         }
3104
3105         if (!mono_class_get_generic_class (klass)->need_sync)
3106                 return TRUE;
3107
3108         int mcount = mono_class_get_method_count (klass);
3109         int gmcount = mono_class_get_method_count (gklass);
3110         if (mcount != gmcount) {
3111                 mono_class_set_method_count (klass, gmcount);
3112                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
3113
3114                 for (i = 0; i < gmcount; i++) {
3115                         klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3116                                 gklass->methods [i], klass, mono_class_get_context (klass), error);
3117                         mono_error_assert_ok (error);
3118                 }
3119         }
3120
3121         if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3122                 klass->interface_count = gklass->interface_count;
3123                 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3124                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3125
3126                 for (i = 0; i < gklass->interface_count; ++i) {
3127                         MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3128                         return_val_if_nok (error, FALSE);
3129
3130                         klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3131                         mono_metadata_free_type (iface_type);
3132
3133                         if (!ensure_runtime_vtable (klass->interfaces [i], error))
3134                                 return FALSE;
3135                 }
3136                 klass->interfaces_inited = 1;
3137         }
3138
3139         int fcount = mono_class_get_field_count (klass);
3140         int gfcount = mono_class_get_field_count (gklass);
3141         if (fcount != gfcount) {
3142                 mono_class_set_field_count (klass, gfcount);
3143                 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3144
3145                 for (i = 0; i < gfcount; i++) {
3146                         klass->fields [i] = gklass->fields [i];
3147                         klass->fields [i].parent = klass;
3148                         klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3149                         return_val_if_nok (error, FALSE);
3150                 }
3151         }
3152
3153         /*We can only finish with this klass once it's parent has as well*/
3154         if (gklass->wastypebuilder)
3155                 klass->wastypebuilder = TRUE;
3156         return TRUE;
3157 }
3158
3159 /**
3160  * ensure_generic_class_runtime_vtable:
3161  * @klass a generic class
3162  * @error set on error
3163  *
3164  * Ensures that the generic container of @klass has a vtable and
3165  * returns TRUE on success.  On error returns FALSE and sets @error.
3166  */
3167 static gboolean
3168 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3169 {
3170         MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3171
3172         error_init (error);
3173
3174         if (!ensure_runtime_vtable (gklass, error))
3175                 return FALSE;
3176
3177         return fix_partial_generic_class (klass, error);
3178 }
3179
3180 /**
3181  * ensure_runtime_vtable:
3182  * @klass the class
3183  * @error set on error
3184  *
3185  * Ensures that @klass has a vtable and returns TRUE on success. On
3186  * error returns FALSE and sets @error.
3187  */
3188 static gboolean
3189 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3190 {
3191         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3192         int i, num, j;
3193
3194         error_init (error);
3195
3196         if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3197                 return TRUE;
3198         if (klass->parent)
3199                 if (!ensure_runtime_vtable (klass->parent, error))
3200                         return FALSE;
3201
3202         if (tb) {
3203                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3204                 num += tb->num_methods;
3205                 mono_class_set_method_count (klass, num);
3206                 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3207                 num = tb->ctors? mono_array_length (tb->ctors): 0;
3208                 for (i = 0; i < num; ++i) {
3209                         MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3210                         if (!ctor)
3211                                 return FALSE;
3212                         klass->methods [i] = ctor;
3213                 }
3214                 num = tb->num_methods;
3215                 j = i;
3216                 for (i = 0; i < num; ++i) {
3217                         MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
3218                         if (!meth)
3219                                 return FALSE;
3220                         klass->methods [j++] = meth;
3221                 }
3222         
3223                 if (tb->interfaces) {
3224                         klass->interface_count = mono_array_length (tb->interfaces);
3225                         klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3226                         for (i = 0; i < klass->interface_count; ++i) {
3227                                 MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
3228                                 return_val_if_nok (error, FALSE);
3229                                 klass->interfaces [i] = mono_class_from_mono_type (iface);
3230                                 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3231                                         return FALSE;
3232                         }
3233                         klass->interfaces_inited = 1;
3234                 }
3235         } else if (mono_class_is_ginst (klass)){
3236                 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3237                         mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3238                         return FALSE;
3239                 }
3240         }
3241
3242         if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3243                 int slot_num = 0;
3244                 int mcount = mono_class_get_method_count (klass);
3245                 for (i = 0; i < mcount; ++i) {
3246                         MonoMethod *im = klass->methods [i];
3247                         if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3248                                 im->slot = slot_num++;
3249                 }
3250                 
3251                 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3252                 mono_class_setup_interface_offsets (klass);
3253                 mono_class_setup_interface_id (klass);
3254         }
3255
3256         /*
3257          * The generic vtable is needed even if image->run is not set since some
3258          * runtime code like ves_icall_Type_GetMethodsByName depends on 
3259          * method->slot being defined.
3260          */
3261
3262         /* 
3263          * tb->methods could not be freed since it is used for determining 
3264          * overrides during dynamic vtable construction.
3265          */
3266
3267         return TRUE;
3268 }
3269
3270 static MonoMethod*
3271 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3272 {
3273         error_init (error);
3274         MonoClass *klass = mono_object_class (method);
3275         if (is_sr_mono_method (klass)) {
3276                 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3277                 return sr_method->method;
3278         }
3279         if (is_sre_method_builder (klass)) {
3280                 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3281                 return mb->mhandle;
3282         }
3283         if (mono_is_sre_method_on_tb_inst (klass)) {
3284                 MonoClass *handle_class;
3285
3286                 MonoMethod *result =  mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3287                 return_val_if_nok (error, NULL);
3288
3289                 return result;
3290         }
3291
3292         g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3293         return NULL;
3294 }
3295
3296 void
3297 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3298 {
3299         MonoReflectionTypeBuilder *tb;
3300         int i, j, onum;
3301         MonoReflectionMethod *m;
3302
3303         error_init (error);
3304         *overrides = NULL;
3305         *num_overrides = 0;
3306
3307         g_assert (image_is_dynamic (klass->image));
3308
3309         if (!mono_class_has_ref_info (klass))
3310                 return;
3311
3312         tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3313         g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
3314
3315         onum = 0;
3316         if (tb->methods) {
3317                 for (i = 0; i < tb->num_methods; ++i) {
3318                         MonoReflectionMethodBuilder *mb = 
3319                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3320                         if (mb->override_methods)
3321                                 onum += mono_array_length (mb->override_methods);
3322                 }
3323         }
3324
3325         if (onum) {
3326                 *overrides = g_new0 (MonoMethod*, onum * 2);
3327
3328                 onum = 0;
3329                 for (i = 0; i < tb->num_methods; ++i) {
3330                         MonoReflectionMethodBuilder *mb = 
3331                                 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3332                         if (mb->override_methods) {
3333                                 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3334                                         m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3335
3336                                         (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3337                                         return_if_nok (error);
3338                                         (*overrides) [onum * 2 + 1] = mb->mhandle;
3339
3340                                         g_assert (mb->mhandle);
3341
3342                                         onum ++;
3343                                 }
3344                         }
3345                 }
3346         }
3347
3348         *num_overrides = onum;
3349 }
3350
3351 /* This initializes the same data as mono_class_setup_fields () */
3352 static void
3353 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3354 {
3355         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3356         MonoReflectionFieldBuilder *fb;
3357         MonoClassField *field;
3358         MonoFieldDefaultValue *def_values;
3359         MonoImage *image = klass->image;
3360         const char *p, *p2;
3361         int i, instance_size, packing_size = 0;
3362         guint32 len, idx;
3363
3364         if (klass->parent) {
3365                 if (!klass->parent->size_inited)
3366                         mono_class_init (klass->parent);
3367                 instance_size = klass->parent->instance_size;
3368         } else {
3369                 instance_size = sizeof (MonoObject);
3370         }
3371
3372         int fcount = tb->num_fields;
3373         mono_class_set_field_count (klass, fcount);
3374
3375         error_init (error);
3376
3377         if (tb->class_size) {
3378                 packing_size = tb->packing_size;
3379                 instance_size += tb->class_size;
3380         }
3381         
3382         klass->fields = image_g_new0 (image, MonoClassField, fcount);
3383         def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3384         mono_class_set_field_def_values (klass, def_values);
3385         /*
3386         This is, guess what, a hack.
3387         The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3388         On the static path no field class is resolved, only types are built. This is the right thing to do
3389         but we suck.
3390         Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3391         */
3392         klass->size_inited = 1;
3393
3394         for (i = 0; i < fcount; ++i) {
3395                 MonoArray *rva_data;
3396                 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3397                 field = &klass->fields [i];
3398                 field->parent = klass;
3399                 field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
3400                 if (!mono_error_ok (error))
3401                         return;
3402                 if (fb->attrs) {
3403                         MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3404                         return_if_nok (error);
3405                         field->type = mono_metadata_type_dup (klass->image, type);
3406                         field->type->attrs = fb->attrs;
3407                 } else {
3408                         field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3409                         return_if_nok (error);
3410                 }
3411
3412                 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3413                         char *base = mono_array_addr (rva_data, char, 0);
3414                         size_t size = mono_array_length (rva_data);
3415                         char *data = (char *)mono_image_alloc (klass->image, size);
3416                         memcpy (data, base, size);
3417                         def_values [i].data = data;
3418                 }
3419                 if (fb->offset != -1)
3420                         field->offset = fb->offset;
3421                 fb->handle = field;
3422                 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3423
3424                 if (fb->def_value) {
3425                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3426                         field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3427                         idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3428                         /* Copy the data from the blob since it might get realloc-ed */
3429                         p = assembly->blob.data + idx;
3430                         len = mono_metadata_decode_blob_size (p, &p2);
3431                         len += p2 - p;
3432                         def_values [i].data = (const char *)mono_image_alloc (image, len);
3433                         memcpy ((gpointer)def_values [i].data, p, len);
3434                 }
3435         }
3436
3437         mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
3438 }
3439
3440 static void
3441 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3442 {
3443         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3444         MonoReflectionPropertyBuilder *pb;
3445         MonoImage *image = klass->image;
3446         MonoProperty *properties;
3447         MonoClassPropertyInfo *info;
3448         int i;
3449
3450         error_init (error);
3451
3452         info = mono_class_get_property_info (klass);
3453         if (!info) {
3454                 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3455                 mono_class_set_property_info (klass, info);
3456         }
3457
3458         info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3459         info->first = 0;
3460
3461         properties = image_g_new0 (image, MonoProperty, info->count);
3462         info->properties = properties;
3463         for (i = 0; i < info->count; ++i) {
3464                 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3465                 properties [i].parent = klass;
3466                 properties [i].attrs = pb->attrs;
3467                 properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
3468                 if (!mono_error_ok (error))
3469                         return;
3470                 if (pb->get_method)
3471                         properties [i].get = pb->get_method->mhandle;
3472                 if (pb->set_method)
3473                         properties [i].set = pb->set_method->mhandle;
3474
3475                 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3476                 if (pb->def_value) {
3477                         guint32 len, idx;
3478                         const char *p, *p2;
3479                         MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3480                         if (!info->def_values)
3481                                 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3482                         properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3483                         idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3484                         /* Copy the data from the blob since it might get realloc-ed */
3485                         p = assembly->blob.data + idx;
3486                         len = mono_metadata_decode_blob_size (p, &p2);
3487                         len += p2 - p;
3488                         info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3489                         memcpy ((gpointer)info->def_values [i].data, p, len);
3490                 }
3491         }
3492 }
3493
3494 static void
3495 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3496 {
3497         MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3498         MonoReflectionEventBuilder *eb;
3499         MonoImage *image = klass->image;
3500         MonoEvent *events;
3501         MonoClassEventInfo *info;
3502         int i;
3503
3504         error_init (error);
3505
3506         info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3507         mono_class_set_event_info (klass, info);
3508
3509         info->count = tb->events ? mono_array_length (tb->events) : 0;
3510         info->first = 0;
3511
3512         events = image_g_new0 (image, MonoEvent, info->count);
3513         info->events = events;
3514         for (i = 0; i < info->count; ++i) {
3515                 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3516                 events [i].parent = klass;
3517                 events [i].attrs = eb->attrs;
3518                 events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
3519                 if (!mono_error_ok (error))
3520                         return;
3521                 if (eb->add_method)
3522                         events [i].add = eb->add_method->mhandle;
3523                 if (eb->remove_method)
3524                         events [i].remove = eb->remove_method->mhandle;
3525                 if (eb->raise_method)
3526                         events [i].raise = eb->raise_method->mhandle;
3527
3528 #ifndef MONO_SMALL_CONFIG
3529                 if (eb->other_methods) {
3530                         int j;
3531                         events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3532                         for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3533                                 MonoReflectionMethodBuilder *mb = 
3534                                         mono_array_get (eb->other_methods,
3535                                                                         MonoReflectionMethodBuilder*, j);
3536                                 events [i].other [j] = mb->mhandle;
3537                         }
3538                 }
3539 #endif
3540                 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3541         }
3542 }
3543
3544 struct remove_instantiations_user_data
3545 {
3546         MonoClass *klass;
3547         MonoError *error;
3548 };
3549
3550 static gboolean
3551 remove_instantiations_of_and_ensure_contents (gpointer key,
3552                                                   gpointer value,
3553                                                   gpointer user_data)
3554 {
3555         struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3556         MonoType *type = (MonoType*)key;
3557         MonoClass *klass = data->klass;
3558         gboolean already_failed = !is_ok (data->error);
3559         MonoError lerror;
3560         MonoError *error = already_failed ? &lerror : data->error;
3561
3562         if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3563                 MonoClass *inst_klass = mono_class_from_mono_type (type);
3564                 //Ensure it's safe to use it.
3565                 if (!fix_partial_generic_class (inst_klass, error)) {
3566                         mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3567                         // Marked the class with failure, but since some other instantiation already failed,
3568                         // just report that one, and swallow the error from this one.
3569                         if (already_failed)
3570                                 mono_error_cleanup (error);
3571                 }
3572                 return TRUE;
3573         } else
3574                 return FALSE;
3575 }
3576
3577 /**
3578  * reflection_setup_internal_class:
3579  * @tb: a TypeBuilder object
3580  * @error: set on error
3581  *
3582  * Creates a MonoClass that represents the TypeBuilder.
3583  * This is a trick that lets us simplify a lot of reflection code
3584  * (and will allow us to support Build and Run assemblies easier).
3585  *
3586  * Returns TRUE on success. On failure, returns FALSE and sets @error.
3587  */
3588 static gboolean
3589 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3590 {
3591         MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
3592         GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
3593
3594         if (unparented_classes) {
3595                 return reflection_setup_internal_class_internal (ref_tb, error);
3596         } else {
3597                 // If we're not being called recursively
3598                 unparented_classes = g_hash_table_new (NULL, NULL);
3599                 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
3600
3601                 gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
3602                 mono_error_assert_ok (error);
3603
3604                 // Fix the relationship between the created classes and their parents
3605                 reflection_setup_class_hierarchy (unparented_classes, error);
3606                 mono_error_assert_ok (error);
3607
3608                 g_hash_table_destroy (unparented_classes);
3609                 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
3610
3611                 return ret_val;
3612         }
3613 }
3614
3615
3616 MonoReflectionTypeHandle
3617 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3618 {
3619         error_init (error);
3620
3621         reflection_setup_internal_class (ref_tb, error);
3622         mono_error_assert_ok (error);
3623
3624         MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
3625         MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
3626         MonoClass *klass = mono_class_from_mono_type (type);
3627
3628         MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
3629         mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
3630
3631         /* 
3632          * we need to lock the domain because the lock will be taken inside
3633          * So, we need to keep the locking order correct.
3634          */
3635         mono_loader_lock ();
3636         mono_domain_lock (domain);
3637         if (klass->wastypebuilder) {
3638                 mono_domain_unlock (domain);
3639                 mono_loader_unlock ();
3640
3641                 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
3642         }
3643         /*
3644          * Fields to set in klass:
3645          * the various flags: delegate/unicode/contextbound etc.
3646          */
3647         mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
3648         klass->has_cctor = 1;
3649
3650         mono_class_setup_parent (klass, klass->parent);
3651         /* fool mono_class_setup_supertypes */
3652         klass->supertypes = NULL;
3653         mono_class_setup_supertypes (klass);
3654         mono_class_setup_mono_type (klass);
3655
3656         /* enums are done right away */
3657         if (!klass->enumtype)
3658                 if (!ensure_runtime_vtable (klass, error))
3659                         goto failure;
3660
3661         MonoArrayHandle nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
3662         if (!MONO_HANDLE_IS_NULL (nested_types)) {
3663                 GList *nested = NULL;
3664                 int num_nested = mono_array_handle_length (nested_types);
3665                 MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3666                 for (int i = 0; i < num_nested; ++i) {
3667                         MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
3668
3669                         if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
3670                                 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
3671                                 mono_error_assert_ok (error);
3672                         }
3673
3674                         MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
3675                         if (!is_ok (error)) goto failure;
3676                         nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3677                 }
3678                 mono_class_set_nested_classes_property (klass, nested);
3679         }
3680
3681         klass->nested_classes_inited = TRUE;
3682
3683         typebuilder_setup_fields (klass, error);
3684         if (!is_ok (error))
3685                 goto failure;
3686         typebuilder_setup_properties (klass, error);
3687         if (!is_ok (error))
3688                 goto failure;
3689
3690         typebuilder_setup_events (klass, error);
3691         if (!is_ok (error))
3692                 goto failure;
3693
3694         klass->wastypebuilder = TRUE;
3695
3696         MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
3697         if (!MONO_HANDLE_IS_NULL (generic_params)) {
3698                 int num_params = mono_array_handle_length (generic_params);
3699                 MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3700                 for (int i = 0; i < num_params; i++) {
3701                         MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
3702                         MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
3703                         if (!is_ok (error))
3704                                 goto failure;
3705                         MonoClass *gklass = mono_class_from_mono_type (param_type);
3706
3707                         gklass->wastypebuilder = TRUE;
3708                 }
3709         }
3710
3711         /* 
3712          * If we are a generic TypeBuilder, there might be instantiations in the type cache
3713          * which have type System.Reflection.MonoGenericClass, but after the type is created, 
3714          * we want to return normal System.MonoType objects, so clear these out from the cache.
3715          *
3716          * Together with this we must ensure the contents of all instances to match the created type.
3717          */
3718         if (domain->type_hash && mono_class_is_gtd (klass)) {
3719                 struct remove_instantiations_user_data data;
3720                 data.klass = klass;
3721                 data.error = error;
3722                 mono_error_assert_ok (error);
3723                 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3724                 if (!is_ok (error))
3725                         goto failure;
3726         }
3727
3728         mono_domain_unlock (domain);
3729         mono_loader_unlock ();
3730
3731         if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3732                 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3733                 mono_error_set_type_load_class (error, klass, "Not a valid enumeration");
3734                 goto failure_unlocked;
3735         }
3736
3737         MonoReflectionTypeHandle res = mono_type_get_object_handle (domain, &klass->byval_arg, error);
3738         if (!is_ok (error))
3739                 goto failure_unlocked;
3740
3741         return res;
3742
3743 failure:
3744         mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
3745         klass->wastypebuilder = TRUE;
3746         mono_domain_unlock (domain);
3747         mono_loader_unlock ();
3748 failure_unlocked:
3749         return NULL;
3750 }
3751
3752 typedef struct {
3753         MonoMethod *handle;
3754         MonoDomain *domain;
3755 } DynamicMethodReleaseData;
3756
3757 /*
3758  * The runtime automatically clean up those after finalization.
3759 */      
3760 static MonoReferenceQueue *dynamic_method_queue;
3761
3762 static void
3763 free_dynamic_method (void *dynamic_method)
3764 {
3765         DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3766         MonoDomain *domain = data->domain;
3767         MonoMethod *method = data->handle;
3768         guint32 dis_link;
3769
3770         mono_domain_lock (domain);
3771         dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3772         g_hash_table_remove (domain->method_to_dyn_method, method);
3773         mono_domain_unlock (domain);
3774         g_assert (dis_link);
3775         mono_gchandle_free (dis_link);
3776
3777         mono_runtime_free_method (domain, method);
3778         g_free (data);
3779 }
3780
3781 static gboolean
3782 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
3783 {
3784         MonoReferenceQueue *queue;
3785         MonoMethod *handle;
3786         DynamicMethodReleaseData *release_data;
3787         ReflectionMethodBuilder rmb;
3788         MonoMethodSignature *sig;
3789         MonoClass *klass;
3790         MonoDomain *domain;
3791         GSList *l;
3792         int i;
3793
3794         error_init (error);
3795
3796         if (mono_runtime_is_shutting_down ()) {
3797                 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3798                 return FALSE;
3799         }
3800
3801         if (!(queue = dynamic_method_queue)) {
3802                 mono_loader_lock ();
3803                 if (!(queue = dynamic_method_queue))
3804                         queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3805                 mono_loader_unlock ();
3806         }
3807
3808         sig = dynamic_method_to_signature (ref_mb, error);
3809         return_val_if_nok (error, FALSE);
3810
3811         MonoReflectionDynamicMethod *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
3812         reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3813
3814         /*
3815          * Resolve references.
3816          */
3817         /* 
3818          * Every second entry in the refs array is reserved for storing handle_class,
3819          * which is needed by the ldtoken implementation in the JIT.
3820          */
3821         rmb.nrefs = mb->nrefs;
3822         rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3823         for (i = 0; i < mb->nrefs; i += 2) {
3824                 MonoClass *handle_class;
3825                 gpointer ref;
3826                 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3827
3828                 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3829                         MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3830                         /*
3831                          * The referenced DynamicMethod should already be created by the managed
3832                          * code, except in the case of circular references. In that case, we store
3833                          * method in the refs array, and fix it up later when the referenced 
3834                          * DynamicMethod is created.
3835                          */
3836                         if (method->mhandle) {
3837                                 ref = method->mhandle;
3838                         } else {
3839                                 /* FIXME: GC object stored in unmanaged memory */
3840                                 ref = method;
3841
3842                                 /* FIXME: GC object stored in unmanaged memory */
3843                                 method->referenced_by = g_slist_append (method->referenced_by, mb);
3844                         }
3845                         handle_class = mono_defaults.methodhandle_class;
3846                 } else {
3847                         MonoException *ex = NULL;
3848                         ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3849                         if (!is_ok  (error)) {
3850                                 g_free (rmb.refs);
3851                                 return FALSE;
3852                         }
3853                         if (!ref)
3854                                 ex = mono_get_exception_type_load (NULL, NULL);
3855                         else if (mono_security_core_clr_enabled ())
3856                                 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3857
3858                         if (ex) {
3859                                 g_free (rmb.refs);
3860                                 mono_error_set_exception_instance (error, ex);
3861                                 return FALSE;
3862                         }
3863                 }
3864
3865                 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3866                 rmb.refs [i + 1] = handle_class;
3867         }               
3868
3869         if (mb->owner) {
3870                 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3871                 if (!is_ok (error)) {
3872                         g_free (rmb.refs);
3873                         return FALSE;
3874                 }
3875                 klass = mono_class_from_mono_type (owner_type);
3876         } else {
3877                 klass = mono_defaults.object_class;
3878         }
3879
3880         mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3881         g_free (rmb.refs);
3882         return_val_if_nok (error, FALSE);
3883
3884         release_data = g_new (DynamicMethodReleaseData, 1);
3885         release_data->handle = handle;
3886         release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3887         if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3888                 g_free (release_data);
3889
3890         /* Fix up refs entries pointing at us */
3891         for (l = mb->referenced_by; l; l = l->next) {
3892                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3893                 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3894                 gpointer *data;
3895                 
3896                 g_assert (method->mhandle);
3897
3898                 data = (gpointer*)wrapper->method_data;
3899                 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3900                         if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3901                                 data [i + 1] = mb->mhandle;
3902                 }
3903         }
3904         g_slist_free (mb->referenced_by);
3905
3906         /* ilgen is no longer needed */
3907         mb->ilgen = NULL;
3908
3909         domain = mono_domain_get ();
3910         mono_domain_lock (domain);
3911         if (!domain->method_to_dyn_method)
3912                 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3913         g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3914         mono_domain_unlock (domain);
3915
3916         return TRUE;
3917 }
3918
3919 void
3920 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
3921 {
3922         (void) reflection_create_dynamic_method (mb, error);
3923 }
3924
3925 #endif /* DISABLE_REFLECTION_EMIT */
3926
3927 MonoMethodSignature *
3928 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3929 {
3930         MonoMethodSignature *sig;
3931         g_assert (image_is_dynamic (image));
3932
3933         error_init (error);
3934
3935         sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
3936         if (sig)
3937                 return sig;
3938
3939         return mono_method_signature_checked (method, error);
3940 }
3941
3942 #ifndef DISABLE_REFLECTION_EMIT
3943
3944 /*
3945  * ensure_complete_type:
3946  *
3947  *   Ensure that KLASS is completed if it is a dynamic type, or references
3948  * dynamic types.
3949  */
3950 static void
3951 ensure_complete_type (MonoClass *klass, MonoError *error)
3952 {
3953         error_init (error);
3954
3955         if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
3956                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3957
3958                 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
3959                 return_if_nok (error);
3960
3961                 // Asserting here could break a lot of code
3962                 //g_assert (klass->wastypebuilder);
3963         }
3964
3965         if (mono_class_is_ginst (klass)) {
3966                 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
3967                 int i;
3968
3969                 for (i = 0; i < inst->type_argc; ++i) {
3970                         ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
3971                         return_if_nok (error);
3972                 }
3973         }
3974 }
3975
3976 gpointer
3977 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
3978 {
3979         MonoClass *oklass = obj->vtable->klass;
3980         gpointer result = NULL;
3981
3982         error_init (error);
3983
3984         if (strcmp (oklass->name, "String") == 0) {
3985                 result = mono_string_intern_checked ((MonoString*)obj, error);
3986                 return_val_if_nok (error, NULL);
3987                 *handle_class = mono_defaults.string_class;
3988                 g_assert (result);
3989         } else if (strcmp (oklass->name, "RuntimeType") == 0) {
3990                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
3991                 return_val_if_nok (error, NULL);
3992                 MonoClass *mc = mono_class_from_mono_type (type);
3993                 if (!mono_class_init (mc)) {
3994                         mono_error_set_for_class_failure (error, mc);
3995                         return NULL;
3996                 }
3997
3998                 if (context) {
3999                         MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4000                         return_val_if_nok (error, NULL);
4001
4002                         result = mono_class_from_mono_type (inflated);
4003                         mono_metadata_free_type (inflated);
4004                 } else {
4005                         result = mono_class_from_mono_type (type);
4006                 }
4007                 *handle_class = mono_defaults.typehandle_class;
4008                 g_assert (result);
4009         } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
4010                            strcmp (oklass->name, "MonoCMethod") == 0) {
4011                 result = ((MonoReflectionMethod*)obj)->method;
4012                 if (context) {
4013                         result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4014                         mono_error_assert_ok (error);
4015                 }
4016                 *handle_class = mono_defaults.methodhandle_class;
4017                 g_assert (result);
4018         } else if (strcmp (oklass->name, "MonoField") == 0) {
4019                 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4020
4021                 ensure_complete_type (field->parent, error);
4022                 return_val_if_nok (error, NULL);
4023
4024                 if (context) {
4025                         MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
4026                         return_val_if_nok (error, NULL);
4027
4028                         MonoClass *klass = mono_class_from_mono_type (inflated);
4029                         MonoClassField *inflated_field;
4030                         gpointer iter = NULL;
4031                         mono_metadata_free_type (inflated);
4032                         while ((inflated_field = mono_class_get_fields (klass, &iter))) {
4033                                 if (!strcmp (field->name, inflated_field->name))
4034                                         break;
4035                         }
4036                         g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4037                         result = inflated_field;
4038                 } else {
4039                         result = field;
4040                 }
4041                 *handle_class = mono_defaults.fieldhandle_class;
4042                 g_assert (result);
4043         } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
4044                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
4045                 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4046                 return_val_if_nok (error, NULL);
4047                 MonoClass *klass;
4048
4049                 klass = type->data.klass;
4050                 if (klass->wastypebuilder) {
4051                         /* Already created */
4052                         result = klass;
4053                 }
4054                 else {
4055                         mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4056                         return_val_if_nok (error, NULL);
4057                         result = type->data.klass;
4058                         g_assert (result);
4059                 }
4060                 *handle_class = mono_defaults.typehandle_class;
4061         } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
4062                 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4063                 MonoMethodSignature *sig;
4064                 int nargs, i;
4065
4066                 if (helper->arguments)
4067                         nargs = mono_array_length (helper->arguments);
4068                 else
4069                         nargs = 0;
4070
4071                 sig = mono_metadata_signature_alloc (image, nargs);
4072                 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4073                 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4074
4075                 if (helper->unmanaged_call_conv) { /* unmanaged */
4076                         sig->call_convention = helper->unmanaged_call_conv - 1;
4077                         sig->pinvoke = TRUE;
4078                 } else if (helper->call_conv & 0x02) {
4079                         sig->call_convention = MONO_CALL_VARARG;
4080                 } else {
4081                         sig->call_convention = MONO_CALL_DEFAULT;
4082                 }
4083
4084                 sig->param_count = nargs;
4085                 /* TODO: Copy type ? */
4086                 sig->ret = helper->return_type->type;
4087                 for (i = 0; i < nargs; ++i) {
4088                         sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
4089                         if (!is_ok (error)) {
4090                                 image_g_free (image, sig);
4091                                 return NULL;
4092                         }
4093                 }
4094
4095                 result = sig;
4096                 *handle_class = NULL;
4097         } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4098                 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4099                 /* Already created by the managed code */
4100                 g_assert (method->mhandle);
4101                 result = method->mhandle;
4102                 *handle_class = mono_defaults.methodhandle_class;
4103         } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4104                 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4105                 MonoType *mtype;
4106                 MonoClass *klass;
4107                 MonoMethod *method;
4108                 gpointer iter;
4109                 char *name;
4110
4111                 mtype = mono_reflection_type_get_handle (m->parent, error);
4112                 return_val_if_nok (error, NULL);
4113                 klass = mono_class_from_mono_type (mtype);
4114
4115                 /* Find the method */
4116
4117                 name = mono_string_to_utf8_checked (m->name, error);
4118                 return_val_if_nok (error, NULL);
4119                 iter = NULL;
4120                 while ((method = mono_class_get_methods (klass, &iter))) {
4121                         if (!strcmp (method->name, name))
4122                                 break;
4123                 }
4124                 g_free (name);
4125
4126                 // FIXME:
4127                 g_assert (method);
4128                 // FIXME: Check parameters/return value etc. match
4129
4130                 result = method;
4131                 *handle_class = mono_defaults.methodhandle_class;
4132         } else if (is_sre_method_builder (oklass) ||
4133                            mono_is_sre_ctor_builder (oklass) ||
4134                            is_sre_field_builder (oklass) ||
4135                            is_sre_gparam_builder (oklass) ||
4136                            is_sre_generic_instance (oklass) ||
4137                            is_sre_array (oklass) ||
4138                            is_sre_byref (oklass) ||
4139                            is_sre_pointer (oklass) ||
4140                            !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4141                            !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4142                            !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4143                 static MonoMethod *resolve_method;
4144                 if (!resolve_method) {
4145                         MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4146                         g_assert (m);
4147                         mono_memory_barrier ();
4148                         resolve_method = m;
4149                 }
4150                 void *args [16];
4151                 args [0] = obj;
4152                 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4153                 mono_error_assert_ok (error);
4154                 g_assert (obj);
4155                 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
4156         } else {
4157                 g_print ("%s\n", obj->vtable->klass->name);
4158                 g_assert_not_reached ();
4159         }
4160         return result;
4161 }
4162
4163 #else /* DISABLE_REFLECTION_EMIT */
4164
4165 MonoArray*
4166 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
4167 {
4168         g_assert_not_reached ();
4169         return NULL;
4170 }
4171
4172 void
4173 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4174 {
4175         g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4176 }
4177
4178 static gboolean
4179 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4180 {
4181         g_assert_not_reached ();
4182         return FALSE;
4183 }
4184
4185 guint32
4186 mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4187 {
4188         g_assert_not_reached ();
4189         return 0;
4190 }
4191
4192 guint32
4193 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
4194 {
4195         g_assert_not_reached ();
4196         return 0;
4197 }
4198
4199 guint32
4200 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, 
4201                          gboolean create_open_instance, gboolean register_token, MonoError *error)
4202 {
4203         g_assert_not_reached ();
4204         return 0;
4205 }
4206
4207 void
4208 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4209 {
4210         error_init (error);
4211         *overrides = NULL;
4212         *num_overrides = 0;
4213 }
4214
4215 MonoReflectionTypeHandle
4216 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
4217 {
4218         g_assert_not_reached ();
4219         return NULL;
4220 }
4221
4222 void 
4223 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4224 {
4225         error_init (error);
4226 }
4227
4228 MonoType*
4229 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4230 {
4231         error_init (error);
4232         if (!ref)
4233                 return NULL;
4234         return ref->type;
4235 }
4236
4237 MonoType*
4238 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
4239 {
4240         error_init (error);
4241         if (MONO_HANDLE_IS_NULL (ref))
4242                 return NULL;
4243         return MONO_HANDLE_GETVAL (ref, type);
4244 }
4245
4246
4247 #endif /* DISABLE_REFLECTION_EMIT */
4248
4249 void
4250 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4251 {
4252         mono_gc_deregister_root ((char*) &entry->gparam);
4253         g_free (entry);
4254 }
4255
4256 gint32
4257 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
4258 {
4259         error_init (error);
4260         if (MONO_HANDLE_IS_NULL (obj)) {
4261                 mono_error_set_argument_null (error, "obj", "");
4262                 return 0;
4263         }
4264         return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
4265 }
4266
4267 gint32
4268 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
4269                                         MonoReflectionMethodHandle method,
4270                                         MonoArrayHandle opt_param_types,
4271                                         MonoError *error)
4272 {
4273         error_init (error);
4274         if (MONO_HANDLE_IS_NULL (method)) {
4275                 mono_error_set_argument_null (error, "method", "");
4276                 return 0;
4277         }
4278
4279         return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
4280 }
4281
4282 void
4283 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4284 {
4285         MonoError error;
4286         mono_image_create_pefile (mb, file, &error);
4287         mono_error_set_pending_exception (&error);
4288 }
4289
4290 void
4291 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4292 {
4293         MonoError error;
4294         mono_image_build_metadata (mb, &error);
4295         mono_error_set_pending_exception (&error);
4296 }
4297
4298 void
4299 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
4300 {
4301         error_init (error);
4302         mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj);
4303 }
4304
4305 MonoObject*
4306 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
4307 {
4308         MonoObject *obj;
4309
4310         mono_loader_lock ();
4311         obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
4312         mono_loader_unlock ();
4313
4314         return obj;
4315 }
4316
4317 #ifndef DISABLE_REFLECTION_EMIT
4318 MonoArray*
4319 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4320 {
4321         MonoError error;
4322         MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4323         mono_error_set_pending_exception (&error);
4324         return result;
4325 }
4326 #endif
4327
4328 void
4329 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4330 {
4331         mono_reflection_dynimage_basic_init (assemblyb);
4332 }
4333
4334 void
4335 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
4336                                                                            MonoReflectionType *t)
4337 {
4338         enumtype->type = t->type;
4339 }
4340
4341 void
4342 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4343 {
4344         error_init (error);
4345         mono_image_module_basic_init (moduleb, error);
4346 }
4347
4348 guint32
4349 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4350 {
4351         return mono_image_insert_string (module, str, error);
4352 }
4353
4354 void
4355 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
4356 {
4357         MonoDynamicImage *image = moduleb->dynamic_image;
4358
4359         g_assert (type->type);
4360         image->wrappers_type = mono_class_from_mono_type (type->type);
4361 }