Merge pull request #3622 from rolfbjarne/remove-stray-file
[mono.git] / mono / metadata / sre-encode.c
1 /*
2  * sre-encode.c: Routines for encoding SRE builders into a
3  *    MonoDynamicImage and generating tokens.
4  *   
5  * 
6  * Author:
7  *   Paolo Molaro (lupus@ximian.com)
8  *
9  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
11  * Copyright 2011 Rodrigo Kumpera
12  * Copyright 2016 Microsoft
13  *
14  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
15  */
16 #include <config.h>
17 #include <glib.h>
18
19 #include "mono/metadata/dynamic-image-internals.h"
20 #include "mono/metadata/dynamic-stream-internals.h"
21 #include "mono/metadata/object-internals.h"
22 #include "mono/metadata/sre-internals.h"
23 #include "mono/metadata/tabledefs.h"
24 #include "mono/metadata/tokentype.h"
25 #include "mono/utils/checked-build.h"
26
27 typedef struct {
28         char *p;
29         char *buf;
30         char *end;
31 } SigBuffer;
32
33 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
34 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
35 static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
36
37 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
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 (k->generic_container) {
199                         MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, k->generic_container->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, MonoReflectionType *type, SigBuffer *buf, MonoError *error)
237 {
238         MONO_REQ_GC_UNSAFE_MODE;
239
240         mono_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_get_handle (type, error);
248         return_if_nok (error);
249         encode_type (assembly, t, buf);
250 }
251
252 static void
253 encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf, MonoError *error)
254 {
255         MONO_REQ_GC_UNSAFE_MODE;
256
257         int i;
258
259         mono_error_init (error);
260
261         if (modreq) {
262                 for (i = 0; i < mono_array_length (modreq); ++i) {
263                         MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
264                         return_if_nok (error);
265                         sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
266                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
267                 }
268         }
269         if (modopt) {
270                 for (i = 0; i < mono_array_length (modopt); ++i) {
271                         MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
272                         return_if_nok (error);
273                         sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
274                         sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
275                 }
276         }
277 }
278
279 #ifndef DISABLE_REFLECTION_EMIT
280 guint32
281 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
282 {
283         MONO_REQ_GC_UNSAFE_MODE;
284
285         SigBuffer buf;
286         int i;
287         guint32 nparams =  sig->param_count;
288         guint32 idx;
289
290         if (!assembly->save)
291                 return 0;
292
293         sigbuffer_init (&buf, 32);
294         /*
295          * FIXME: vararg, explicit_this, differenc call_conv values...
296          */
297         idx = sig->call_convention;
298         if (sig->hasthis)
299                 idx |= 0x20; /* hasthis */
300         if (sig->generic_param_count)
301                 idx |= 0x10; /* generic */
302         sigbuffer_add_byte (&buf, idx);
303         if (sig->generic_param_count)
304                 sigbuffer_add_value (&buf, sig->generic_param_count);
305         sigbuffer_add_value (&buf, nparams);
306         encode_type (assembly, sig->ret, &buf);
307         for (i = 0; i < nparams; ++i) {
308                 if (i == sig->sentinelpos)
309                         sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
310                 encode_type (assembly, sig->params [i], &buf);
311         }
312         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
313         sigbuffer_free (&buf);
314         return idx;
315 }
316 #else /* DISABLE_REFLECTION_EMIT */
317 guint32
318 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
319 {
320         g_assert_not_reached ();
321         return 0;
322 }
323 #endif
324
325 guint32
326 mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
327 {
328         MONO_REQ_GC_UNSAFE_MODE;
329
330         mono_error_init (error);
331
332         /*
333          * FIXME: reuse code from method_encode_signature().
334          */
335         SigBuffer buf;
336         int i;
337         guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
338         guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
339         guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
340         guint32 idx;
341
342         sigbuffer_init (&buf, 32);
343         /* LAMESPEC: all the call conv spec is foobared */
344         idx = mb->call_conv & 0x60; /* has-this, explicit-this */
345         if (mb->call_conv & 2)
346                 idx |= 0x5; /* vararg */
347         if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
348                 idx |= 0x20; /* hasthis */
349         if (ngparams)
350                 idx |= 0x10; /* generic */
351         sigbuffer_add_byte (&buf, idx);
352         if (ngparams)
353                 sigbuffer_add_value (&buf, ngparams);
354         sigbuffer_add_value (&buf, nparams + notypes);
355         encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
356         if (!is_ok (error))
357                 goto leave;
358         encode_reflection_type (assembly, mb->rtype, &buf, error);
359         if (!is_ok (error))
360                 goto leave;
361         for (i = 0; i < nparams; ++i) {
362                 MonoArray *modreq = NULL;
363                 MonoArray *modopt = NULL;
364                 MonoReflectionType *pt;
365
366                 if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
367                         modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
368                 if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
369                         modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
370                 encode_custom_modifiers (assembly, modreq, modopt, &buf, error);
371                 if (!is_ok (error))
372                         goto leave;
373                 pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
374                 encode_reflection_type (assembly, pt, &buf, error);
375                 if (!is_ok (error))
376                         goto leave;
377         }
378         if (notypes)
379                 sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
380         for (i = 0; i < notypes; ++i) {
381                 MonoReflectionType *pt;
382
383                 pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
384                 encode_reflection_type (assembly, pt, &buf, error);
385                 if (!is_ok (error))
386                         goto leave;
387         }
388
389         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
390 leave:
391         sigbuffer_free (&buf);
392         return idx;
393 }
394
395 guint32
396 mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
397 {
398         MONO_REQ_GC_UNSAFE_MODE;
399
400         mono_error_init (error);
401
402         MonoDynamicTable *table;
403         guint32 *values;
404         guint32 idx, sig_idx;
405         guint nl = mono_array_length (ilgen->locals);
406         SigBuffer buf;
407         int i;
408
409         sigbuffer_init (&buf, 32);
410         sigbuffer_add_value (&buf, 0x07);
411         sigbuffer_add_value (&buf, nl);
412         for (i = 0; i < nl; ++i) {
413                 MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
414                 
415                 if (lb->is_pinned)
416                         sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
417                 
418                 encode_reflection_type (assembly, (MonoReflectionType*)lb->type, &buf, error);
419                 if (!is_ok (error)) {
420                         sigbuffer_free (&buf);
421                         return 0;
422                 }
423         }
424         sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
425         sigbuffer_free (&buf);
426
427         if (assembly->standalonesig_cache == NULL)
428                 assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
429         idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
430         if (idx)
431                 return idx;
432
433         table = &assembly->tables [MONO_TABLE_STANDALONESIG];
434         idx = table->next_idx ++;
435         table->rows ++;
436         alloc_table (table, table->rows);
437         values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
438
439         values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
440
441         g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
442
443         return idx;
444 }
445
446
447 /*
448  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
449  * dest may be misaligned.
450  */
451 static void
452 swap_with_size (char *dest, const char* val, int len, int nelem) {
453         MONO_REQ_GC_NEUTRAL_MODE;
454 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
455         int elem;
456
457         for (elem = 0; elem < nelem; ++elem) {
458                 switch (len) {
459                 case 1:
460                         *dest = *val;
461                         break;
462                 case 2:
463                         dest [0] = val [1];
464                         dest [1] = val [0];
465                         break;
466                 case 4:
467                         dest [0] = val [3];
468                         dest [1] = val [2];
469                         dest [2] = val [1];
470                         dest [3] = val [0];
471                         break;
472                 case 8:
473                         dest [0] = val [7];
474                         dest [1] = val [6];
475                         dest [2] = val [5];
476                         dest [3] = val [4];
477                         dest [4] = val [3];
478                         dest [5] = val [2];
479                         dest [6] = val [1];
480                         dest [7] = val [0];
481                         break;
482                 default:
483                         g_assert_not_reached ();
484                 }
485                 dest += len;
486                 val += len;
487         }
488 #else
489         memcpy (dest, val, len * nelem);
490 #endif
491 }
492
493
494 guint32
495 mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
496 {
497         MONO_REQ_GC_UNSAFE_MODE;
498
499         char blob_size [64];
500         char *b = blob_size;
501         char *box_val;
502         char* buf;
503         guint32 idx = 0, len = 0, dummy = 0;
504
505         buf = (char *)g_malloc (64);
506         if (!val) {
507                 *ret_type = MONO_TYPE_CLASS;
508                 len = 4;
509                 box_val = (char*)&dummy;
510         } else {
511                 box_val = ((char*)val) + sizeof (MonoObject);
512                 *ret_type = val->vtable->klass->byval_arg.type;
513         }
514 handle_enum:
515         switch (*ret_type) {
516         case MONO_TYPE_BOOLEAN:
517         case MONO_TYPE_U1:
518         case MONO_TYPE_I1:
519                 len = 1;
520                 break;
521         case MONO_TYPE_CHAR:
522         case MONO_TYPE_U2:
523         case MONO_TYPE_I2:
524                 len = 2;
525                 break;
526         case MONO_TYPE_U4:
527         case MONO_TYPE_I4:
528         case MONO_TYPE_R4:
529                 len = 4;
530                 break;
531         case MONO_TYPE_U8:
532         case MONO_TYPE_I8:
533                 len = 8;
534                 break;
535         case MONO_TYPE_R8:
536                 len = 8;
537                 break;
538         case MONO_TYPE_VALUETYPE: {
539                 MonoClass *klass = val->vtable->klass;
540                 
541                 if (klass->enumtype) {
542                         *ret_type = mono_class_enum_basetype (klass)->type;
543                         goto handle_enum;
544                 } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
545                         len = 8;
546                 } else 
547                         g_error ("we can't encode valuetypes, we should have never reached this line");
548                 break;
549         }
550         case MONO_TYPE_CLASS:
551                 break;
552         case MONO_TYPE_STRING: {
553                 MonoString *str = (MonoString*)val;
554                 /* there is no signature */
555                 len = str->length * 2;
556                 mono_metadata_encode_value (len, b, &b);
557 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
558                 {
559                         char *swapped = g_malloc (2 * mono_string_length (str));
560                         const char *p = (const char*)mono_string_chars (str);
561
562                         swap_with_size (swapped, p, 2, mono_string_length (str));
563                         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
564                         g_free (swapped);
565                 }
566 #else
567                 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
568 #endif
569
570                 g_free (buf);
571                 return idx;
572         }
573         case MONO_TYPE_GENERICINST:
574                 *ret_type = val->vtable->klass->generic_class->container_class->byval_arg.type;
575                 goto handle_enum;
576         default:
577                 g_error ("we don't encode constant type 0x%02x yet", *ret_type);
578         }
579
580         /* there is no signature */
581         mono_metadata_encode_value (len, b, &b);
582 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
583         idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
584         swap_with_size (blob_size, box_val, len, 1);
585         mono_image_add_stream_data (&assembly->blob, blob_size, len);
586 #else
587         idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
588 #endif
589
590         g_free (buf);
591         return idx;
592 }
593
594
595 guint32
596 mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
597 {
598         MONO_REQ_GC_UNSAFE_MODE;
599
600         mono_error_init (error);
601
602         SigBuffer buf;
603         guint32 idx;
604         guint32 typespec = 0;
605         MonoType *type;
606         MonoClass *klass;
607
608         mono_reflection_init_type_builder_generics (fb->type, error);
609         return_val_if_nok (error, 0);
610
611         type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
612         return_val_if_nok (error, 0);
613         klass = mono_class_from_mono_type (type);
614
615         sigbuffer_init (&buf, 32);
616         
617         sigbuffer_add_value (&buf, 0x06);
618         encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf, error);
619         if (!is_ok (error))
620                 goto fail;
621         /* encode custom attributes before the type */
622
623         if (klass->generic_container)
624                 typespec = create_typespec (assembly, type);
625
626         if (typespec) {
627                 MonoGenericClass *gclass;
628                 gclass = mono_metadata_lookup_generic_class (klass, klass->generic_container->context.class_inst, TRUE);
629                 encode_generic_class (assembly, gclass, &buf);
630         } else {
631                 encode_type (assembly, type, &buf);
632         }
633         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
634         sigbuffer_free (&buf);
635         return idx;
636 fail:
637         sigbuffer_free (&buf);
638         return 0;
639 }
640
641 #ifndef DISABLE_REFLECTION_EMIT
642 /*field_image is the image to which the eventual custom mods have been encoded against*/
643 guint32
644 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
645 {
646         MONO_REQ_GC_NEUTRAL_MODE;
647
648         SigBuffer buf;
649         guint32 idx, i, token;
650
651         if (!assembly->save)
652                 return 0;
653
654         sigbuffer_init (&buf, 32);
655         
656         sigbuffer_add_value (&buf, 0x06);
657         /* encode custom attributes before the type */
658         if (type->num_mods) {
659                 for (i = 0; i < type->num_mods; ++i) {
660                         if (field_image) {
661                                 MonoError error;
662                                 MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
663                                 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
664
665                                 token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
666                         } else {
667                                 token = type->modifiers [i].token;
668                         }
669
670                         if (type->modifiers [i].required)
671                                 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
672                         else
673                                 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
674
675                         sigbuffer_add_value (&buf, token);
676                 }
677         }
678         encode_type (assembly, type, &buf);
679         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
680         sigbuffer_free (&buf);
681         return idx;
682 }
683 #else /* DISABLE_REFLECTION_EMIT */
684 guint32
685 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
686 {
687         g_assert_not_reached ();
688         return 0;
689 }
690 #endif /* DISABLE_REFLECTION_EMIT */
691
692 static guint32
693 create_typespec (MonoDynamicImage *assembly, MonoType *type)
694 {
695         MONO_REQ_GC_NEUTRAL_MODE;
696
697         MonoDynamicTable *table;
698         guint32 *values;
699         guint32 token;
700         SigBuffer buf;
701
702         if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
703                 return token;
704
705         sigbuffer_init (&buf, 32);
706         switch (type->type) {
707         case MONO_TYPE_FNPTR:
708         case MONO_TYPE_PTR:
709         case MONO_TYPE_SZARRAY:
710         case MONO_TYPE_ARRAY:
711         case MONO_TYPE_VAR:
712         case MONO_TYPE_MVAR:
713         case MONO_TYPE_GENERICINST:
714                 encode_type (assembly, type, &buf);
715                 break;
716         case MONO_TYPE_CLASS:
717         case MONO_TYPE_VALUETYPE: {
718                 MonoClass *k = mono_class_from_mono_type (type);
719                 if (!k || !k->generic_container) {
720                         sigbuffer_free (&buf);
721                         return 0;
722                 }
723                 encode_type (assembly, type, &buf);
724                 break;
725         }
726         default:
727                 sigbuffer_free (&buf);
728                 return 0;
729         }
730
731         table = &assembly->tables [MONO_TABLE_TYPESPEC];
732         if (assembly->save) {
733                 token = sigbuffer_add_to_blob_cached (assembly, &buf);
734                 alloc_table (table, table->rows + 1);
735                 values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
736                 values [MONO_TYPESPEC_SIGNATURE] = token;
737         }
738         sigbuffer_free (&buf);
739
740         token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
741         g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
742         table->next_idx ++;
743         return token;
744 }
745
746 guint32
747 mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
748 {
749         MONO_REQ_GC_UNSAFE_MODE;
750
751         MonoDynamicTable *table;
752         guint32 *values;
753         guint32 token, scope, enclosing;
754         MonoClass *klass;
755
756         /* if the type requires a typespec, we must try that first*/
757         if (try_typespec && (token = create_typespec (assembly, type)))
758                 return token;
759         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
760         if (token)
761                 return token;
762         klass = mono_class_from_mono_type (type);
763         if (!klass)
764                 klass = mono_class_from_mono_type (type);
765
766         /*
767          * If it's in the same module and not a generic type parameter:
768          */
769         if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && 
770                         (type->type != MONO_TYPE_MVAR)) {
771                 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
772                 token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
773                 mono_dynamic_image_register_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
774                 return token;
775         }
776
777         if (klass->nested_in) {
778                 enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
779                 /* get the typeref idx of the enclosing type */
780                 enclosing >>= MONO_TYPEDEFORREF_BITS;
781                 scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
782         } else {
783                 scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
784         }
785         table = &assembly->tables [MONO_TABLE_TYPEREF];
786         if (assembly->save) {
787                 alloc_table (table, table->rows + 1);
788                 values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
789                 values [MONO_TYPEREF_SCOPE] = scope;
790                 values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, klass->name);
791                 values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, klass->name_space);
792         }
793         token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
794         g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
795         table->next_idx ++;
796         mono_dynamic_image_register_token (assembly, token, (MonoObject *)mono_class_get_ref_info (klass));
797         return token;
798 }
799
800 /*
801  * Despite the name, we handle also TypeSpec (with the above helper).
802  */
803 static guint32
804 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
805 {
806         return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
807 }
808
809 guint32
810 mono_dynimage_encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
811 {
812         SigBuffer buf;
813         int i;
814         guint32 nparams = mono_array_length (mb->generic_params);
815         guint32 idx;
816
817         if (!assembly->save)
818                 return 0;
819
820         sigbuffer_init (&buf, 32);
821
822         sigbuffer_add_value (&buf, 0xa);
823         sigbuffer_add_value (&buf, nparams);
824
825         for (i = 0; i < nparams; i++) {
826                 sigbuffer_add_value (&buf, MONO_TYPE_MVAR);
827                 sigbuffer_add_value (&buf, i);
828         }
829
830         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
831         sigbuffer_free (&buf);
832         return idx;
833 }
834
835 guint32
836 mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
837 {
838         SigBuffer buf;
839         int i;
840         guint32 nparams = context->method_inst->type_argc;
841         guint32 idx;
842
843         if (!assembly->save)
844                 return 0;
845
846         sigbuffer_init (&buf, 32);
847         /*
848          * FIXME: vararg, explicit_this, differenc call_conv values...
849          */
850         sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
851         sigbuffer_add_value (&buf, nparams);
852
853         for (i = 0; i < nparams; i++)
854                 encode_type (assembly, context->method_inst->type_argv [i], &buf);
855
856         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
857         sigbuffer_free (&buf);
858         return idx;
859 }
860
861 #ifndef DISABLE_REFLECTION_EMIT
862 guint32
863 mono_dynimage_encode_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error)
864 {
865         MonoDynamicTable *table;
866         MonoClass *klass;
867         MonoType *type;
868         guint32 *values;
869         guint32 token;
870         SigBuffer buf;
871         int count, i;
872
873         /*
874          * We're creating a TypeSpec for the TypeBuilder of a generic type declaration,
875          * ie. what we'd normally use as the generic type in a TypeSpec signature.
876          * Because of this, we must not insert it into the `typeref' hash table.
877          */
878         type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
879         return_val_if_nok (error, 0);
880         token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type));
881         if (token)
882                 return token;
883
884         sigbuffer_init (&buf, 32);
885
886         g_assert (tb->generic_params);
887         klass = mono_class_from_mono_type (type);
888
889         if (tb->generic_container) {
890                 if (!mono_reflection_create_generic_class (tb, error))
891                         goto fail;
892         }
893
894         sigbuffer_add_value (&buf, MONO_TYPE_GENERICINST);
895         g_assert (klass->generic_container);
896         sigbuffer_add_value (&buf, klass->byval_arg.type);
897         sigbuffer_add_value (&buf, mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
898
899         count = mono_array_length (tb->generic_params);
900         sigbuffer_add_value (&buf, count);
901         for (i = 0; i < count; i++) {
902                 MonoReflectionGenericParam *gparam;
903
904                 gparam = mono_array_get (tb->generic_params, MonoReflectionGenericParam *, i);
905                 MonoType *gparam_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
906                 if (!is_ok (error))
907                         goto fail;
908
909                 encode_type (assembly, gparam_type, &buf);
910         }
911
912         table = &assembly->tables [MONO_TABLE_TYPESPEC];
913
914         if (assembly->save) {
915                 token = sigbuffer_add_to_blob_cached (assembly, &buf);
916                 alloc_table (table, table->rows + 1);
917                 values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
918                 values [MONO_TYPESPEC_SIGNATURE] = token;
919         }
920         sigbuffer_free (&buf);
921
922         token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
923         g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
924         table->next_idx ++;
925         return token;
926 fail:
927         sigbuffer_free (&buf);
928         return 0;
929 }
930 #else /*DISABLE_REFLECTION_EMIT*/
931 guint32
932 mono_dynimage_encode_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb, MonoError *error)
933 {
934         g_assert_not_reached ();
935         return 0;
936 }
937 #endif /*DISABLE_REFLECTION_EMIT*/
938
939 #ifndef DISABLE_REFLECTION_EMIT
940 guint32
941 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
942 {
943         SigBuffer buf;
944         guint32 nargs;
945         guint32 i, idx;
946
947         mono_error_init (error);
948
949         if (!assembly->save)
950                 return 0;
951
952         /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
953         g_assert (helper->type == 2);
954
955         if (helper->arguments)
956                 nargs = mono_array_length (helper->arguments);
957         else
958                 nargs = 0;
959
960         sigbuffer_init (&buf, 32);
961
962         /* Encode calling convention */
963         /* Change Any to Standard */
964         if ((helper->call_conv & 0x03) == 0x03)
965                 helper->call_conv = 0x01;
966         /* explicit_this implies has_this */
967         if (helper->call_conv & 0x40)
968                 helper->call_conv &= 0x20;
969
970         if (helper->call_conv == 0) { /* Unmanaged */
971                 idx = helper->unmanaged_call_conv - 1;
972         } else {
973                 /* Managed */
974                 idx = helper->call_conv & 0x60; /* has_this + explicit_this */
975                 if (helper->call_conv & 0x02) /* varargs */
976                         idx += 0x05;
977         }
978
979         sigbuffer_add_byte (&buf, idx);
980         sigbuffer_add_value (&buf, nargs);
981         encode_reflection_type (assembly, helper->return_type, &buf, error);
982         if (!is_ok (error))
983                 goto fail;
984         for (i = 0; i < nargs; ++i) {
985                 MonoArray *modreqs = NULL;
986                 MonoArray *modopts = NULL;
987                 MonoReflectionType *pt;
988
989                 if (helper->modreqs && (i < mono_array_length (helper->modreqs)))
990                         modreqs = mono_array_get (helper->modreqs, MonoArray*, i);
991                 if (helper->modopts && (i < mono_array_length (helper->modopts)))
992                         modopts = mono_array_get (helper->modopts, MonoArray*, i);
993
994                 encode_custom_modifiers (assembly, modreqs, modopts, &buf, error);
995                 if (!is_ok (error))
996                         goto fail;
997                 pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
998                 encode_reflection_type (assembly, pt, &buf, error);
999                 if (!is_ok (error))
1000                         goto fail;
1001         }
1002         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1003         sigbuffer_free (&buf);
1004
1005         return idx;
1006 fail:
1007         sigbuffer_free (&buf);
1008         return 0;
1009 }
1010 #else /* DISABLE_REFLECTION_EMIT */
1011 guint32
1012 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
1013 {
1014         g_assert_not_reached ();
1015         return 0;
1016 }
1017 #endif /* DISABLE_REFLECTION_EMIT */
1018
1019 static MonoArray *
1020 reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig, MonoError *error)
1021 {
1022         MonoReflectionModuleBuilder *module = sig->module;
1023         MonoDynamicImage *assembly = module != NULL ? module->dynamic_image : NULL;
1024         guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
1025         guint32 buflen, i;
1026         MonoArray *result;
1027         SigBuffer buf;
1028
1029         mono_error_init (error);
1030
1031         sigbuffer_init (&buf, 32);
1032
1033         sigbuffer_add_value (&buf, 0x07);
1034         sigbuffer_add_value (&buf, na);
1035         if (assembly != NULL){
1036                 for (i = 0; i < na; ++i) {
1037                         MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
1038                         encode_reflection_type (assembly, type, &buf, error);
1039                         if (!is_ok (error)) goto fail;
1040                 }
1041         }
1042
1043         buflen = buf.p - buf.buf;
1044         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
1045         if (!is_ok (error)) goto fail;
1046         memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
1047         sigbuffer_free (&buf);
1048         return result;
1049 fail:
1050         sigbuffer_free (&buf);
1051         return NULL;
1052 }
1053
1054 static MonoArray *
1055 reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig, MonoError *error)
1056 {
1057         MonoDynamicImage *assembly = sig->module->dynamic_image;
1058         guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
1059         guint32 buflen, i;
1060         MonoArray *result;
1061         SigBuffer buf;
1062
1063         mono_error_init (error);
1064
1065         sigbuffer_init (&buf, 32);
1066
1067         sigbuffer_add_value (&buf, 0x06);
1068         for (i = 0; i < na; ++i) {
1069                 MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
1070                 encode_reflection_type (assembly, type, &buf, error);
1071                 if (!is_ok (error))
1072                         goto fail;
1073         }
1074
1075         buflen = buf.p - buf.buf;
1076         result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
1077         if (!is_ok (error)) goto fail;
1078         memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
1079         sigbuffer_free (&buf);
1080
1081         return result;
1082 fail:
1083         sigbuffer_free (&buf);
1084         return NULL;
1085 }
1086
1087 static char*
1088 type_get_fully_qualified_name (MonoType *type)
1089 {
1090         MONO_REQ_GC_NEUTRAL_MODE;
1091
1092         return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1093 }
1094
1095 #ifndef DISABLE_REFLECTION_EMIT_SAVE
1096 guint32
1097 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1098 {
1099         MONO_REQ_GC_UNSAFE_MODE;
1100
1101         mono_error_init (error);
1102
1103         char *str;
1104         SigBuffer buf;
1105         guint32 idx, len;
1106
1107         sigbuffer_init (&buf, 32);
1108
1109         sigbuffer_add_value (&buf, minfo->type);
1110
1111         switch (minfo->type) {
1112         case MONO_NATIVE_BYVALTSTR:
1113         case MONO_NATIVE_BYVALARRAY:
1114                 sigbuffer_add_value (&buf, minfo->count);
1115                 break;
1116         case MONO_NATIVE_LPARRAY:
1117                 if (minfo->eltype || minfo->has_size) {
1118                         sigbuffer_add_value (&buf, minfo->eltype);
1119                         if (minfo->has_size) {
1120                                 sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
1121                                 sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
1122
1123                                 /* LAMESPEC: ElemMult is undocumented */
1124                                 sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
1125                         }
1126                 }
1127                 break;
1128         case MONO_NATIVE_SAFEARRAY:
1129                 if (minfo->eltype)
1130                         sigbuffer_add_value (&buf, minfo->eltype);
1131                 break;
1132         case MONO_NATIVE_CUSTOM:
1133                 if (minfo->guid) {
1134                         str = mono_string_to_utf8_checked (minfo->guid, error);
1135                         if (!is_ok (error)) {
1136                                 sigbuffer_free (&buf);
1137                                 return 0;
1138                         }
1139                         len = strlen (str);
1140                         sigbuffer_add_value (&buf, len);
1141                         sigbuffer_add_mem (&buf, str, len);
1142                         g_free (str);
1143                 } else {
1144                         sigbuffer_add_value (&buf, 0);
1145                 }
1146                 /* native type name */
1147                 sigbuffer_add_value (&buf, 0);
1148                 /* custom marshaler type name */
1149                 if (minfo->marshaltype || minfo->marshaltyperef) {
1150                         if (minfo->marshaltyperef) {
1151                                 MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
1152                                 if (!is_ok (error)) {
1153                                         sigbuffer_free (&buf);
1154                                         return 0;
1155                                 }
1156                                 str = type_get_fully_qualified_name (marshaltype);
1157                         } else {
1158                                 str = mono_string_to_utf8_checked (minfo->marshaltype, error);
1159                                 if (!is_ok (error)) {
1160                                         sigbuffer_free (&buf);
1161                                         return 0;
1162                                 }
1163                         }
1164                         len = strlen (str);
1165                         sigbuffer_add_value (&buf, len);
1166                         sigbuffer_add_mem (&buf, str, len);
1167                         g_free (str);
1168                 } else {
1169                         /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
1170                         sigbuffer_add_value (&buf, 0);
1171                 }
1172                 if (minfo->mcookie) {
1173                         str = mono_string_to_utf8_checked (minfo->mcookie, error);
1174                         if (!is_ok (error)) {
1175                                 sigbuffer_free (&buf);
1176                                 return 0;
1177                         }
1178                         len = strlen (str);
1179                         sigbuffer_add_value (&buf, len);
1180                         sigbuffer_add_mem (&buf, str, len);
1181                         g_free (str);
1182                 } else {
1183                         sigbuffer_add_value (&buf, 0);
1184                 }
1185                 break;
1186         default:
1187                 break;
1188         }
1189         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1190         sigbuffer_free (&buf);
1191         return idx;
1192 }
1193
1194 guint32
1195 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1196 {
1197         MONO_REQ_GC_UNSAFE_MODE;
1198
1199         mono_error_init (error);
1200
1201         SigBuffer buf;
1202         guint32 nparams = 0;
1203         MonoReflectionMethodBuilder *mb = fb->get_method;
1204         MonoReflectionMethodBuilder *smb = fb->set_method;
1205         guint32 idx, i;
1206
1207         if (mb && mb->parameters)
1208                 nparams = mono_array_length (mb->parameters);
1209         if (!mb && smb && smb->parameters)
1210                 nparams = mono_array_length (smb->parameters) - 1;
1211         sigbuffer_init (&buf, 32);
1212         if (fb->call_conv & 0x20)
1213                 sigbuffer_add_byte (&buf, 0x28);
1214         else
1215                 sigbuffer_add_byte (&buf, 0x08);
1216         sigbuffer_add_value (&buf, nparams);
1217         if (mb) {
1218                 encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
1219                 if (!is_ok (error))
1220                         goto fail;
1221                 for (i = 0; i < nparams; ++i) {
1222                         MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
1223                         encode_reflection_type (assembly, pt, &buf, error);
1224                         if (!is_ok (error))
1225                                 goto fail;
1226                 }
1227         } else if (smb && smb->parameters) {
1228                 /* the property type is the last param */
1229                 encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
1230                 if (!is_ok (error))
1231                         goto fail;
1232
1233                 for (i = 0; i < nparams; ++i) {
1234                         MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
1235                         encode_reflection_type (assembly, pt, &buf, error);
1236                         if (!is_ok (error))
1237                                 goto fail;
1238                 }
1239         } else {
1240                 encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf, error);
1241                 if (!is_ok (error))
1242                         goto fail;
1243         }
1244
1245         idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1246         sigbuffer_free (&buf);
1247         return idx;
1248 fail:
1249         sigbuffer_free (&buf);
1250         return 0;
1251 }
1252
1253
1254 #else /*DISABLE_REFLECTION_EMIT_SAVE*/
1255 guint32
1256 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1257 {
1258         g_assert_not_reached ();
1259         return 0;
1260 }
1261
1262 guint32
1263 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1264 {
1265         g_assert_not_reached ();
1266         return 0;
1267 }
1268 #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
1269
1270 #ifndef DISABLE_REFLECTION_EMIT
1271 MonoArray *
1272 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
1273 {
1274         MonoError error;
1275         MonoArray *result = reflection_sighelper_get_signature_local (sig, &error);
1276         mono_error_set_pending_exception (&error);
1277         return result;
1278 }
1279
1280 MonoArray *
1281 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
1282 {
1283         MonoError error;
1284         MonoArray *result = reflection_sighelper_get_signature_field (sig, &error);
1285         mono_error_set_pending_exception (&error);
1286         return result;
1287 }
1288 #else /* DISABLE_REFLECTION_EMIT */
1289 MonoArray *
1290 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
1291 {
1292         g_assert_not_reached ();
1293         return NULL;
1294 }
1295
1296 MonoArray *
1297 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
1298 {
1299         g_assert_not_reached ();
1300         return NULL;
1301 }
1302
1303 #endif /* DISABLE_REFLECTION_EMIT */