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