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