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