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