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