Merge pull request #4851 from kumpera/handle_eloop_errno
[mono.git] / mono / metadata / sre-encode.c
1 /**
2  * \file
3  * Routines for encoding SRE builders into a
4  * MonoDynamicImage and generating tokens.
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
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/object-internals.h"
23 #include "mono/metadata/reflection-internals.h"
24 #include "mono/metadata/sre-internals.h"
25 #include "mono/metadata/tabledefs.h"
26 #include "mono/metadata/tokentype.h"
27 #include "mono/utils/checked-build.h"
28
29 typedef struct {
30         char *p;
31         char *buf;
32         char *end;
33 } SigBuffer;
34
35 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
36 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
37 static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
38
39 static guint32
40 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
41 {
42         return mono_dynstream_add_data (stream, data, len);
43 }
44
45 static void
46 alloc_table (MonoDynamicTable *table, guint nrows)
47 {
48         mono_dynimage_alloc_table (table, nrows);
49 }
50
51 static void
52 sigbuffer_init (SigBuffer *buf, int size)
53 {
54         MONO_REQ_GC_NEUTRAL_MODE;
55
56         buf->buf = (char *)g_malloc (size);
57         buf->p = buf->buf;
58         buf->end = buf->buf + size;
59 }
60
61 static void
62 sigbuffer_make_room (SigBuffer *buf, int size)
63 {
64         MONO_REQ_GC_NEUTRAL_MODE;
65
66         if (buf->end - buf->p < size) {
67                 int new_size = buf->end - buf->buf + size + 32;
68                 char *p = (char *)g_realloc (buf->buf, new_size);
69                 size = buf->p - buf->buf;
70                 buf->buf = p;
71                 buf->p = p + size;
72                 buf->end = buf->buf + new_size;
73         }
74 }
75
76 static void
77 sigbuffer_add_value (SigBuffer *buf, guint32 val)
78 {
79         MONO_REQ_GC_NEUTRAL_MODE;
80
81         sigbuffer_make_room (buf, 6);
82         mono_metadata_encode_value (val, buf->p, &buf->p);
83 }
84
85 static void
86 sigbuffer_add_byte (SigBuffer *buf, guint8 val)
87 {
88         MONO_REQ_GC_NEUTRAL_MODE;
89
90         sigbuffer_make_room (buf, 1);
91         buf->p [0] = val;
92         buf->p++;
93 }
94
95 static void
96 sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
97 {
98         MONO_REQ_GC_NEUTRAL_MODE;
99
100         sigbuffer_make_room (buf, size);
101         memcpy (buf->p, p, size);
102         buf->p += size;
103 }
104
105 static void
106 sigbuffer_free (SigBuffer *buf)
107 {
108         MONO_REQ_GC_NEUTRAL_MODE;
109
110         g_free (buf->buf);
111 }
112
113 static guint32
114 sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
115 {
116         MONO_REQ_GC_NEUTRAL_MODE;
117
118         char blob_size [8];
119         char *b = blob_size;
120         guint32 size = buf->p - buf->buf;
121         /* store length */
122         g_assert (size <= (buf->end - buf->buf));
123         mono_metadata_encode_value (size, b, &b);
124         return mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
125 }
126
127
128 static void
129 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
130 {
131         MONO_REQ_GC_NEUTRAL_MODE;
132
133         int i;
134         MonoGenericInst *class_inst;
135         MonoClass *klass;
136
137         g_assert (gclass);
138
139         class_inst = gclass->context.class_inst;
140
141         sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
142         klass = gclass->container_class;
143         sigbuffer_add_value (buf, klass->byval_arg.type);
144         sigbuffer_add_value (buf, mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
145
146         sigbuffer_add_value (buf, class_inst->type_argc);
147         for (i = 0; i < class_inst->type_argc; ++i)
148                 encode_type (assembly, class_inst->type_argv [i], buf);
149
150 }
151
152 static void
153 encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
154 {
155         MONO_REQ_GC_NEUTRAL_MODE;
156
157         if (!type) {
158                 g_assert_not_reached ();
159                 return;
160         }
161                 
162         if (type->byref)
163                 sigbuffer_add_value (buf, MONO_TYPE_BYREF);
164
165         switch (type->type){
166         case MONO_TYPE_VOID:
167         case MONO_TYPE_BOOLEAN:
168         case MONO_TYPE_CHAR:
169         case MONO_TYPE_I1:
170         case MONO_TYPE_U1:
171         case MONO_TYPE_I2:
172         case MONO_TYPE_U2:
173         case MONO_TYPE_I4:
174         case MONO_TYPE_U4:
175         case MONO_TYPE_I8:
176         case MONO_TYPE_U8:
177         case MONO_TYPE_R4:
178         case MONO_TYPE_R8:
179         case MONO_TYPE_I:
180         case MONO_TYPE_U:
181         case MONO_TYPE_STRING:
182         case MONO_TYPE_OBJECT:
183         case MONO_TYPE_TYPEDBYREF:
184                 sigbuffer_add_value (buf, type->type);
185                 break;
186         case MONO_TYPE_PTR:
187                 sigbuffer_add_value (buf, type->type);
188                 encode_type (assembly, type->data.type, buf);
189                 break;
190         case MONO_TYPE_SZARRAY:
191                 sigbuffer_add_value (buf, type->type);
192                 encode_type (assembly, &type->data.klass->byval_arg, buf);
193                 break;
194         case MONO_TYPE_VALUETYPE:
195         case MONO_TYPE_CLASS: {
196                 MonoClass *k = mono_class_from_mono_type (type);
197
198                 if (mono_class_is_gtd (k)) {
199                         MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, mono_class_get_generic_container (k)->context.class_inst, TRUE);
200                         encode_generic_class (assembly, gclass, buf);
201                 } else {
202                         /*
203                          * Make sure we use the correct type.
204                          */
205                         sigbuffer_add_value (buf, k->byval_arg.type);
206                         /*
207                          * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
208                          * otherwise two typerefs could point to the same type, leading to
209                          * verification errors.
210                          */
211                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
212                 }
213                 break;
214         }
215         case MONO_TYPE_ARRAY:
216                 sigbuffer_add_value (buf, type->type);
217                 encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
218                 sigbuffer_add_value (buf, type->data.array->rank);
219                 sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
220                 sigbuffer_add_value (buf, 0);
221                 break;
222         case MONO_TYPE_GENERICINST:
223                 encode_generic_class (assembly, type->data.generic_class, buf);
224                 break;
225         case MONO_TYPE_VAR:
226         case MONO_TYPE_MVAR:
227                 sigbuffer_add_value (buf, type->type);
228                 sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
229                 break;
230         default:
231                 g_error ("need to encode type %x", type->type);
232         }
233 }
234
235 static void
236 encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionTypeHandle type, SigBuffer *buf, MonoError *error)
237 {
238         MONO_REQ_GC_UNSAFE_MODE;
239
240         error_init (error);
241
242         if (!type) {
243                 sigbuffer_add_value (buf, MONO_TYPE_VOID);
244                 return;
245         }
246
247         MonoType *t = mono_reflection_type_handle_mono_type (type, error);
248         return_if_nok (error);
249         encode_type (assembly, t, buf);
250 }
251
252 static void
253 encode_reflection_type_raw (MonoDynamicImage *assembly, MonoReflectionType* type_raw, SigBuffer *buf, MonoError *error)
254 {
255         HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_reflection_type_raw should use handles */
256         error_init (error);
257         MONO_HANDLE_DCL (MonoReflectionType, type);
258         encode_reflection_type (assembly, type, buf, error);
259         HANDLE_FUNCTION_RETURN ();
260 }
261
262
263 static void
264 encode_custom_modifiers (MonoDynamicImage *assembly, MonoArrayHandle modreq, MonoArrayHandle modopt, SigBuffer *buf, MonoError *error)
265 {
266         HANDLE_FUNCTION_ENTER ();
267         MONO_REQ_GC_UNSAFE_MODE;
268
269         int i;
270
271         error_init (error);
272
273         if (!MONO_HANDLE_IS_NULL (modreq)) {
274                 for (i = 0; i < mono_array_handle_length (modreq); ++i) {
275                         MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
276                         if (!is_ok (error))
277                                 goto leave;
278                         sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
279                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
280                 }
281         }
282         if (!MONO_HANDLE_IS_NULL (modopt)) {
283                 for (i = 0; i < mono_array_handle_length (modopt); ++i) {
284                         MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
285                         if (!is_ok (error))
286                                 goto leave;
287                         sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
288                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
289                 }
290         }
291 leave:
292         HANDLE_FUNCTION_RETURN ();
293 }
294
295 static void
296 encode_custom_modifiers_raw (MonoDynamicImage *assembly, MonoArray *modreq_raw, MonoArray *modopt_raw, SigBuffer *buf, MonoError *error)
297 {
298         HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_custom_modifiers_raw should use handles */
299         error_init (error);
300         MONO_HANDLE_DCL (MonoArray, modreq);
301         MONO_HANDLE_DCL (MonoArray, modopt);
302         encode_custom_modifiers (assembly, modreq, modopt, buf, error);
303         HANDLE_FUNCTION_RETURN ();
304 }
305
306
307 #ifndef DISABLE_REFLECTION_EMIT
308 guint32
309 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
310 {
311         MONO_REQ_GC_UNSAFE_MODE;
312
313         SigBuffer buf;
314         int i;
315         guint32 nparams =  sig->param_count;
316         guint32 idx;
317
318         if (!assembly->save)
319                 return 0;
320
321         sigbuffer_init (&buf, 32);
322         /*
323          * FIXME: vararg, explicit_this, differenc call_conv values...
324          */
325         idx = sig->call_convention;
326         if (sig->hasthis)
327                 idx |= 0x20; /* hasthis */
328         if (sig->generic_param_count)
329                 idx |= 0x10; /* generic */
330         sigbuffer_add_byte (&buf, idx);
331         if (sig->generic_param_count)
332                 sigbuffer_add_value (&buf, sig->generic_param_count);
333         sigbuffer_add_value (&buf, nparams);
334         encode_type (assembly, sig->ret, &buf);
335         for (i = 0; i < nparams; ++i) {
336                 if (i == sig->sentinelpos)
337                         sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
338                 encode_type (assembly, sig->params [i], &buf);
339         }
340         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
341         sigbuffer_free (&buf);
342         return idx;
343 }
344 #else /* DISABLE_REFLECTION_EMIT */
345 guint32
346 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
347 {
348         g_assert_not_reached ();
349         return 0;
350 }
351 #endif
352
353 guint32
354 mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
355 {
356         MONO_REQ_GC_UNSAFE_MODE;
357
358         error_init (error);
359
360         /*
361          * FIXME: reuse code from method_encode_signature().
362          */
363         SigBuffer buf;
364         int i;
365         guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
366         guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
367         guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
368         guint32 idx;
369
370         sigbuffer_init (&buf, 32);
371         /* LAMESPEC: all the call conv spec is foobared */
372         idx = mb->call_conv & 0x60; /* has-this, explicit-this */
373         if (mb->call_conv & 2)
374                 idx |= 0x5; /* vararg */
375         if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
376                 idx |= 0x20; /* hasthis */
377         if (ngparams)
378                 idx |= 0x10; /* generic */
379         sigbuffer_add_byte (&buf, idx);
380         if (ngparams)
381                 sigbuffer_add_value (&buf, ngparams);
382         sigbuffer_add_value (&buf, nparams + notypes);
383         encode_custom_modifiers_raw (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
384         if (!is_ok (error))
385                 goto leave;
386         encode_reflection_type_raw (assembly, mb->rtype, &buf, error);
387         if (!is_ok (error))
388                 goto leave;
389         for (i = 0; i < nparams; ++i) {
390                 MonoArray *modreq = NULL;
391                 MonoArray *modopt = NULL;
392                 MonoReflectionType *pt;
393
394                 if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
395                         modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
396                 if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
397                         modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
398                 encode_custom_modifiers_raw (assembly, modreq, modopt, &buf, error);
399                 if (!is_ok (error))
400                         goto leave;
401                 pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
402                 encode_reflection_type_raw (assembly, pt, &buf, error);
403                 if (!is_ok (error))
404                         goto leave;
405         }
406         if (notypes)
407                 sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
408         for (i = 0; i < notypes; ++i) {
409                 MonoReflectionType *pt;
410
411                 pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
412                 encode_reflection_type_raw (assembly, pt, &buf, error);
413                 if (!is_ok (error))
414                         goto leave;
415         }
416
417         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
418 leave:
419         sigbuffer_free (&buf);
420         return idx;
421 }
422
423 guint32
424 mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
425 {
426         MONO_REQ_GC_UNSAFE_MODE;
427
428         error_init (error);
429
430         MonoDynamicTable *table;
431         guint32 *values;
432         guint32 idx, sig_idx;
433         guint nl = mono_array_length (ilgen->locals);
434         SigBuffer buf;
435         int i;
436
437         sigbuffer_init (&buf, 32);
438         sigbuffer_add_value (&buf, 0x07);
439         sigbuffer_add_value (&buf, nl);
440         for (i = 0; i < nl; ++i) {
441                 MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
442                 
443                 if (lb->is_pinned)
444                         sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
445                 
446                 encode_reflection_type_raw (assembly, (MonoReflectionType*)lb->type, &buf, error);
447                 if (!is_ok (error)) {
448                         sigbuffer_free (&buf);
449                         return 0;
450                 }
451         }
452         sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
453         sigbuffer_free (&buf);
454
455         if (assembly->standalonesig_cache == NULL)
456                 assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
457         idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
458         if (idx)
459                 return idx;
460
461         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
462         idx = table->next_idx ++;
463         table->rows ++;
464         alloc_table (table, table->rows);
465         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
466
467         values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
468
469         g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
470
471         return idx;
472 }
473
474
475 /*
476  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
477  * dest may be misaligned.
478  */
479 static void
480 swap_with_size (char *dest, const char* val, int len, int nelem) {
481         MONO_REQ_GC_NEUTRAL_MODE;
482 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
483         int elem;
484
485         for (elem = 0; elem < nelem; ++elem) {
486                 switch (len) {
487                 case 1:
488                         *dest = *val;
489                         break;
490                 case 2:
491                         dest [0] = val [1];
492                         dest [1] = val [0];
493                         break;
494                 case 4:
495                         dest [0] = val [3];
496                         dest [1] = val [2];
497                         dest [2] = val [1];
498                         dest [3] = val [0];
499                         break;
500                 case 8:
501                         dest [0] = val [7];
502                         dest [1] = val [6];
503                         dest [2] = val [5];
504                         dest [3] = val [4];
505                         dest [4] = val [3];
506                         dest [5] = val [2];
507                         dest [6] = val [1];
508                         dest [7] = val [0];
509                         break;
510                 default:
511                         g_assert_not_reached ();
512                 }
513                 dest += len;
514                 val += len;
515         }
516 #else
517         memcpy (dest, val, len * nelem);
518 #endif
519 }
520
521
522 guint32
523 mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
524 {
525         MONO_REQ_GC_UNSAFE_MODE;
526
527         char blob_size [64];
528         char *b = blob_size;
529         char *box_val;
530         char* buf;
531         guint32 idx = 0, len = 0, dummy = 0;
532
533         buf = (char *)g_malloc (64);
534         if (!val) {
535                 *ret_type = MONO_TYPE_CLASS;
536                 len = 4;
537                 box_val = (char*)&dummy;
538         } else {
539                 box_val = ((char*)val) + sizeof (MonoObject);
540                 *ret_type = val->vtable->klass->byval_arg.type;
541         }
542 handle_enum:
543         switch (*ret_type) {
544         case MONO_TYPE_BOOLEAN:
545         case MONO_TYPE_U1:
546         case MONO_TYPE_I1:
547                 len = 1;
548                 break;
549         case MONO_TYPE_CHAR:
550         case MONO_TYPE_U2:
551         case MONO_TYPE_I2:
552                 len = 2;
553                 break;
554         case MONO_TYPE_U4:
555         case MONO_TYPE_I4:
556         case MONO_TYPE_R4:
557                 len = 4;
558                 break;
559         case MONO_TYPE_U8:
560         case MONO_TYPE_I8:
561                 len = 8;
562                 break;
563         case MONO_TYPE_R8:
564                 len = 8;
565                 break;
566         case MONO_TYPE_VALUETYPE: {
567                 MonoClass *klass = val->vtable->klass;
568                 
569                 if (klass->enumtype) {
570                         *ret_type = mono_class_enum_basetype (klass)->type;
571                         goto handle_enum;
572                 } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
573                         len = 8;
574                 } else 
575                         g_error ("we can't encode valuetypes, we should have never reached this line");
576                 break;
577         }
578         case MONO_TYPE_CLASS:
579                 break;
580         case MONO_TYPE_STRING: {
581                 MonoString *str = (MonoString*)val;
582                 /* there is no signature */
583                 len = str->length * 2;
584                 mono_metadata_encode_value (len, b, &b);
585 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
586                 {
587                         char *swapped = g_malloc (2 * mono_string_length (str));
588                         const char *p = (const char*)mono_string_chars (str);
589
590                         swap_with_size (swapped, p, 2, mono_string_length (str));
591                         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
592                         g_free (swapped);
593                 }
594 #else
595                 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
596 #endif
597
598                 g_free (buf);
599                 return idx;
600         }
601         case MONO_TYPE_GENERICINST:
602                 *ret_type = mono_class_get_generic_class (val->vtable->klass)->container_class->byval_arg.type;
603                 goto handle_enum;
604         default:
605                 g_error ("we don't encode constant type 0x%02x yet", *ret_type);
606         }
607
608         /* there is no signature */
609         mono_metadata_encode_value (len, b, &b);
610 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
611         idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
612         swap_with_size (blob_size, box_val, len, 1);
613         mono_image_add_stream_data (&assembly->blob, blob_size, len);
614 #else
615         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
616 #endif
617
618         g_free (buf);
619         return idx;
620 }
621
622 guint32
623 mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
624 {
625         MONO_REQ_GC_UNSAFE_MODE;
626
627         error_init (error);
628
629         SigBuffer buf;
630         guint32 idx;
631         guint32 typespec = 0;
632         MonoType *type;
633         MonoClass *klass;
634
635         type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
636         return_val_if_nok (error, 0);
637         klass = mono_class_from_mono_type (type);
638
639         sigbuffer_init (&buf, 32);
640         
641         sigbuffer_add_value (&buf, 0x06);
642         encode_custom_modifiers_raw (assembly, fb->modreq, fb->modopt, &buf, error);
643         if (!is_ok (error))
644                 goto fail;
645         /* encode custom attributes before the type */
646
647         if (mono_class_is_gtd (klass))
648                 typespec = create_typespec (assembly, type);
649
650         if (typespec) {
651                 MonoGenericClass *gclass;
652                 gclass = mono_metadata_lookup_generic_class (klass, mono_class_get_generic_container (klass)->context.class_inst, TRUE);
653                 encode_generic_class (assembly, gclass, &buf);
654         } else {
655                 encode_type (assembly, type, &buf);
656         }
657         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
658         sigbuffer_free (&buf);
659         return idx;
660 fail:
661         sigbuffer_free (&buf);
662         return 0;
663 }
664
665 #ifndef DISABLE_REFLECTION_EMIT
666 /*field_image is the image to which the eventual custom mods have been encoded against*/
667 guint32
668 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
669 {
670         MONO_REQ_GC_NEUTRAL_MODE;
671
672         SigBuffer buf;
673         guint32 idx, i, token;
674
675         if (!assembly->save)
676                 return 0;
677
678         sigbuffer_init (&buf, 32);
679         
680         sigbuffer_add_value (&buf, 0x06);
681         /* encode custom attributes before the type */
682         if (type->num_mods) {
683                 for (i = 0; i < type->num_mods; ++i) {
684                         if (field_image) {
685                                 MonoError error;
686                                 MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
687                                 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
688
689                                 token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
690                         } else {
691                                 token = type->modifiers [i].token;
692                         }
693
694                         if (type->modifiers [i].required)
695                                 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
696                         else
697                                 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
698
699                         sigbuffer_add_value (&buf, token);
700                 }
701         }
702         encode_type (assembly, type, &buf);
703         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
704         sigbuffer_free (&buf);
705         return idx;
706 }
707 #else /* DISABLE_REFLECTION_EMIT */
708 guint32
709 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
710 {
711         g_assert_not_reached ();
712         return 0;
713 }
714 #endif /* DISABLE_REFLECTION_EMIT */
715
716 static guint32
717 create_typespec (MonoDynamicImage *assembly, MonoType *type)
718 {
719         MONO_REQ_GC_NEUTRAL_MODE;
720
721         MonoDynamicTable *table;
722         guint32 *values;
723         guint32 token;
724         SigBuffer buf;
725
726         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
727                 return token;
728
729         sigbuffer_init (&buf, 32);
730         switch (type->type) {
731         case MONO_TYPE_FNPTR:
732         case MONO_TYPE_PTR:
733         case MONO_TYPE_SZARRAY:
734         case MONO_TYPE_ARRAY:
735         case MONO_TYPE_VAR:
736         case MONO_TYPE_MVAR:
737         case MONO_TYPE_GENERICINST:
738                 encode_type (assembly, type, &buf);
739                 break;
740         case MONO_TYPE_CLASS:
741         case MONO_TYPE_VALUETYPE: {
742                 MonoClass *k = mono_class_from_mono_type (type);
743                 if (!k || !mono_class_is_gtd (k)) {
744                         sigbuffer_free (&buf);
745                         return 0;
746                 }
747                 encode_type (assembly, type, &buf);
748                 break;
749         }
750         default:
751                 sigbuffer_free (&buf);
752                 return 0;
753         }
754
755         table = &assembly->tables [MONO_TABLE_TYPESPEC];
756         if (assembly->save) {
757                 token = sigbuffer_add_to_blob_cached (assembly, &buf);
758                 alloc_table (table, table->rows + 1);
759                 values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
760                 values [MONO_TYPESPEC_SIGNATURE] = token;
761         }
762         sigbuffer_free (&buf);
763
764         token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
765         g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
766         table->next_idx ++;
767         return token;
768 }
769
770 guint32
771 mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
772 {
773         MONO_REQ_GC_UNSAFE_MODE;
774         HANDLE_FUNCTION_ENTER ();
775
776         MonoDynamicTable *table;
777         guint32 *values;
778         guint32 token, scope, enclosing;
779         MonoClass *klass;
780
781         /* if the type requires a typespec, we must try that first*/
782         if (try_typespec && (token = create_typespec (assembly, type)))
783                 goto leave;
784         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
785         if (token)
786                 goto leave;
787         klass = mono_class_from_mono_type (type);
788
789         MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, mono_class_get_ref_info (klass));
790         /*
791          * If it's in the same module and not a generic type parameter:
792          */
793         if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && 
794                         (type->type != MONO_TYPE_MVAR)) {
795                 token = MONO_TYPEDEFORREF_TYPEDEF | (MONO_HANDLE_GETVAL (tb, table_idx) << MONO_TYPEDEFORREF_BITS);
796                 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb));
797                 goto leave;
798         }
799
800         if (klass->nested_in) {
801                 enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
802                 /* get the typeref idx of the enclosing type */
803                 enclosing >>= MONO_TYPEDEFORREF_BITS;
804                 scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
805         } else {
806                 scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
807         }
808         table = &assembly->tables [MONO_TABLE_TYPEREF];
809         if (assembly->save) {
810                 alloc_table (table, table->rows + 1);
811                 values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
812                 values [MONO_TYPEREF_SCOPE] = scope;
813                 values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, klass->name);
814                 values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, klass->name_space);
815         }
816         token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
817         g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
818         table->next_idx ++;
819         mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb));
820 leave:
821         HANDLE_FUNCTION_RETURN_VAL (token);
822 }
823
824 /*
825  * Despite the name, we handle also TypeSpec (with the above helper).
826  */
827 static guint32
828 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
829 {
830         return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
831 }
832
833 guint32
834 mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
835 {
836         SigBuffer buf;
837         int i;
838         guint32 nparams = context->method_inst->type_argc;
839         guint32 idx;
840
841         if (!assembly->save)
842                 return 0;
843
844         sigbuffer_init (&buf, 32);
845         /*
846          * FIXME: vararg, explicit_this, differenc call_conv values...
847          */
848         sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
849         sigbuffer_add_value (&buf, nparams);
850
851         for (i = 0; i < nparams; i++)
852                 encode_type (assembly, context->method_inst->type_argv [i], &buf);
853
854         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
855         sigbuffer_free (&buf);
856         return idx;
857 }
858
859 #ifndef DISABLE_REFLECTION_EMIT
860 static gboolean
861 encode_sighelper_arg (MonoDynamicImage *assembly, int i, MonoArrayHandle helper_arguments, MonoArrayHandle helper_modreqs, MonoArrayHandle helper_modopts, SigBuffer* buf, MonoError *error)
862 {
863         HANDLE_FUNCTION_ENTER();
864         error_init (error);
865         MonoArrayHandle modreqs = MONO_HANDLE_NEW (MonoArray, NULL);
866         MonoArrayHandle modopts = MONO_HANDLE_NEW (MonoArray, NULL);
867
868         if (!MONO_HANDLE_IS_NULL (helper_modreqs) && (i < mono_array_handle_length (helper_modreqs)))
869                 MONO_HANDLE_ARRAY_GETREF (modreqs, helper_modreqs, i);
870         if (!MONO_HANDLE_IS_NULL (helper_modopts) && (i < mono_array_handle_length (helper_modopts)))
871                 MONO_HANDLE_ARRAY_GETREF (modopts, helper_modopts, i);
872
873         encode_custom_modifiers (assembly, modreqs, modopts, buf, error);
874         if (!is_ok (error))
875                 goto leave;
876         MonoReflectionTypeHandle pt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
877         MONO_HANDLE_ARRAY_GETREF (pt, helper_arguments, i);
878         encode_reflection_type (assembly, pt, buf, error);
879         if (!is_ok (error))
880                 goto leave;
881 leave:
882         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
883 }
884
885 guint32
886 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
887 {
888         SigBuffer buf;
889         guint32 nargs;
890         guint32 i, idx;
891
892         error_init (error);
893
894         if (!assembly->save)
895                 return 0;
896
897         /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
898         g_assert (MONO_HANDLE_GETVAL (helper, type) == 2);
899
900         MonoArrayHandle arguments = MONO_HANDLE_NEW_GET (MonoArray, helper, arguments);
901         if (!MONO_HANDLE_IS_NULL (arguments))
902                 nargs = mono_array_handle_length (arguments);
903         else
904                 nargs = 0;
905
906         sigbuffer_init (&buf, 32);
907
908         /* Encode calling convention */
909         /* Change Any to Standard */
910         if ((MONO_HANDLE_GETVAL (helper, call_conv) & 0x03) == 0x03)
911                 MONO_HANDLE_SETVAL (helper, call_conv, guint32, 0x01);
912         /* explicit_this implies has_this */
913         if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x40)
914                 MONO_HANDLE_SETVAL (helper, call_conv, guint32, MONO_HANDLE_GETVAL (helper, call_conv) & 0x20);
915
916         if (MONO_HANDLE_GETVAL (helper, call_conv) == 0) { /* Unmanaged */
917                 idx = MONO_HANDLE_GETVAL (helper, unmanaged_call_conv) - 1;
918         } else {
919                 /* Managed */
920                 idx = MONO_HANDLE_GETVAL (helper, call_conv) & 0x60; /* has_this + explicit_this */
921                 if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x02) /* varargs */
922                         idx += 0x05;
923         }
924
925         sigbuffer_add_byte (&buf, idx);
926         sigbuffer_add_value (&buf, nargs);
927         encode_reflection_type (assembly, MONO_HANDLE_NEW_GET (MonoReflectionType, helper, return_type), &buf, error);
928         if (!is_ok (error))
929                 goto fail;
930         MonoArrayHandle modreqs = MONO_HANDLE_NEW_GET (MonoArray, helper, modreqs);
931         MonoArrayHandle modopts = MONO_HANDLE_NEW_GET (MonoArray, helper, modopts);
932         for (i = 0; i < nargs; ++i) {
933                 if (!encode_sighelper_arg (assembly, i, arguments, modreqs, modopts, &buf, error))
934                         goto fail;
935         }
936         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
937         sigbuffer_free (&buf);
938
939         return idx;
940 fail:
941         sigbuffer_free (&buf);
942         return 0;
943 }
944 #else /* DISABLE_REFLECTION_EMIT */
945 guint32
946 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
947 {
948         g_assert_not_reached ();
949         return 0;
950 }
951 #endif /* DISABLE_REFLECTION_EMIT */
952
953 static gboolean
954 encode_reflection_types (MonoDynamicImage *assembly, MonoArrayHandle sig_arguments, int i, SigBuffer *buf, MonoError *error)
955 {
956         HANDLE_FUNCTION_ENTER ();
957         error_init (error);
958         MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
959         MONO_HANDLE_ARRAY_GETREF (type, sig_arguments, i);
960         encode_reflection_type (assembly, type, buf, error);
961         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
962 }
963
964 static MonoArrayHandle
965 reflection_sighelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
966 {
967         MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
968         MonoDynamicImage *assembly = MONO_HANDLE_IS_NULL (module) ? NULL : MONO_HANDLE_GETVAL (module, dynamic_image);
969         MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
970         guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
971         guint32 buflen, i;
972         SigBuffer buf;
973
974         error_init (error);
975
976         sigbuffer_init (&buf, 32);
977
978         sigbuffer_add_value (&buf, 0x07);
979         sigbuffer_add_value (&buf, na);
980         if (assembly != NULL){
981                 for (i = 0; i < na; ++i) {
982                         if (!encode_reflection_types (assembly, sig_arguments, i, &buf, error))
983                                 goto fail;
984                 }
985         }
986
987         buflen = buf.p - buf.buf;
988         MonoArrayHandle result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
989         if (!is_ok (error)) goto fail;
990         uint32_t gchandle;
991         void *base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
992         memcpy (base, buf.buf, buflen);
993         sigbuffer_free (&buf);
994         mono_gchandle_free (gchandle);
995         return result;
996 fail:
997         sigbuffer_free (&buf);
998         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
999 }
1000
1001 static MonoArrayHandle
1002 reflection_sighelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1003 {
1004         MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
1005         MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (module, dynamic_image);
1006         MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
1007         guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
1008         guint32 buflen, i;
1009         SigBuffer buf;
1010
1011         error_init (error);
1012
1013         sigbuffer_init (&buf, 32);
1014
1015         sigbuffer_add_value (&buf, 0x06);
1016         for (i = 0; i < na; ++i) {
1017                 if (! encode_reflection_types (assembly, sig_arguments, i, &buf, error))
1018                         goto fail;
1019         }
1020
1021         buflen = buf.p - buf.buf;
1022         MonoArrayHandle result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
1023         if (!is_ok (error)) goto fail;
1024         uint32_t gchandle;
1025         void *base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
1026         memcpy (base, buf.buf, buflen);
1027         sigbuffer_free (&buf);
1028         mono_gchandle_free (gchandle);
1029
1030         return result;
1031 fail:
1032         sigbuffer_free (&buf);
1033         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1034 }
1035
1036 static char*
1037 type_get_fully_qualified_name (MonoType *type)
1038 {
1039         MONO_REQ_GC_NEUTRAL_MODE;
1040
1041         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1042 }
1043
1044 #ifndef DISABLE_REFLECTION_EMIT_SAVE
1045 guint32
1046 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1047 {
1048         MONO_REQ_GC_UNSAFE_MODE;
1049
1050         error_init (error);
1051
1052         char *str;
1053         SigBuffer buf;
1054         guint32 idx, len;
1055
1056         sigbuffer_init (&buf, 32);
1057
1058         sigbuffer_add_value (&buf, minfo->type);
1059
1060         switch (minfo->type) {
1061         case MONO_NATIVE_BYVALTSTR:
1062         case MONO_NATIVE_BYVALARRAY:
1063                 sigbuffer_add_value (&buf, minfo->count);
1064                 break;
1065         case MONO_NATIVE_LPARRAY:
1066                 if (minfo->eltype || minfo->has_size) {
1067                         sigbuffer_add_value (&buf, minfo->eltype);
1068                         if (minfo->has_size) {
1069                                 sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
1070                                 sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
1071
1072                                 /* LAMESPEC: ElemMult is undocumented */
1073                                 sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
1074                         }
1075                 }
1076                 break;
1077         case MONO_NATIVE_SAFEARRAY:
1078                 if (minfo->eltype)
1079                         sigbuffer_add_value (&buf, minfo->eltype);
1080                 break;
1081         case MONO_NATIVE_CUSTOM:
1082                 if (minfo->guid) {
1083                         str = mono_string_to_utf8_checked (minfo->guid, error);
1084                         if (!is_ok (error)) {
1085                                 sigbuffer_free (&buf);
1086                                 return 0;
1087                         }
1088                         len = strlen (str);
1089                         sigbuffer_add_value (&buf, len);
1090                         sigbuffer_add_mem (&buf, str, len);
1091                         g_free (str);
1092                 } else {
1093                         sigbuffer_add_value (&buf, 0);
1094                 }
1095                 /* native type name */
1096                 sigbuffer_add_value (&buf, 0);
1097                 /* custom marshaler type name */
1098                 if (minfo->marshaltype || minfo->marshaltyperef) {
1099                         if (minfo->marshaltyperef) {
1100                                 MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
1101                                 if (!is_ok (error)) {
1102                                         sigbuffer_free (&buf);
1103                                         return 0;
1104                                 }
1105                                 str = type_get_fully_qualified_name (marshaltype);
1106                         } else {
1107                                 str = mono_string_to_utf8_checked (minfo->marshaltype, error);
1108                                 if (!is_ok (error)) {
1109                                         sigbuffer_free (&buf);
1110                                         return 0;
1111                                 }
1112                         }
1113                         len = strlen (str);
1114                         sigbuffer_add_value (&buf, len);
1115                         sigbuffer_add_mem (&buf, str, len);
1116                         g_free (str);
1117                 } else {
1118                         /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
1119                         sigbuffer_add_value (&buf, 0);
1120                 }
1121                 if (minfo->mcookie) {
1122                         str = mono_string_to_utf8_checked (minfo->mcookie, error);
1123                         if (!is_ok (error)) {
1124                                 sigbuffer_free (&buf);
1125                                 return 0;
1126                         }
1127                         len = strlen (str);
1128                         sigbuffer_add_value (&buf, len);
1129                         sigbuffer_add_mem (&buf, str, len);
1130                         g_free (str);
1131                 } else {
1132                         sigbuffer_add_value (&buf, 0);
1133                 }
1134                 break;
1135         default:
1136                 break;
1137         }
1138         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1139         sigbuffer_free (&buf);
1140         return idx;
1141 }
1142
1143 guint32
1144 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1145 {
1146         MONO_REQ_GC_UNSAFE_MODE;
1147
1148         error_init (error);
1149
1150         SigBuffer buf;
1151         guint32 nparams = 0;
1152         MonoReflectionMethodBuilder *mb = fb->get_method;
1153         MonoReflectionMethodBuilder *smb = fb->set_method;
1154         guint32 idx, i;
1155
1156         if (mb && mb->parameters)
1157                 nparams = mono_array_length (mb->parameters);
1158         if (!mb && smb && smb->parameters)
1159                 nparams = mono_array_length (smb->parameters) - 1;
1160         sigbuffer_init (&buf, 32);
1161         if (fb->call_conv & 0x20)
1162                 sigbuffer_add_byte (&buf, 0x28);
1163         else
1164                 sigbuffer_add_byte (&buf, 0x08);
1165         sigbuffer_add_value (&buf, nparams);
1166         if (mb) {
1167                 encode_reflection_type_raw (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
1168                 if (!is_ok (error))
1169                         goto fail;
1170                 for (i = 0; i < nparams; ++i) {
1171                         MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
1172                         encode_reflection_type_raw (assembly, pt, &buf, error);
1173                         if (!is_ok (error))
1174                                 goto fail;
1175                 }
1176         } else if (smb && smb->parameters) {
1177                 /* the property type is the last param */
1178                 encode_reflection_type_raw (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
1179                 if (!is_ok (error))
1180                         goto fail;
1181
1182                 for (i = 0; i < nparams; ++i) {
1183                         MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
1184                         encode_reflection_type_raw (assembly, pt, &buf, error);
1185                         if (!is_ok (error))
1186                                 goto fail;
1187                 }
1188         } else {
1189                 encode_reflection_type_raw (assembly, (MonoReflectionType*)fb->type, &buf, error);
1190                 if (!is_ok (error))
1191                         goto fail;
1192         }
1193
1194         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1195         sigbuffer_free (&buf);
1196         return idx;
1197 fail:
1198         sigbuffer_free (&buf);
1199         return 0;
1200 }
1201
1202
1203 #else /*DISABLE_REFLECTION_EMIT_SAVE*/
1204 guint32
1205 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1206 {
1207         g_assert_not_reached ();
1208         return 0;
1209 }
1210
1211 guint32
1212 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1213 {
1214         g_assert_not_reached ();
1215         return 0;
1216 }
1217 #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
1218
1219 #ifndef DISABLE_REFLECTION_EMIT
1220 MonoArrayHandle
1221 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
1222 {
1223         error_init (error);
1224         return reflection_sighelper_get_signature_local (sig, error);
1225 }
1226
1227 MonoArrayHandle
1228 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1229 {
1230         error_init (error);
1231         return reflection_sighelper_get_signature_field (sig, error);
1232 }
1233 #else /* DISABLE_REFLECTION_EMIT */
1234 MonoArrayHandle
1235 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
1236 {
1237         error_init (error);
1238         g_assert_not_reached ();
1239         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1240 }
1241
1242 MonoArrayHandle
1243 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1244 {
1245         error_init (error);
1246         g_assert_not_reached ();
1247         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1248 }
1249
1250 #endif /* DISABLE_REFLECTION_EMIT */