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