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