Merge pull request #5714 from alexischr/update_bockbuild
[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                 /* This function is called multiple times from sre and sre-save, so same object is okay */
797                 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
798                 goto leave;
799         }
800
801         if (klass->nested_in) {
802                 enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
803                 /* get the typeref idx of the enclosing type */
804                 enclosing >>= MONO_TYPEDEFORREF_BITS;
805                 scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
806         } else {
807                 scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
808         }
809         table = &assembly->tables [MONO_TABLE_TYPEREF];
810         if (assembly->save) {
811                 alloc_table (table, table->rows + 1);
812                 values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
813                 values [MONO_TYPEREF_SCOPE] = scope;
814                 values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, klass->name);
815                 values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, klass->name_space);
816         }
817         token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
818         g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
819         table->next_idx ++;
820
821
822         if (!MONO_HANDLE_IS_NULL (tb)) {
823                 /* This function is called multiple times from sre and sre-save, so same object is okay */
824                 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
825         }
826
827 leave:
828         HANDLE_FUNCTION_RETURN_VAL (token);
829 }
830
831 /*
832  * Despite the name, we handle also TypeSpec (with the above helper).
833  */
834 static guint32
835 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
836 {
837         return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
838 }
839
840 guint32
841 mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
842 {
843         SigBuffer buf;
844         int i;
845         guint32 nparams = context->method_inst->type_argc;
846         guint32 idx;
847
848         if (!assembly->save)
849                 return 0;
850
851         sigbuffer_init (&buf, 32);
852         /*
853          * FIXME: vararg, explicit_this, differenc call_conv values...
854          */
855         sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
856         sigbuffer_add_value (&buf, nparams);
857
858         for (i = 0; i < nparams; i++)
859                 encode_type (assembly, context->method_inst->type_argv [i], &buf);
860
861         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
862         sigbuffer_free (&buf);
863         return idx;
864 }
865
866 #ifndef DISABLE_REFLECTION_EMIT
867 static gboolean
868 encode_sighelper_arg (MonoDynamicImage *assembly, int i, MonoArrayHandle helper_arguments, MonoArrayHandle helper_modreqs, MonoArrayHandle helper_modopts, SigBuffer* buf, MonoError *error)
869 {
870         HANDLE_FUNCTION_ENTER();
871         error_init (error);
872         MonoArrayHandle modreqs = MONO_HANDLE_NEW (MonoArray, NULL);
873         MonoArrayHandle modopts = MONO_HANDLE_NEW (MonoArray, NULL);
874
875         if (!MONO_HANDLE_IS_NULL (helper_modreqs) && (i < mono_array_handle_length (helper_modreqs)))
876                 MONO_HANDLE_ARRAY_GETREF (modreqs, helper_modreqs, i);
877         if (!MONO_HANDLE_IS_NULL (helper_modopts) && (i < mono_array_handle_length (helper_modopts)))
878                 MONO_HANDLE_ARRAY_GETREF (modopts, helper_modopts, i);
879
880         encode_custom_modifiers (assembly, modreqs, modopts, buf, error);
881         if (!is_ok (error))
882                 goto leave;
883         MonoReflectionTypeHandle pt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
884         MONO_HANDLE_ARRAY_GETREF (pt, helper_arguments, i);
885         encode_reflection_type (assembly, pt, buf, error);
886         if (!is_ok (error))
887                 goto leave;
888 leave:
889         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
890 }
891
892 guint32
893 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
894 {
895         SigBuffer buf;
896         guint32 nargs;
897         guint32 i, idx;
898
899         error_init (error);
900
901         if (!assembly->save)
902                 return 0;
903
904         /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
905         g_assert (MONO_HANDLE_GETVAL (helper, type) == 2);
906
907         MonoArrayHandle arguments = MONO_HANDLE_NEW_GET (MonoArray, helper, arguments);
908         if (!MONO_HANDLE_IS_NULL (arguments))
909                 nargs = mono_array_handle_length (arguments);
910         else
911                 nargs = 0;
912
913         sigbuffer_init (&buf, 32);
914
915         /* Encode calling convention */
916         /* Change Any to Standard */
917         if ((MONO_HANDLE_GETVAL (helper, call_conv) & 0x03) == 0x03)
918                 MONO_HANDLE_SETVAL (helper, call_conv, guint32, 0x01);
919         /* explicit_this implies has_this */
920         if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x40)
921                 MONO_HANDLE_SETVAL (helper, call_conv, guint32, MONO_HANDLE_GETVAL (helper, call_conv) & 0x20);
922
923         if (MONO_HANDLE_GETVAL (helper, call_conv) == 0) { /* Unmanaged */
924                 idx = MONO_HANDLE_GETVAL (helper, unmanaged_call_conv) - 1;
925         } else {
926                 /* Managed */
927                 idx = MONO_HANDLE_GETVAL (helper, call_conv) & 0x60; /* has_this + explicit_this */
928                 if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x02) /* varargs */
929                         idx += 0x05;
930         }
931
932         sigbuffer_add_byte (&buf, idx);
933         sigbuffer_add_value (&buf, nargs);
934         encode_reflection_type (assembly, MONO_HANDLE_NEW_GET (MonoReflectionType, helper, return_type), &buf, error);
935         if (!is_ok (error))
936                 goto fail;
937         MonoArrayHandle modreqs = MONO_HANDLE_NEW_GET (MonoArray, helper, modreqs);
938         MonoArrayHandle modopts = MONO_HANDLE_NEW_GET (MonoArray, helper, modopts);
939         for (i = 0; i < nargs; ++i) {
940                 if (!encode_sighelper_arg (assembly, i, arguments, modreqs, modopts, &buf, error))
941                         goto fail;
942         }
943         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
944         sigbuffer_free (&buf);
945
946         return idx;
947 fail:
948         sigbuffer_free (&buf);
949         return 0;
950 }
951 #else /* DISABLE_REFLECTION_EMIT */
952 guint32
953 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
954 {
955         g_assert_not_reached ();
956         return 0;
957 }
958 #endif /* DISABLE_REFLECTION_EMIT */
959
960 static gboolean
961 encode_reflection_types (MonoDynamicImage *assembly, MonoArrayHandle sig_arguments, int i, SigBuffer *buf, MonoError *error)
962 {
963         HANDLE_FUNCTION_ENTER ();
964         error_init (error);
965         MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
966         MONO_HANDLE_ARRAY_GETREF (type, sig_arguments, i);
967         encode_reflection_type (assembly, type, buf, error);
968         HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
969 }
970
971 static MonoArrayHandle
972 reflection_sighelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
973 {
974         MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
975         MonoDynamicImage *assembly = MONO_HANDLE_IS_NULL (module) ? NULL : MONO_HANDLE_GETVAL (module, dynamic_image);
976         MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
977         guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
978         guint32 buflen, i;
979         SigBuffer buf;
980
981         error_init (error);
982
983         sigbuffer_init (&buf, 32);
984
985         sigbuffer_add_value (&buf, 0x07);
986         sigbuffer_add_value (&buf, na);
987         if (assembly != NULL){
988                 for (i = 0; i < na; ++i) {
989                         if (!encode_reflection_types (assembly, sig_arguments, i, &buf, error))
990                                 goto fail;
991                 }
992         }
993
994         buflen = buf.p - buf.buf;
995         MonoArrayHandle result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
996         if (!is_ok (error)) goto fail;
997         uint32_t gchandle;
998         void *base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
999         memcpy (base, buf.buf, buflen);
1000         sigbuffer_free (&buf);
1001         mono_gchandle_free (gchandle);
1002         return result;
1003 fail:
1004         sigbuffer_free (&buf);
1005         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1006 }
1007
1008 static MonoArrayHandle
1009 reflection_sighelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1010 {
1011         MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
1012         MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (module, dynamic_image);
1013         MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
1014         guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
1015         guint32 buflen, i;
1016         SigBuffer buf;
1017
1018         error_init (error);
1019
1020         sigbuffer_init (&buf, 32);
1021
1022         sigbuffer_add_value (&buf, 0x06);
1023         for (i = 0; i < na; ++i) {
1024                 if (! encode_reflection_types (assembly, sig_arguments, i, &buf, error))
1025                         goto fail;
1026         }
1027
1028         buflen = buf.p - buf.buf;
1029         MonoArrayHandle result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
1030         if (!is_ok (error)) goto fail;
1031         uint32_t gchandle;
1032         void *base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
1033         memcpy (base, buf.buf, buflen);
1034         sigbuffer_free (&buf);
1035         mono_gchandle_free (gchandle);
1036
1037         return result;
1038 fail:
1039         sigbuffer_free (&buf);
1040         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1041 }
1042
1043 static char*
1044 type_get_fully_qualified_name (MonoType *type)
1045 {
1046         MONO_REQ_GC_NEUTRAL_MODE;
1047
1048         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1049 }
1050
1051 #ifndef DISABLE_REFLECTION_EMIT_SAVE
1052 guint32
1053 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1054 {
1055         MONO_REQ_GC_UNSAFE_MODE;
1056
1057         error_init (error);
1058
1059         char *str;
1060         SigBuffer buf;
1061         guint32 idx, len;
1062
1063         sigbuffer_init (&buf, 32);
1064
1065         sigbuffer_add_value (&buf, minfo->type);
1066
1067         switch (minfo->type) {
1068         case MONO_NATIVE_BYVALTSTR:
1069         case MONO_NATIVE_BYVALARRAY:
1070                 sigbuffer_add_value (&buf, minfo->count);
1071                 break;
1072         case MONO_NATIVE_LPARRAY:
1073                 if (minfo->eltype || minfo->has_size) {
1074                         sigbuffer_add_value (&buf, minfo->eltype);
1075                         if (minfo->has_size) {
1076                                 sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
1077                                 sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
1078
1079                                 /* LAMESPEC: ElemMult is undocumented */
1080                                 sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
1081                         }
1082                 }
1083                 break;
1084         case MONO_NATIVE_SAFEARRAY:
1085                 if (minfo->eltype)
1086                         sigbuffer_add_value (&buf, minfo->eltype);
1087                 break;
1088         case MONO_NATIVE_CUSTOM:
1089                 if (minfo->guid) {
1090                         str = mono_string_to_utf8_checked (minfo->guid, error);
1091                         if (!is_ok (error)) {
1092                                 sigbuffer_free (&buf);
1093                                 return 0;
1094                         }
1095                         len = strlen (str);
1096                         sigbuffer_add_value (&buf, len);
1097                         sigbuffer_add_mem (&buf, str, len);
1098                         g_free (str);
1099                 } else {
1100                         sigbuffer_add_value (&buf, 0);
1101                 }
1102                 /* native type name */
1103                 sigbuffer_add_value (&buf, 0);
1104                 /* custom marshaler type name */
1105                 if (minfo->marshaltype || minfo->marshaltyperef) {
1106                         if (minfo->marshaltyperef) {
1107                                 MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
1108                                 if (!is_ok (error)) {
1109                                         sigbuffer_free (&buf);
1110                                         return 0;
1111                                 }
1112                                 str = type_get_fully_qualified_name (marshaltype);
1113                         } else {
1114                                 str = mono_string_to_utf8_checked (minfo->marshaltype, error);
1115                                 if (!is_ok (error)) {
1116                                         sigbuffer_free (&buf);
1117                                         return 0;
1118                                 }
1119                         }
1120                         len = strlen (str);
1121                         sigbuffer_add_value (&buf, len);
1122                         sigbuffer_add_mem (&buf, str, len);
1123                         g_free (str);
1124                 } else {
1125                         /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
1126                         sigbuffer_add_value (&buf, 0);
1127                 }
1128                 if (minfo->mcookie) {
1129                         str = mono_string_to_utf8_checked (minfo->mcookie, error);
1130                         if (!is_ok (error)) {
1131                                 sigbuffer_free (&buf);
1132                                 return 0;
1133                         }
1134                         len = strlen (str);
1135                         sigbuffer_add_value (&buf, len);
1136                         sigbuffer_add_mem (&buf, str, len);
1137                         g_free (str);
1138                 } else {
1139                         sigbuffer_add_value (&buf, 0);
1140                 }
1141                 break;
1142         default:
1143                 break;
1144         }
1145         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1146         sigbuffer_free (&buf);
1147         return idx;
1148 }
1149
1150 guint32
1151 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1152 {
1153         MONO_REQ_GC_UNSAFE_MODE;
1154
1155         error_init (error);
1156
1157         SigBuffer buf;
1158         guint32 nparams = 0;
1159         MonoReflectionMethodBuilder *mb = fb->get_method;
1160         MonoReflectionMethodBuilder *smb = fb->set_method;
1161         guint32 idx, i;
1162
1163         if (mb && mb->parameters)
1164                 nparams = mono_array_length (mb->parameters);
1165         if (!mb && smb && smb->parameters)
1166                 nparams = mono_array_length (smb->parameters) - 1;
1167         sigbuffer_init (&buf, 32);
1168         if (fb->call_conv & 0x20)
1169                 sigbuffer_add_byte (&buf, 0x28);
1170         else
1171                 sigbuffer_add_byte (&buf, 0x08);
1172         sigbuffer_add_value (&buf, nparams);
1173         if (mb) {
1174                 encode_reflection_type_raw (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
1175                 if (!is_ok (error))
1176                         goto fail;
1177                 for (i = 0; i < nparams; ++i) {
1178                         MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
1179                         encode_reflection_type_raw (assembly, pt, &buf, error);
1180                         if (!is_ok (error))
1181                                 goto fail;
1182                 }
1183         } else if (smb && smb->parameters) {
1184                 /* the property type is the last param */
1185                 encode_reflection_type_raw (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
1186                 if (!is_ok (error))
1187                         goto fail;
1188
1189                 for (i = 0; i < nparams; ++i) {
1190                         MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
1191                         encode_reflection_type_raw (assembly, pt, &buf, error);
1192                         if (!is_ok (error))
1193                                 goto fail;
1194                 }
1195         } else {
1196                 encode_reflection_type_raw (assembly, (MonoReflectionType*)fb->type, &buf, error);
1197                 if (!is_ok (error))
1198                         goto fail;
1199         }
1200
1201         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1202         sigbuffer_free (&buf);
1203         return idx;
1204 fail:
1205         sigbuffer_free (&buf);
1206         return 0;
1207 }
1208
1209
1210 #else /*DISABLE_REFLECTION_EMIT_SAVE*/
1211 guint32
1212 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1213 {
1214         g_assert_not_reached ();
1215         return 0;
1216 }
1217
1218 guint32
1219 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1220 {
1221         g_assert_not_reached ();
1222         return 0;
1223 }
1224 #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
1225
1226 #ifndef DISABLE_REFLECTION_EMIT
1227 MonoArrayHandle
1228 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
1229 {
1230         error_init (error);
1231         return reflection_sighelper_get_signature_local (sig, error);
1232 }
1233
1234 MonoArrayHandle
1235 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1236 {
1237         error_init (error);
1238         return reflection_sighelper_get_signature_field (sig, error);
1239 }
1240 #else /* DISABLE_REFLECTION_EMIT */
1241 MonoArrayHandle
1242 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
1243 {
1244         error_init (error);
1245         g_assert_not_reached ();
1246         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1247 }
1248
1249 MonoArrayHandle
1250 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1251 {
1252         error_init (error);
1253         g_assert_not_reached ();
1254         return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1255 }
1256
1257 #endif /* DISABLE_REFLECTION_EMIT */