2 * sre-encode.c: Routines for encoding SRE builders into a
3 * MonoDynamicImage and generating tokens.
7 * Paolo Molaro (lupus@ximian.com)
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
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
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/reflection-internals.h"
23 #include "mono/metadata/sre-internals.h"
24 #include "mono/metadata/tabledefs.h"
25 #include "mono/metadata/tokentype.h"
26 #include "mono/utils/checked-build.h"
34 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
35 static void encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
36 static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
39 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
41 return mono_dynstream_add_data (stream, data, len);
45 alloc_table (MonoDynamicTable *table, guint nrows)
47 mono_dynimage_alloc_table (table, nrows);
51 sigbuffer_init (SigBuffer *buf, int size)
53 MONO_REQ_GC_NEUTRAL_MODE;
55 buf->buf = (char *)g_malloc (size);
57 buf->end = buf->buf + size;
61 sigbuffer_make_room (SigBuffer *buf, int size)
63 MONO_REQ_GC_NEUTRAL_MODE;
65 if (buf->end - buf->p < size) {
66 int new_size = buf->end - buf->buf + size + 32;
67 char *p = (char *)g_realloc (buf->buf, new_size);
68 size = buf->p - buf->buf;
71 buf->end = buf->buf + new_size;
76 sigbuffer_add_value (SigBuffer *buf, guint32 val)
78 MONO_REQ_GC_NEUTRAL_MODE;
80 sigbuffer_make_room (buf, 6);
81 mono_metadata_encode_value (val, buf->p, &buf->p);
85 sigbuffer_add_byte (SigBuffer *buf, guint8 val)
87 MONO_REQ_GC_NEUTRAL_MODE;
89 sigbuffer_make_room (buf, 1);
95 sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
97 MONO_REQ_GC_NEUTRAL_MODE;
99 sigbuffer_make_room (buf, size);
100 memcpy (buf->p, p, size);
105 sigbuffer_free (SigBuffer *buf)
107 MONO_REQ_GC_NEUTRAL_MODE;
113 sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
115 MONO_REQ_GC_NEUTRAL_MODE;
119 guint32 size = buf->p - buf->buf;
121 g_assert (size <= (buf->end - buf->buf));
122 mono_metadata_encode_value (size, b, &b);
123 return mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
128 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
130 MONO_REQ_GC_NEUTRAL_MODE;
133 MonoGenericInst *class_inst;
138 class_inst = gclass->context.class_inst;
140 sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
141 klass = gclass->container_class;
142 sigbuffer_add_value (buf, klass->byval_arg.type);
143 sigbuffer_add_value (buf, mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
145 sigbuffer_add_value (buf, class_inst->type_argc);
146 for (i = 0; i < class_inst->type_argc; ++i)
147 encode_type (assembly, class_inst->type_argv [i], buf);
152 encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
154 MONO_REQ_GC_NEUTRAL_MODE;
157 g_assert_not_reached ();
162 sigbuffer_add_value (buf, MONO_TYPE_BYREF);
166 case MONO_TYPE_BOOLEAN:
180 case MONO_TYPE_STRING:
181 case MONO_TYPE_OBJECT:
182 case MONO_TYPE_TYPEDBYREF:
183 sigbuffer_add_value (buf, type->type);
186 sigbuffer_add_value (buf, type->type);
187 encode_type (assembly, type->data.type, buf);
189 case MONO_TYPE_SZARRAY:
190 sigbuffer_add_value (buf, type->type);
191 encode_type (assembly, &type->data.klass->byval_arg, buf);
193 case MONO_TYPE_VALUETYPE:
194 case MONO_TYPE_CLASS: {
195 MonoClass *k = mono_class_from_mono_type (type);
197 if (mono_class_is_gtd (k)) {
198 MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, mono_class_get_generic_container (k)->context.class_inst, TRUE);
199 encode_generic_class (assembly, gclass, buf);
202 * Make sure we use the correct type.
204 sigbuffer_add_value (buf, k->byval_arg.type);
206 * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
207 * otherwise two typerefs could point to the same type, leading to
208 * verification errors.
210 sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
214 case MONO_TYPE_ARRAY:
215 sigbuffer_add_value (buf, type->type);
216 encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
217 sigbuffer_add_value (buf, type->data.array->rank);
218 sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
219 sigbuffer_add_value (buf, 0);
221 case MONO_TYPE_GENERICINST:
222 encode_generic_class (assembly, type->data.generic_class, buf);
226 sigbuffer_add_value (buf, type->type);
227 sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
230 g_error ("need to encode type %x", type->type);
235 encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionTypeHandle type, SigBuffer *buf, MonoError *error)
237 MONO_REQ_GC_UNSAFE_MODE;
242 sigbuffer_add_value (buf, MONO_TYPE_VOID);
246 MonoType *t = mono_reflection_type_handle_mono_type (type, error);
247 return_if_nok (error);
248 encode_type (assembly, t, buf);
252 encode_reflection_type_raw (MonoDynamicImage *assembly, MonoReflectionType* type_raw, SigBuffer *buf, MonoError *error)
254 HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_reflection_type_raw should use handles */
256 MONO_HANDLE_DCL (MonoReflectionType, type);
257 encode_reflection_type (assembly, type, buf, error);
258 HANDLE_FUNCTION_RETURN ();
263 encode_custom_modifiers (MonoDynamicImage *assembly, MonoArrayHandle modreq, MonoArrayHandle modopt, SigBuffer *buf, MonoError *error)
265 HANDLE_FUNCTION_ENTER ();
266 MONO_REQ_GC_UNSAFE_MODE;
272 if (!MONO_HANDLE_IS_NULL (modreq)) {
273 for (i = 0; i < mono_array_handle_length (modreq); ++i) {
274 MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
277 sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
278 sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
281 if (!MONO_HANDLE_IS_NULL (modopt)) {
282 for (i = 0; i < mono_array_handle_length (modopt); ++i) {
283 MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
286 sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
287 sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
291 HANDLE_FUNCTION_RETURN ();
295 encode_custom_modifiers_raw (MonoDynamicImage *assembly, MonoArray *modreq_raw, MonoArray *modopt_raw, SigBuffer *buf, MonoError *error)
297 HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_custom_modifiers_raw should use handles */
299 MONO_HANDLE_DCL (MonoArray, modreq);
300 MONO_HANDLE_DCL (MonoArray, modopt);
301 encode_custom_modifiers (assembly, modreq, modopt, buf, error);
302 HANDLE_FUNCTION_RETURN ();
306 #ifndef DISABLE_REFLECTION_EMIT
308 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
310 MONO_REQ_GC_UNSAFE_MODE;
314 guint32 nparams = sig->param_count;
320 sigbuffer_init (&buf, 32);
322 * FIXME: vararg, explicit_this, differenc call_conv values...
324 idx = sig->call_convention;
326 idx |= 0x20; /* hasthis */
327 if (sig->generic_param_count)
328 idx |= 0x10; /* generic */
329 sigbuffer_add_byte (&buf, idx);
330 if (sig->generic_param_count)
331 sigbuffer_add_value (&buf, sig->generic_param_count);
332 sigbuffer_add_value (&buf, nparams);
333 encode_type (assembly, sig->ret, &buf);
334 for (i = 0; i < nparams; ++i) {
335 if (i == sig->sentinelpos)
336 sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
337 encode_type (assembly, sig->params [i], &buf);
339 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
340 sigbuffer_free (&buf);
343 #else /* DISABLE_REFLECTION_EMIT */
345 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
347 g_assert_not_reached ();
353 mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
355 MONO_REQ_GC_UNSAFE_MODE;
360 * FIXME: reuse code from method_encode_signature().
364 guint32 nparams = mb->parameters ? mono_array_length (mb->parameters): 0;
365 guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
366 guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
369 sigbuffer_init (&buf, 32);
370 /* LAMESPEC: all the call conv spec is foobared */
371 idx = mb->call_conv & 0x60; /* has-this, explicit-this */
372 if (mb->call_conv & 2)
373 idx |= 0x5; /* vararg */
374 if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
375 idx |= 0x20; /* hasthis */
377 idx |= 0x10; /* generic */
378 sigbuffer_add_byte (&buf, idx);
380 sigbuffer_add_value (&buf, ngparams);
381 sigbuffer_add_value (&buf, nparams + notypes);
382 encode_custom_modifiers_raw (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
385 encode_reflection_type_raw (assembly, mb->rtype, &buf, error);
388 for (i = 0; i < nparams; ++i) {
389 MonoArray *modreq = NULL;
390 MonoArray *modopt = NULL;
391 MonoReflectionType *pt;
393 if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
394 modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
395 if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
396 modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
397 encode_custom_modifiers_raw (assembly, modreq, modopt, &buf, error);
400 pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
401 encode_reflection_type_raw (assembly, pt, &buf, error);
406 sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
407 for (i = 0; i < notypes; ++i) {
408 MonoReflectionType *pt;
410 pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
411 encode_reflection_type_raw (assembly, pt, &buf, error);
416 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
418 sigbuffer_free (&buf);
423 mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
425 MONO_REQ_GC_UNSAFE_MODE;
429 MonoDynamicTable *table;
431 guint32 idx, sig_idx;
432 guint nl = mono_array_length (ilgen->locals);
436 sigbuffer_init (&buf, 32);
437 sigbuffer_add_value (&buf, 0x07);
438 sigbuffer_add_value (&buf, nl);
439 for (i = 0; i < nl; ++i) {
440 MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
443 sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
445 encode_reflection_type_raw (assembly, (MonoReflectionType*)lb->type, &buf, error);
446 if (!is_ok (error)) {
447 sigbuffer_free (&buf);
451 sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
452 sigbuffer_free (&buf);
454 if (assembly->standalonesig_cache == NULL)
455 assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
456 idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
460 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
461 idx = table->next_idx ++;
463 alloc_table (table, table->rows);
464 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
466 values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
468 g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
475 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
476 * dest may be misaligned.
479 swap_with_size (char *dest, const char* val, int len, int nelem) {
480 MONO_REQ_GC_NEUTRAL_MODE;
481 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
484 for (elem = 0; elem < nelem; ++elem) {
510 g_assert_not_reached ();
516 memcpy (dest, val, len * nelem);
522 mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
524 MONO_REQ_GC_UNSAFE_MODE;
530 guint32 idx = 0, len = 0, dummy = 0;
532 buf = (char *)g_malloc (64);
534 *ret_type = MONO_TYPE_CLASS;
536 box_val = (char*)&dummy;
538 box_val = ((char*)val) + sizeof (MonoObject);
539 *ret_type = val->vtable->klass->byval_arg.type;
543 case MONO_TYPE_BOOLEAN:
565 case MONO_TYPE_VALUETYPE: {
566 MonoClass *klass = val->vtable->klass;
568 if (klass->enumtype) {
569 *ret_type = mono_class_enum_basetype (klass)->type;
571 } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
574 g_error ("we can't encode valuetypes, we should have never reached this line");
577 case MONO_TYPE_CLASS:
579 case MONO_TYPE_STRING: {
580 MonoString *str = (MonoString*)val;
581 /* there is no signature */
582 len = str->length * 2;
583 mono_metadata_encode_value (len, b, &b);
584 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
586 char *swapped = g_malloc (2 * mono_string_length (str));
587 const char *p = (const char*)mono_string_chars (str);
589 swap_with_size (swapped, p, 2, mono_string_length (str));
590 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
594 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
600 case MONO_TYPE_GENERICINST:
601 *ret_type = mono_class_get_generic_class (val->vtable->klass)->container_class->byval_arg.type;
604 g_error ("we don't encode constant type 0x%02x yet", *ret_type);
607 /* there is no signature */
608 mono_metadata_encode_value (len, b, &b);
609 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
610 idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
611 swap_with_size (blob_size, box_val, len, 1);
612 mono_image_add_stream_data (&assembly->blob, blob_size, len);
614 idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
622 mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
624 MONO_REQ_GC_UNSAFE_MODE;
630 guint32 typespec = 0;
634 type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
635 return_val_if_nok (error, 0);
636 klass = mono_class_from_mono_type (type);
638 sigbuffer_init (&buf, 32);
640 sigbuffer_add_value (&buf, 0x06);
641 encode_custom_modifiers_raw (assembly, fb->modreq, fb->modopt, &buf, error);
644 /* encode custom attributes before the type */
646 if (mono_class_is_gtd (klass))
647 typespec = create_typespec (assembly, type);
650 MonoGenericClass *gclass;
651 gclass = mono_metadata_lookup_generic_class (klass, mono_class_get_generic_container (klass)->context.class_inst, TRUE);
652 encode_generic_class (assembly, gclass, &buf);
654 encode_type (assembly, type, &buf);
656 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
657 sigbuffer_free (&buf);
660 sigbuffer_free (&buf);
664 #ifndef DISABLE_REFLECTION_EMIT
665 /*field_image is the image to which the eventual custom mods have been encoded against*/
667 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
669 MONO_REQ_GC_NEUTRAL_MODE;
672 guint32 idx, i, token;
677 sigbuffer_init (&buf, 32);
679 sigbuffer_add_value (&buf, 0x06);
680 /* encode custom attributes before the type */
681 if (type->num_mods) {
682 for (i = 0; i < type->num_mods; ++i) {
685 MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
686 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
688 token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
690 token = type->modifiers [i].token;
693 if (type->modifiers [i].required)
694 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
696 sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
698 sigbuffer_add_value (&buf, token);
701 encode_type (assembly, type, &buf);
702 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
703 sigbuffer_free (&buf);
706 #else /* DISABLE_REFLECTION_EMIT */
708 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
710 g_assert_not_reached ();
713 #endif /* DISABLE_REFLECTION_EMIT */
716 create_typespec (MonoDynamicImage *assembly, MonoType *type)
718 MONO_REQ_GC_NEUTRAL_MODE;
720 MonoDynamicTable *table;
725 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
728 sigbuffer_init (&buf, 32);
729 switch (type->type) {
730 case MONO_TYPE_FNPTR:
732 case MONO_TYPE_SZARRAY:
733 case MONO_TYPE_ARRAY:
736 case MONO_TYPE_GENERICINST:
737 encode_type (assembly, type, &buf);
739 case MONO_TYPE_CLASS:
740 case MONO_TYPE_VALUETYPE: {
741 MonoClass *k = mono_class_from_mono_type (type);
742 if (!k || !mono_class_is_gtd (k)) {
743 sigbuffer_free (&buf);
746 encode_type (assembly, type, &buf);
750 sigbuffer_free (&buf);
754 table = &assembly->tables [MONO_TABLE_TYPESPEC];
755 if (assembly->save) {
756 token = sigbuffer_add_to_blob_cached (assembly, &buf);
757 alloc_table (table, table->rows + 1);
758 values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
759 values [MONO_TYPESPEC_SIGNATURE] = token;
761 sigbuffer_free (&buf);
763 token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
764 g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
770 mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
772 MONO_REQ_GC_UNSAFE_MODE;
774 MonoDynamicTable *table;
776 guint32 token, scope, enclosing;
779 /* if the type requires a typespec, we must try that first*/
780 if (try_typespec && (token = create_typespec (assembly, type)))
782 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
785 klass = mono_class_from_mono_type (type);
787 MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, mono_class_get_ref_info (klass));
789 * If it's in the same module and not a generic type parameter:
791 if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) &&
792 (type->type != MONO_TYPE_MVAR)) {
793 token = MONO_TYPEDEFORREF_TYPEDEF | (MONO_HANDLE_GETVAL (tb, table_idx) << MONO_TYPEDEFORREF_BITS);
794 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb));
798 if (klass->nested_in) {
799 enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
800 /* get the typeref idx of the enclosing type */
801 enclosing >>= MONO_TYPEDEFORREF_BITS;
802 scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
804 scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
806 table = &assembly->tables [MONO_TABLE_TYPEREF];
807 if (assembly->save) {
808 alloc_table (table, table->rows + 1);
809 values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
810 values [MONO_TYPEREF_SCOPE] = scope;
811 values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, klass->name);
812 values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, klass->name_space);
814 token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
815 g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
817 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb));
822 * Despite the name, we handle also TypeSpec (with the above helper).
825 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
827 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
831 mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
835 guint32 nparams = context->method_inst->type_argc;
841 sigbuffer_init (&buf, 32);
843 * FIXME: vararg, explicit_this, differenc call_conv values...
845 sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
846 sigbuffer_add_value (&buf, nparams);
848 for (i = 0; i < nparams; i++)
849 encode_type (assembly, context->method_inst->type_argv [i], &buf);
851 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
852 sigbuffer_free (&buf);
856 #ifndef DISABLE_REFLECTION_EMIT
858 encode_sighelper_arg (MonoDynamicImage *assembly, int i, MonoArrayHandle helper_arguments, MonoArrayHandle helper_modreqs, MonoArrayHandle helper_modopts, SigBuffer* buf, MonoError *error)
860 HANDLE_FUNCTION_ENTER();
862 MonoArrayHandle modreqs = MONO_HANDLE_NEW (MonoArray, NULL);
863 MonoArrayHandle modopts = MONO_HANDLE_NEW (MonoArray, NULL);
865 if (!MONO_HANDLE_IS_NULL (helper_modreqs) && (i < mono_array_handle_length (helper_modreqs)))
866 MONO_HANDLE_ARRAY_GETREF (modreqs, helper_modreqs, i);
867 if (!MONO_HANDLE_IS_NULL (helper_modopts) && (i < mono_array_handle_length (helper_modopts)))
868 MONO_HANDLE_ARRAY_GETREF (modopts, helper_modopts, i);
870 encode_custom_modifiers (assembly, modreqs, modopts, buf, error);
873 MonoReflectionTypeHandle pt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
874 MONO_HANDLE_ARRAY_GETREF (pt, helper_arguments, i);
875 encode_reflection_type (assembly, pt, buf, error);
879 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
883 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
894 /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
895 g_assert (MONO_HANDLE_GETVAL (helper, type) == 2);
897 MonoArrayHandle arguments = MONO_HANDLE_NEW_GET (MonoArray, helper, arguments);
898 if (!MONO_HANDLE_IS_NULL (arguments))
899 nargs = mono_array_handle_length (arguments);
903 sigbuffer_init (&buf, 32);
905 /* Encode calling convention */
906 /* Change Any to Standard */
907 if ((MONO_HANDLE_GETVAL (helper, call_conv) & 0x03) == 0x03)
908 MONO_HANDLE_SETVAL (helper, call_conv, guint32, 0x01);
909 /* explicit_this implies has_this */
910 if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x40)
911 MONO_HANDLE_SETVAL (helper, call_conv, guint32, MONO_HANDLE_GETVAL (helper, call_conv) & 0x20);
913 if (MONO_HANDLE_GETVAL (helper, call_conv) == 0) { /* Unmanaged */
914 idx = MONO_HANDLE_GETVAL (helper, unmanaged_call_conv) - 1;
917 idx = MONO_HANDLE_GETVAL (helper, call_conv) & 0x60; /* has_this + explicit_this */
918 if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x02) /* varargs */
922 sigbuffer_add_byte (&buf, idx);
923 sigbuffer_add_value (&buf, nargs);
924 encode_reflection_type (assembly, MONO_HANDLE_NEW_GET (MonoReflectionType, helper, return_type), &buf, error);
927 MonoArrayHandle modreqs = MONO_HANDLE_NEW_GET (MonoArray, helper, modreqs);
928 MonoArrayHandle modopts = MONO_HANDLE_NEW_GET (MonoArray, helper, modopts);
929 for (i = 0; i < nargs; ++i) {
930 if (!encode_sighelper_arg (assembly, i, arguments, modreqs, modopts, &buf, error))
933 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
934 sigbuffer_free (&buf);
938 sigbuffer_free (&buf);
941 #else /* DISABLE_REFLECTION_EMIT */
943 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
945 g_assert_not_reached ();
948 #endif /* DISABLE_REFLECTION_EMIT */
951 reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig, MonoError *error)
953 MonoReflectionModuleBuilder *module = sig->module;
954 MonoDynamicImage *assembly = module != NULL ? module->dynamic_image : NULL;
955 guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
962 sigbuffer_init (&buf, 32);
964 sigbuffer_add_value (&buf, 0x07);
965 sigbuffer_add_value (&buf, na);
966 if (assembly != NULL){
967 for (i = 0; i < na; ++i) {
968 MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
969 encode_reflection_type_raw (assembly, type, &buf, error);
970 if (!is_ok (error)) goto fail;
974 buflen = buf.p - buf.buf;
975 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
976 if (!is_ok (error)) goto fail;
977 memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
978 sigbuffer_free (&buf);
981 sigbuffer_free (&buf);
986 reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig, MonoError *error)
988 MonoDynamicImage *assembly = sig->module->dynamic_image;
989 guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
996 sigbuffer_init (&buf, 32);
998 sigbuffer_add_value (&buf, 0x06);
999 for (i = 0; i < na; ++i) {
1000 MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
1001 encode_reflection_type_raw (assembly, type, &buf, error);
1006 buflen = buf.p - buf.buf;
1007 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
1008 if (!is_ok (error)) goto fail;
1009 memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
1010 sigbuffer_free (&buf);
1014 sigbuffer_free (&buf);
1019 type_get_fully_qualified_name (MonoType *type)
1021 MONO_REQ_GC_NEUTRAL_MODE;
1023 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1026 #ifndef DISABLE_REFLECTION_EMIT_SAVE
1028 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1030 MONO_REQ_GC_UNSAFE_MODE;
1038 sigbuffer_init (&buf, 32);
1040 sigbuffer_add_value (&buf, minfo->type);
1042 switch (minfo->type) {
1043 case MONO_NATIVE_BYVALTSTR:
1044 case MONO_NATIVE_BYVALARRAY:
1045 sigbuffer_add_value (&buf, minfo->count);
1047 case MONO_NATIVE_LPARRAY:
1048 if (minfo->eltype || minfo->has_size) {
1049 sigbuffer_add_value (&buf, minfo->eltype);
1050 if (minfo->has_size) {
1051 sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
1052 sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
1054 /* LAMESPEC: ElemMult is undocumented */
1055 sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
1059 case MONO_NATIVE_SAFEARRAY:
1061 sigbuffer_add_value (&buf, minfo->eltype);
1063 case MONO_NATIVE_CUSTOM:
1065 str = mono_string_to_utf8_checked (minfo->guid, error);
1066 if (!is_ok (error)) {
1067 sigbuffer_free (&buf);
1071 sigbuffer_add_value (&buf, len);
1072 sigbuffer_add_mem (&buf, str, len);
1075 sigbuffer_add_value (&buf, 0);
1077 /* native type name */
1078 sigbuffer_add_value (&buf, 0);
1079 /* custom marshaler type name */
1080 if (minfo->marshaltype || minfo->marshaltyperef) {
1081 if (minfo->marshaltyperef) {
1082 MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
1083 if (!is_ok (error)) {
1084 sigbuffer_free (&buf);
1087 str = type_get_fully_qualified_name (marshaltype);
1089 str = mono_string_to_utf8_checked (minfo->marshaltype, error);
1090 if (!is_ok (error)) {
1091 sigbuffer_free (&buf);
1096 sigbuffer_add_value (&buf, len);
1097 sigbuffer_add_mem (&buf, str, len);
1100 /* FIXME: Actually a bug, since this field is required. Punting for now ... */
1101 sigbuffer_add_value (&buf, 0);
1103 if (minfo->mcookie) {
1104 str = mono_string_to_utf8_checked (minfo->mcookie, error);
1105 if (!is_ok (error)) {
1106 sigbuffer_free (&buf);
1110 sigbuffer_add_value (&buf, len);
1111 sigbuffer_add_mem (&buf, str, len);
1114 sigbuffer_add_value (&buf, 0);
1120 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1121 sigbuffer_free (&buf);
1126 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1128 MONO_REQ_GC_UNSAFE_MODE;
1133 guint32 nparams = 0;
1134 MonoReflectionMethodBuilder *mb = fb->get_method;
1135 MonoReflectionMethodBuilder *smb = fb->set_method;
1138 if (mb && mb->parameters)
1139 nparams = mono_array_length (mb->parameters);
1140 if (!mb && smb && smb->parameters)
1141 nparams = mono_array_length (smb->parameters) - 1;
1142 sigbuffer_init (&buf, 32);
1143 if (fb->call_conv & 0x20)
1144 sigbuffer_add_byte (&buf, 0x28);
1146 sigbuffer_add_byte (&buf, 0x08);
1147 sigbuffer_add_value (&buf, nparams);
1149 encode_reflection_type_raw (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
1152 for (i = 0; i < nparams; ++i) {
1153 MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
1154 encode_reflection_type_raw (assembly, pt, &buf, error);
1158 } else if (smb && smb->parameters) {
1159 /* the property type is the last param */
1160 encode_reflection_type_raw (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
1164 for (i = 0; i < nparams; ++i) {
1165 MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
1166 encode_reflection_type_raw (assembly, pt, &buf, error);
1171 encode_reflection_type_raw (assembly, (MonoReflectionType*)fb->type, &buf, error);
1176 idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1177 sigbuffer_free (&buf);
1180 sigbuffer_free (&buf);
1185 #else /*DISABLE_REFLECTION_EMIT_SAVE*/
1187 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1189 g_assert_not_reached ();
1194 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1196 g_assert_not_reached ();
1199 #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
1201 #ifndef DISABLE_REFLECTION_EMIT
1203 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
1206 MonoArray *result = reflection_sighelper_get_signature_local (sig, &error);
1207 mono_error_set_pending_exception (&error);
1212 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
1215 MonoArray *result = reflection_sighelper_get_signature_field (sig, &error);
1216 mono_error_set_pending_exception (&error);
1219 #else /* DISABLE_REFLECTION_EMIT */
1221 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelper *sig)
1223 g_assert_not_reached ();
1228 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelper *sig)
1230 g_assert_not_reached ();
1234 #endif /* DISABLE_REFLECTION_EMIT */