3 * Routines for encoding SRE builders into a
4 * MonoDynamicImage and generating tokens.
8 * Paolo Molaro (lupus@ximian.com)
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
15 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
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 #include "icall-decl.h"
36 static guint32
create_typespec (MonoDynamicImage
*assembly
, MonoType
*type
);
37 static void encode_type (MonoDynamicImage
*assembly
, MonoType
*type
, SigBuffer
*buf
);
38 static guint32
mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
);
40 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
42 mono_image_add_stream_data (MonoDynamicStream
*stream
, const char *data
, guint32 len
)
44 return mono_dynstream_add_data (stream
, data
, len
);
49 alloc_table (MonoDynamicTable
*table
, guint nrows
)
51 mono_dynimage_alloc_table (table
, nrows
);
55 sigbuffer_init (SigBuffer
*buf
, int size
)
57 MONO_REQ_GC_NEUTRAL_MODE
;
59 buf
->buf
= (char *)g_malloc (size
);
61 buf
->end
= buf
->buf
+ size
;
65 sigbuffer_make_room (SigBuffer
*buf
, int size
)
67 MONO_REQ_GC_NEUTRAL_MODE
;
69 if (buf
->end
- buf
->p
< size
) {
70 int new_size
= buf
->end
- buf
->buf
+ size
+ 32;
71 char *p
= (char *)g_realloc (buf
->buf
, new_size
);
72 size
= buf
->p
- buf
->buf
;
75 buf
->end
= buf
->buf
+ new_size
;
80 sigbuffer_add_value (SigBuffer
*buf
, guint32 val
)
82 MONO_REQ_GC_NEUTRAL_MODE
;
84 sigbuffer_make_room (buf
, 6);
85 mono_metadata_encode_value (val
, buf
->p
, &buf
->p
);
89 sigbuffer_add_byte (SigBuffer
*buf
, guint8 val
)
91 MONO_REQ_GC_NEUTRAL_MODE
;
93 sigbuffer_make_room (buf
, 1);
99 sigbuffer_add_mem (SigBuffer
*buf
, char *p
, guint32 size
)
101 MONO_REQ_GC_NEUTRAL_MODE
;
103 sigbuffer_make_room (buf
, size
);
104 memcpy (buf
->p
, p
, size
);
109 sigbuffer_free (SigBuffer
*buf
)
111 MONO_REQ_GC_NEUTRAL_MODE
;
117 sigbuffer_add_to_blob_cached (MonoDynamicImage
*assembly
, SigBuffer
*buf
)
119 MONO_REQ_GC_NEUTRAL_MODE
;
123 guint32 size
= buf
->p
- buf
->buf
;
125 g_assert (size
<= (buf
->end
- buf
->buf
));
126 mono_metadata_encode_value (size
, b
, &b
);
127 return mono_dynamic_image_add_to_blob_cached (assembly
, blob_size
, b
-blob_size
, buf
->buf
, size
);
132 encode_generic_class (MonoDynamicImage
*assembly
, MonoGenericClass
*gclass
, SigBuffer
*buf
)
134 MONO_REQ_GC_NEUTRAL_MODE
;
137 MonoGenericInst
*class_inst
;
142 class_inst
= gclass
->context
.class_inst
;
144 sigbuffer_add_value (buf
, MONO_TYPE_GENERICINST
);
145 klass
= gclass
->container_class
;
146 sigbuffer_add_value (buf
, m_class_get_byval_arg (klass
)->type
);
147 sigbuffer_add_value (buf
, mono_dynimage_encode_typedef_or_ref_full (assembly
, m_class_get_byval_arg (klass
), FALSE
));
149 sigbuffer_add_value (buf
, class_inst
->type_argc
);
150 for (i
= 0; i
< class_inst
->type_argc
; ++i
)
151 encode_type (assembly
, class_inst
->type_argv
[i
], buf
);
156 encode_type (MonoDynamicImage
*assembly
, MonoType
*type
, SigBuffer
*buf
)
158 MONO_REQ_GC_NEUTRAL_MODE
;
161 g_assert_not_reached ();
166 sigbuffer_add_value (buf
, MONO_TYPE_BYREF
);
170 case MONO_TYPE_BOOLEAN
:
184 case MONO_TYPE_STRING
:
185 case MONO_TYPE_OBJECT
:
186 case MONO_TYPE_TYPEDBYREF
:
187 sigbuffer_add_value (buf
, type
->type
);
190 sigbuffer_add_value (buf
, type
->type
);
191 encode_type (assembly
, type
->data
.type
, buf
);
193 case MONO_TYPE_SZARRAY
:
194 sigbuffer_add_value (buf
, type
->type
);
195 encode_type (assembly
, m_class_get_byval_arg (type
->data
.klass
), buf
);
197 case MONO_TYPE_VALUETYPE
:
198 case MONO_TYPE_CLASS
: {
199 MonoClass
*k
= mono_class_from_mono_type_internal (type
);
201 if (mono_class_is_gtd (k
)) {
202 MonoGenericClass
*gclass
= mono_metadata_lookup_generic_class (k
, mono_class_get_generic_container (k
)->context
.class_inst
, TRUE
);
203 encode_generic_class (assembly
, gclass
, buf
);
206 * Make sure we use the correct type.
208 sigbuffer_add_value (buf
, m_class_get_byval_arg (k
)->type
);
210 * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
211 * otherwise two typerefs could point to the same type, leading to
212 * verification errors.
214 sigbuffer_add_value (buf
, mono_image_typedef_or_ref (assembly
, m_class_get_byval_arg (k
)));
218 case MONO_TYPE_ARRAY
:
219 sigbuffer_add_value (buf
, type
->type
);
220 encode_type (assembly
, m_class_get_byval_arg (type
->data
.array
->eklass
), buf
);
221 sigbuffer_add_value (buf
, type
->data
.array
->rank
);
222 sigbuffer_add_value (buf
, 0); /* FIXME: set to 0 for now */
223 sigbuffer_add_value (buf
, 0);
225 case MONO_TYPE_GENERICINST
:
226 encode_generic_class (assembly
, type
->data
.generic_class
, buf
);
230 sigbuffer_add_value (buf
, type
->type
);
231 sigbuffer_add_value (buf
, mono_type_get_generic_param_num (type
));
234 g_error ("need to encode type %x", type
->type
);
239 encode_reflection_type (MonoDynamicImage
*assembly
, MonoReflectionTypeHandle type
, SigBuffer
*buf
, MonoError
*error
)
241 MONO_REQ_GC_UNSAFE_MODE
;
245 if (MONO_HANDLE_IS_NULL (type
)) {
246 sigbuffer_add_value (buf
, MONO_TYPE_VOID
);
250 MonoType
*t
= mono_reflection_type_handle_mono_type (type
, error
);
251 return_if_nok (error
);
252 encode_type (assembly
, t
, buf
);
256 encode_reflection_type_raw (MonoDynamicImage
*assembly
, MonoReflectionType
* type_raw
, SigBuffer
*buf
, MonoError
*error
)
258 HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_reflection_type_raw should use handles */
260 MONO_HANDLE_DCL (MonoReflectionType
, type
);
261 encode_reflection_type (assembly
, type
, buf
, error
);
262 HANDLE_FUNCTION_RETURN ();
267 encode_custom_modifiers (MonoDynamicImage
*assembly
, MonoArrayHandle modreq
, MonoArrayHandle modopt
, SigBuffer
*buf
, MonoError
*error
)
269 HANDLE_FUNCTION_ENTER ();
270 MONO_REQ_GC_UNSAFE_MODE
;
276 /* Have to follow .NET Framework behavior here. For an IL type spec like:
277 * int32 modreq(A) modreq(B) modopt(C) modopt(D)
280 * cmod_opt [encoding of D] cmod_opt [encoding of C] cmod_req [encoding of B] cmod_req [encoding of A] I4.
282 * Even though the reflection API specifies required and optional
283 * modifiers in separate arrays, the .NET Framework creates a typespec
284 * as above: required mods first, then optional. (And so we emit the
285 * optional ones first, then required).
288 if (!MONO_HANDLE_IS_NULL (modopt
)) {
289 int count
= mono_array_handle_length (modopt
);
290 g_assert (count
> 0);
291 for (i
= count
- 1; i
>= 0 ; --i
) {
292 MonoType
*mod
= mono_type_array_get_and_resolve (modopt
, i
, error
);
293 goto_if_nok (error
, leave
);
294 sigbuffer_add_byte (buf
, MONO_TYPE_CMOD_OPT
);
295 sigbuffer_add_value (buf
, mono_image_typedef_or_ref (assembly
, mod
));
298 if (!MONO_HANDLE_IS_NULL (modreq
)) {
299 int count
= mono_array_handle_length (modreq
);
300 g_assert (count
> 0);
301 for (i
= count
- 1; i
>= 0 ; --i
) {
302 MonoType
*mod
= mono_type_array_get_and_resolve (modreq
, i
, error
);
303 goto_if_nok (error
, leave
);
304 sigbuffer_add_byte (buf
, MONO_TYPE_CMOD_REQD
);
305 sigbuffer_add_value (buf
, mono_image_typedef_or_ref (assembly
, mod
));
310 HANDLE_FUNCTION_RETURN ();
314 encode_custom_modifiers_raw (MonoDynamicImage
*assembly
, MonoArray
*modreq_raw
, MonoArray
*modopt_raw
, SigBuffer
*buf
, MonoError
*error
)
316 HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_custom_modifiers_raw should use handles */
318 MONO_HANDLE_DCL (MonoArray
, modreq
);
319 MONO_HANDLE_DCL (MonoArray
, modopt
);
320 encode_custom_modifiers (assembly
, modreq
, modopt
, buf
, error
);
321 HANDLE_FUNCTION_RETURN ();
325 #ifndef DISABLE_REFLECTION_EMIT
327 mono_dynimage_encode_method_signature (MonoDynamicImage
*assembly
, MonoMethodSignature
*sig
)
329 MONO_REQ_GC_UNSAFE_MODE
;
333 guint32 nparams
= sig
->param_count
;
339 sigbuffer_init (&buf
, 32);
341 * FIXME: vararg, explicit_this, differenc call_conv values...
343 idx
= sig
->call_convention
;
345 idx
|= 0x20; /* hasthis */
346 if (sig
->generic_param_count
)
347 idx
|= 0x10; /* generic */
348 sigbuffer_add_byte (&buf
, idx
);
349 if (sig
->generic_param_count
)
350 sigbuffer_add_value (&buf
, sig
->generic_param_count
);
351 sigbuffer_add_value (&buf
, nparams
);
352 encode_type (assembly
, sig
->ret
, &buf
);
353 for (i
= 0; i
< nparams
; ++i
) {
354 if (i
== sig
->sentinelpos
)
355 sigbuffer_add_byte (&buf
, MONO_TYPE_SENTINEL
);
356 encode_type (assembly
, sig
->params
[i
], &buf
);
358 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
359 sigbuffer_free (&buf
);
362 #else /* DISABLE_REFLECTION_EMIT */
364 mono_dynimage_encode_method_signature (MonoDynamicImage
*assembly
, MonoMethodSignature
*sig
)
366 g_assert_not_reached ();
372 mono_dynimage_encode_method_builder_signature (MonoDynamicImage
*assembly
, ReflectionMethodBuilder
*mb
, MonoError
*error
)
374 MONO_REQ_GC_UNSAFE_MODE
;
379 * FIXME: reuse code from method_encode_signature().
383 guint32 nparams
= mb
->parameters
? mono_array_length_internal (mb
->parameters
): 0;
384 guint32 ngparams
= mb
->generic_params
? mono_array_length_internal (mb
->generic_params
): 0;
385 guint32 notypes
= mb
->opt_types
? mono_array_length_internal (mb
->opt_types
): 0;
388 sigbuffer_init (&buf
, 32);
389 /* LAMESPEC: all the call conv spec is foobared */
390 idx
= mb
->call_conv
& 0x60; /* has-this, explicit-this */
391 if (mb
->call_conv
& 2)
392 idx
|= 0x5; /* vararg */
393 if (!(mb
->attrs
& METHOD_ATTRIBUTE_STATIC
))
394 idx
|= 0x20; /* hasthis */
396 idx
|= 0x10; /* generic */
397 sigbuffer_add_byte (&buf
, idx
);
399 sigbuffer_add_value (&buf
, ngparams
);
400 sigbuffer_add_value (&buf
, nparams
+ notypes
);
401 encode_custom_modifiers_raw (assembly
, mb
->return_modreq
, mb
->return_modopt
, &buf
, error
);
402 goto_if_nok (error
, leave
);
403 encode_reflection_type_raw (assembly
, mb
->rtype
, &buf
, error
);
404 goto_if_nok (error
, leave
);
405 for (i
= 0; i
< nparams
; ++i
) {
406 MonoArray
*modreq
= NULL
;
407 MonoArray
*modopt
= NULL
;
408 MonoReflectionType
*pt
;
410 if (mb
->param_modreq
&& (i
< mono_array_length_internal (mb
->param_modreq
)))
411 modreq
= mono_array_get_internal (mb
->param_modreq
, MonoArray
*, i
);
412 if (mb
->param_modopt
&& (i
< mono_array_length_internal (mb
->param_modopt
)))
413 modopt
= mono_array_get_internal (mb
->param_modopt
, MonoArray
*, i
);
414 encode_custom_modifiers_raw (assembly
, modreq
, modopt
, &buf
, error
);
415 goto_if_nok (error
, leave
);
416 pt
= mono_array_get_internal (mb
->parameters
, MonoReflectionType
*, i
);
417 encode_reflection_type_raw (assembly
, pt
, &buf
, error
);
418 goto_if_nok (error
, leave
);
421 sigbuffer_add_byte (&buf
, MONO_TYPE_SENTINEL
);
422 for (i
= 0; i
< notypes
; ++i
) {
423 MonoReflectionType
*pt
;
425 pt
= mono_array_get_internal (mb
->opt_types
, MonoReflectionType
*, i
);
426 encode_reflection_type_raw (assembly
, pt
, &buf
, error
);
427 goto_if_nok (error
, leave
);
430 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
432 sigbuffer_free (&buf
);
437 mono_dynimage_encode_locals (MonoDynamicImage
*assembly
, MonoReflectionILGen
*ilgen
, MonoError
*error
)
439 MONO_REQ_GC_UNSAFE_MODE
;
443 MonoDynamicTable
*table
;
445 guint32 idx
, sig_idx
;
446 guint nl
= mono_array_length_internal (ilgen
->locals
);
450 sigbuffer_init (&buf
, 32);
451 sigbuffer_add_value (&buf
, 0x07);
452 sigbuffer_add_value (&buf
, nl
);
453 for (i
= 0; i
< nl
; ++i
) {
454 MonoReflectionLocalBuilder
*lb
= mono_array_get_internal (ilgen
->locals
, MonoReflectionLocalBuilder
*, i
);
457 sigbuffer_add_value (&buf
, MONO_TYPE_PINNED
);
459 encode_reflection_type_raw (assembly
, (MonoReflectionType
*)lb
->type
, &buf
, error
);
460 if (!is_ok (error
)) {
461 sigbuffer_free (&buf
);
465 sig_idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
466 sigbuffer_free (&buf
);
468 if (assembly
->standalonesig_cache
== NULL
)
469 assembly
->standalonesig_cache
= g_hash_table_new (NULL
, NULL
);
470 idx
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->standalonesig_cache
, GUINT_TO_POINTER (sig_idx
)));
474 table
= &assembly
->tables
[MONO_TABLE_STANDALONESIG
];
475 idx
= table
->next_idx
++;
477 alloc_table (table
, table
->rows
);
478 values
= table
->values
+ idx
* MONO_STAND_ALONE_SIGNATURE_SIZE
;
480 values
[MONO_STAND_ALONE_SIGNATURE
] = sig_idx
;
482 g_hash_table_insert (assembly
->standalonesig_cache
, GUINT_TO_POINTER (sig_idx
), GUINT_TO_POINTER (idx
));
489 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
490 * dest may be misaligned.
492 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
494 swap_with_size (char *dest
, const char* val
, int len
, int nelem
) {
495 MONO_REQ_GC_NEUTRAL_MODE
;
498 for (elem
= 0; elem
< nelem
; ++elem
) {
524 g_assert_not_reached ();
534 mono_dynimage_encode_constant (MonoDynamicImage
*assembly
, MonoObject
*val
, MonoTypeEnum
*ret_type
)
536 MONO_REQ_GC_UNSAFE_MODE
;
542 guint32 idx
= 0, len
= 0, dummy
= 0;
544 buf
= (char *)g_malloc (64);
546 *ret_type
= MONO_TYPE_CLASS
;
550 box_val
= mono_object_get_data (val
);
551 *ret_type
= m_class_get_byval_arg (val
->vtable
->klass
)->type
;
555 case MONO_TYPE_BOOLEAN
:
577 case MONO_TYPE_VALUETYPE
: {
578 MonoClass
*klass
= val
->vtable
->klass
;
580 if (m_class_is_enumtype (klass
)) {
581 *ret_type
= mono_class_enum_basetype_internal (klass
)->type
;
583 } else if (mono_is_corlib_image (m_class_get_image (klass
)) && strcmp (m_class_get_name_space (klass
), "System") == 0 && strcmp (m_class_get_name (klass
), "DateTime") == 0) {
586 g_error ("we can't encode valuetypes, we should have never reached this line");
589 case MONO_TYPE_CLASS
:
591 case MONO_TYPE_STRING
: {
592 MonoString
*str
= (MonoString
*)val
;
593 /* there is no signature */
594 len
= str
->length
* 2;
595 mono_metadata_encode_value (len
, b
, &b
);
596 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
598 char *swapped
= g_malloc (2 * mono_string_length_internal (str
));
599 const char *p
= (const char*)mono_string_chars_internal (str
);
601 swap_with_size (swapped
, p
, 2, mono_string_length_internal (str
));
602 idx
= mono_dynamic_image_add_to_blob_cached (assembly
, blob_size
, b
-blob_size
, swapped
, len
);
606 idx
= mono_dynamic_image_add_to_blob_cached (assembly
, blob_size
, b
-blob_size
, mono_string_chars_internal (str
), len
);
612 case MONO_TYPE_GENERICINST
:
613 *ret_type
= m_class_get_byval_arg (mono_class_get_generic_class (val
->vtable
->klass
)->container_class
)->type
;
616 g_error ("we don't encode constant type 0x%02x yet", *ret_type
);
619 /* there is no signature */
620 mono_metadata_encode_value (len
, b
, &b
);
621 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
622 idx
= mono_image_add_stream_data (&assembly
->blob
, blob_size
, b
-blob_size
);
623 swap_with_size (blob_size
, box_val
, len
, 1);
624 mono_image_add_stream_data (&assembly
->blob
, blob_size
, len
);
626 idx
= mono_dynamic_image_add_to_blob_cached (assembly
, blob_size
, b
-blob_size
, box_val
, len
);
634 mono_dynimage_encode_field_signature (MonoDynamicImage
*assembly
, MonoReflectionFieldBuilder
*fb
, MonoError
*error
)
636 MONO_REQ_GC_UNSAFE_MODE
;
642 guint32 typespec
= 0;
646 type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
647 return_val_if_nok (error
, 0);
648 klass
= mono_class_from_mono_type_internal (type
);
650 sigbuffer_init (&buf
, 32);
652 sigbuffer_add_value (&buf
, 0x06);
653 encode_custom_modifiers_raw (assembly
, fb
->modreq
, fb
->modopt
, &buf
, error
);
654 goto_if_nok (error
, fail
);
655 /* encode custom attributes before the type */
657 if (mono_class_is_gtd (klass
))
658 typespec
= create_typespec (assembly
, type
);
661 MonoGenericClass
*gclass
;
662 gclass
= mono_metadata_lookup_generic_class (klass
, mono_class_get_generic_container (klass
)->context
.class_inst
, TRUE
);
663 encode_generic_class (assembly
, gclass
, &buf
);
665 encode_type (assembly
, type
, &buf
);
667 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
668 sigbuffer_free (&buf
);
671 sigbuffer_free (&buf
);
675 #ifndef DISABLE_REFLECTION_EMIT
676 /*field_image is the image to which the eventual custom mods have been encoded against*/
678 mono_dynimage_encode_fieldref_signature (MonoDynamicImage
*assembly
, MonoImage
*field_image
, MonoType
*type
)
680 MONO_REQ_GC_NEUTRAL_MODE
;
683 guint32 idx
, i
, token
;
688 sigbuffer_init (&buf
, 32);
690 sigbuffer_add_value (&buf
, 0x06);
691 /* encode custom attributes before the type */
692 if (type
->has_cmods
) {
693 MonoCustomModContainer
*cmods
= mono_type_get_cmods (type
);
694 for (i
= 0; i
< cmods
->count
; ++i
) {
697 MonoClass
*klass
= mono_class_get_checked (field_image
, cmods
->modifiers
[i
].token
, error
);
698 g_assert (mono_error_ok (error
)); /* FIXME don't swallow the error */
700 token
= mono_image_typedef_or_ref (assembly
, m_class_get_byval_arg (klass
));
702 token
= cmods
->modifiers
[i
].token
;
705 if (cmods
->modifiers
[i
].required
)
706 sigbuffer_add_byte (&buf
, MONO_TYPE_CMOD_REQD
);
708 sigbuffer_add_byte (&buf
, MONO_TYPE_CMOD_OPT
);
710 sigbuffer_add_value (&buf
, token
);
713 encode_type (assembly
, type
, &buf
);
714 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
715 sigbuffer_free (&buf
);
718 #else /* DISABLE_REFLECTION_EMIT */
720 mono_dynimage_encode_fieldref_signature (MonoDynamicImage
*assembly
, MonoImage
*field_image
, MonoType
*type
)
722 g_assert_not_reached ();
725 #endif /* DISABLE_REFLECTION_EMIT */
728 create_typespec (MonoDynamicImage
*assembly
, MonoType
*type
)
730 MONO_REQ_GC_NEUTRAL_MODE
;
732 MonoDynamicTable
*table
;
737 if ((token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->typespec
, type
))))
740 sigbuffer_init (&buf
, 32);
741 switch (type
->type
) {
742 case MONO_TYPE_FNPTR
:
744 case MONO_TYPE_SZARRAY
:
745 case MONO_TYPE_ARRAY
:
748 case MONO_TYPE_GENERICINST
:
749 encode_type (assembly
, type
, &buf
);
751 case MONO_TYPE_CLASS
:
752 case MONO_TYPE_VALUETYPE
: {
753 MonoClass
*k
= mono_class_from_mono_type_internal (type
);
754 if (!k
|| !mono_class_is_gtd (k
)) {
755 sigbuffer_free (&buf
);
758 encode_type (assembly
, type
, &buf
);
762 sigbuffer_free (&buf
);
766 table
= &assembly
->tables
[MONO_TABLE_TYPESPEC
];
767 if (assembly
->save
) {
768 token
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
769 alloc_table (table
, table
->rows
+ 1);
770 values
= table
->values
+ table
->next_idx
* MONO_TYPESPEC_SIZE
;
771 values
[MONO_TYPESPEC_SIGNATURE
] = token
;
773 sigbuffer_free (&buf
);
775 token
= MONO_TYPEDEFORREF_TYPESPEC
| (table
->next_idx
<< MONO_TYPEDEFORREF_BITS
);
776 g_hash_table_insert (assembly
->typespec
, type
, GUINT_TO_POINTER(token
));
782 mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage
*assembly
, MonoType
*type
, gboolean try_typespec
)
784 MONO_REQ_GC_UNSAFE_MODE
;
785 HANDLE_FUNCTION_ENTER ();
787 MonoDynamicTable
*table
;
789 guint32 token
, scope
, enclosing
;
792 /* if the type requires a typespec, we must try that first*/
793 if (try_typespec
&& (token
= create_typespec (assembly
, type
)))
795 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->typeref
, type
));
798 klass
= mono_class_from_mono_type_internal (type
);
800 MonoReflectionTypeBuilderHandle tb
;
801 tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, mono_class_get_ref_info (klass
));
803 * If it's in the same module and not a generic type parameter:
805 if ((m_class_get_image (klass
) == &assembly
->image
) && (type
->type
!= MONO_TYPE_VAR
) &&
806 (type
->type
!= MONO_TYPE_MVAR
)) {
807 token
= MONO_TYPEDEFORREF_TYPEDEF
| (MONO_HANDLE_GETVAL (tb
, table_idx
) << MONO_TYPEDEFORREF_BITS
);
808 /* This function is called multiple times from sre and sre-save, so same object is okay */
809 mono_dynamic_image_register_token (assembly
, token
, MONO_HANDLE_CAST (MonoObject
, tb
), MONO_DYN_IMAGE_TOK_SAME_OK
);
813 if (m_class_get_nested_in (klass
)) {
814 enclosing
= mono_dynimage_encode_typedef_or_ref_full (assembly
, m_class_get_byval_arg (m_class_get_nested_in (klass
)), FALSE
);
815 /* get the typeref idx of the enclosing type */
816 enclosing
>>= MONO_TYPEDEFORREF_BITS
;
817 scope
= (enclosing
<< MONO_RESOLUTION_SCOPE_BITS
) | MONO_RESOLUTION_SCOPE_TYPEREF
;
819 scope
= mono_reflection_resolution_scope_from_image (assembly
, m_class_get_image (klass
));
821 table
= &assembly
->tables
[MONO_TABLE_TYPEREF
];
822 if (assembly
->save
) {
823 alloc_table (table
, table
->rows
+ 1);
824 values
= table
->values
+ table
->next_idx
* MONO_TYPEREF_SIZE
;
825 values
[MONO_TYPEREF_SCOPE
] = scope
;
826 values
[MONO_TYPEREF_NAME
] = mono_dynstream_insert_string (&assembly
->sheap
, m_class_get_name (klass
));
827 values
[MONO_TYPEREF_NAMESPACE
] = mono_dynstream_insert_string (&assembly
->sheap
, m_class_get_name_space (klass
));
829 token
= MONO_TYPEDEFORREF_TYPEREF
| (table
->next_idx
<< MONO_TYPEDEFORREF_BITS
); /* typeref */
830 g_hash_table_insert (assembly
->typeref
, type
, GUINT_TO_POINTER(token
));
834 if (!MONO_HANDLE_IS_NULL (tb
)) {
835 /* This function is called multiple times from sre and sre-save, so same object is okay */
836 mono_dynamic_image_register_token (assembly
, token
, MONO_HANDLE_CAST (MonoObject
, tb
), MONO_DYN_IMAGE_TOK_SAME_OK
);
840 HANDLE_FUNCTION_RETURN_VAL (token
);
844 * Despite the name, we handle also TypeSpec (with the above helper).
847 mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
)
849 return mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, TRUE
);
853 mono_dynimage_encode_generic_method_sig (MonoDynamicImage
*assembly
, MonoGenericContext
*context
)
857 guint32 nparams
= context
->method_inst
->type_argc
;
863 sigbuffer_init (&buf
, 32);
865 * FIXME: vararg, explicit_this, differenc call_conv values...
867 sigbuffer_add_value (&buf
, 0xa); /* FIXME FIXME FIXME */
868 sigbuffer_add_value (&buf
, nparams
);
870 for (i
= 0; i
< nparams
; i
++)
871 encode_type (assembly
, context
->method_inst
->type_argv
[i
], &buf
);
873 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
874 sigbuffer_free (&buf
);
878 #ifndef DISABLE_REFLECTION_EMIT
880 encode_sighelper_arg (MonoDynamicImage
*assembly
, int i
, MonoArrayHandle helper_arguments
, MonoArrayHandle helper_modreqs
, MonoArrayHandle helper_modopts
, SigBuffer
* buf
, MonoError
*error
)
882 HANDLE_FUNCTION_ENTER();
884 MonoArrayHandle modreqs
= MONO_HANDLE_NEW (MonoArray
, NULL
);
885 MonoArrayHandle modopts
= MONO_HANDLE_NEW (MonoArray
, NULL
);
887 if (!MONO_HANDLE_IS_NULL (helper_modreqs
) && (i
< mono_array_handle_length (helper_modreqs
)))
888 MONO_HANDLE_ARRAY_GETREF (modreqs
, helper_modreqs
, i
);
889 if (!MONO_HANDLE_IS_NULL (helper_modopts
) && (i
< mono_array_handle_length (helper_modopts
)))
890 MONO_HANDLE_ARRAY_GETREF (modopts
, helper_modopts
, i
);
892 encode_custom_modifiers (assembly
, modreqs
, modopts
, buf
, error
);
893 goto_if_nok (error
, leave
);
894 MonoReflectionTypeHandle pt
;
895 pt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
896 MONO_HANDLE_ARRAY_GETREF (pt
, helper_arguments
, i
);
897 encode_reflection_type (assembly
, pt
, buf
, error
);
898 goto_if_nok (error
, leave
);
900 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
904 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
)
915 /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
916 g_assert (MONO_HANDLE_GETVAL (helper
, type
) == 2);
918 MonoArrayHandle arguments
= MONO_HANDLE_NEW_GET (MonoArray
, helper
, arguments
);
919 if (!MONO_HANDLE_IS_NULL (arguments
))
920 nargs
= mono_array_handle_length (arguments
);
924 sigbuffer_init (&buf
, 32);
926 /* Encode calling convention */
927 /* Change Any to Standard */
928 if ((MONO_HANDLE_GETVAL (helper
, call_conv
) & 0x03) == 0x03)
929 MONO_HANDLE_SETVAL (helper
, call_conv
, guint32
, 0x01);
930 /* explicit_this implies has_this */
931 if (MONO_HANDLE_GETVAL (helper
, call_conv
) & 0x40)
932 MONO_HANDLE_SETVAL (helper
, call_conv
, guint32
, MONO_HANDLE_GETVAL (helper
, call_conv
) & 0x20);
934 if (MONO_HANDLE_GETVAL (helper
, call_conv
) == 0) { /* Unmanaged */
935 idx
= MONO_HANDLE_GETVAL (helper
, unmanaged_call_conv
) - 1;
938 idx
= MONO_HANDLE_GETVAL (helper
, call_conv
) & 0x60; /* has_this + explicit_this */
939 if (MONO_HANDLE_GETVAL (helper
, call_conv
) & 0x02) /* varargs */
943 sigbuffer_add_byte (&buf
, idx
);
944 sigbuffer_add_value (&buf
, nargs
);
945 encode_reflection_type (assembly
, MONO_HANDLE_NEW_GET (MonoReflectionType
, helper
, return_type
), &buf
, error
);
946 goto_if_nok (error
, fail
);
947 MonoArrayHandle modreqs
;
948 modreqs
= MONO_HANDLE_NEW_GET (MonoArray
, helper
, modreqs
);
949 MonoArrayHandle modopts
;
950 modopts
= MONO_HANDLE_NEW_GET (MonoArray
, helper
, modopts
);
951 for (i
= 0; i
< nargs
; ++i
) {
952 if (!encode_sighelper_arg (assembly
, i
, arguments
, modreqs
, modopts
, &buf
, error
))
955 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
956 sigbuffer_free (&buf
);
960 sigbuffer_free (&buf
);
963 #else /* DISABLE_REFLECTION_EMIT */
965 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
)
967 g_assert_not_reached ();
970 #endif /* DISABLE_REFLECTION_EMIT */
973 encode_reflection_types (MonoDynamicImage
*assembly
, MonoArrayHandle sig_arguments
, int i
, SigBuffer
*buf
, MonoError
*error
)
975 HANDLE_FUNCTION_ENTER ();
977 MonoReflectionTypeHandle type
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
978 MONO_HANDLE_ARRAY_GETREF (type
, sig_arguments
, i
);
979 encode_reflection_type (assembly
, type
, buf
, error
);
980 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
983 static MonoArrayHandle
984 reflection_sighelper_get_signature_local (MonoReflectionSigHelperHandle sig
, MonoError
*error
)
986 MonoReflectionModuleBuilderHandle module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, sig
, module
);
987 MonoDynamicImage
*assembly
= MONO_HANDLE_IS_NULL (module
) ? NULL
: MONO_HANDLE_GETVAL (module
, dynamic_image
);
988 MonoArrayHandle sig_arguments
= MONO_HANDLE_NEW_GET (MonoArray
, sig
, arguments
);
989 guint32 na
= MONO_HANDLE_IS_NULL (sig_arguments
) ? 0 : mono_array_handle_length (sig_arguments
);
995 sigbuffer_init (&buf
, 32);
997 sigbuffer_add_value (&buf
, 0x07);
998 sigbuffer_add_value (&buf
, na
);
999 if (assembly
!= NULL
){
1000 for (i
= 0; i
< na
; ++i
) {
1001 if (!encode_reflection_types (assembly
, sig_arguments
, i
, &buf
, error
))
1006 buflen
= buf
.p
- buf
.buf
;
1007 MonoArrayHandle result
;
1008 result
= mono_array_new_handle (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
1009 goto_if_nok (error
, fail
);
1012 base
= MONO_ARRAY_HANDLE_PIN (result
, char, 0, &gchandle
);
1013 memcpy (base
, buf
.buf
, buflen
);
1014 sigbuffer_free (&buf
);
1015 mono_gchandle_free_internal (gchandle
);
1018 sigbuffer_free (&buf
);
1019 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
1022 static MonoArrayHandle
1023 reflection_sighelper_get_signature_field (MonoReflectionSigHelperHandle sig
, MonoError
*error
)
1025 MonoReflectionModuleBuilderHandle module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, sig
, module
);
1026 MonoDynamicImage
*assembly
= MONO_HANDLE_GETVAL (module
, dynamic_image
);
1027 MonoArrayHandle sig_arguments
= MONO_HANDLE_NEW_GET (MonoArray
, sig
, arguments
);
1028 guint32 na
= MONO_HANDLE_IS_NULL (sig_arguments
) ? 0 : mono_array_handle_length (sig_arguments
);
1034 sigbuffer_init (&buf
, 32);
1036 sigbuffer_add_value (&buf
, 0x06);
1037 for (i
= 0; i
< na
; ++i
) {
1038 if (! encode_reflection_types (assembly
, sig_arguments
, i
, &buf
, error
))
1042 buflen
= buf
.p
- buf
.buf
;
1043 MonoArrayHandle result
;
1044 result
= mono_array_new_handle (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
1045 goto_if_nok (error
, fail
);
1048 base
= MONO_ARRAY_HANDLE_PIN (result
, char, 0, &gchandle
);
1049 memcpy (base
, buf
.buf
, buflen
);
1050 sigbuffer_free (&buf
);
1051 mono_gchandle_free_internal (gchandle
);
1055 sigbuffer_free (&buf
);
1056 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
1060 type_get_fully_qualified_name (MonoType
*type
)
1062 MONO_REQ_GC_NEUTRAL_MODE
;
1064 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
1067 #ifndef DISABLE_REFLECTION_EMIT_SAVE
1069 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage
*assembly
, MonoReflectionMarshal
*minfo
, MonoError
*error
)
1071 MONO_REQ_GC_UNSAFE_MODE
;
1079 sigbuffer_init (&buf
, 32);
1081 sigbuffer_add_value (&buf
, minfo
->type
);
1083 switch (minfo
->type
) {
1084 case MONO_NATIVE_BYVALTSTR
:
1085 case MONO_NATIVE_BYVALARRAY
:
1086 sigbuffer_add_value (&buf
, minfo
->count
);
1088 case MONO_NATIVE_LPARRAY
:
1089 if (minfo
->eltype
|| minfo
->has_size
) {
1090 sigbuffer_add_value (&buf
, minfo
->eltype
);
1091 if (minfo
->has_size
) {
1092 sigbuffer_add_value (&buf
, minfo
->param_num
!= -1? minfo
->param_num
: 0);
1093 sigbuffer_add_value (&buf
, minfo
->count
!= -1? minfo
->count
: 0);
1095 /* LAMESPEC: ElemMult is undocumented */
1096 sigbuffer_add_value (&buf
, minfo
->param_num
!= -1? 1: 0);
1100 case MONO_NATIVE_SAFEARRAY
:
1102 sigbuffer_add_value (&buf
, minfo
->eltype
);
1104 case MONO_NATIVE_CUSTOM
:
1106 str
= mono_string_to_utf8_checked_internal (minfo
->guid
, error
);
1107 if (!is_ok (error
)) {
1108 sigbuffer_free (&buf
);
1112 sigbuffer_add_value (&buf
, len
);
1113 sigbuffer_add_mem (&buf
, str
, len
);
1116 sigbuffer_add_value (&buf
, 0);
1118 /* native type name */
1119 sigbuffer_add_value (&buf
, 0);
1120 /* custom marshaler type name */
1121 if (minfo
->marshaltype
|| minfo
->marshaltyperef
) {
1122 if (minfo
->marshaltyperef
) {
1123 MonoType
*marshaltype
= mono_reflection_type_get_handle ((MonoReflectionType
*)minfo
->marshaltyperef
, error
);
1124 if (!is_ok (error
)) {
1125 sigbuffer_free (&buf
);
1128 str
= type_get_fully_qualified_name (marshaltype
);
1130 str
= mono_string_to_utf8_checked_internal (minfo
->marshaltype
, error
);
1131 if (!is_ok (error
)) {
1132 sigbuffer_free (&buf
);
1137 sigbuffer_add_value (&buf
, len
);
1138 sigbuffer_add_mem (&buf
, str
, len
);
1141 /* FIXME: Actually a bug, since this field is required. Punting for now ... */
1142 sigbuffer_add_value (&buf
, 0);
1144 if (minfo
->mcookie
) {
1145 str
= mono_string_to_utf8_checked_internal (minfo
->mcookie
, error
);
1146 if (!is_ok (error
)) {
1147 sigbuffer_free (&buf
);
1151 sigbuffer_add_value (&buf
, len
);
1152 sigbuffer_add_mem (&buf
, str
, len
);
1155 sigbuffer_add_value (&buf
, 0);
1161 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
1162 sigbuffer_free (&buf
);
1167 mono_dynimage_save_encode_property_signature (MonoDynamicImage
*assembly
, MonoReflectionPropertyBuilder
*fb
, MonoError
*error
)
1169 MONO_REQ_GC_UNSAFE_MODE
;
1174 guint32 nparams
= 0;
1175 MonoReflectionMethodBuilder
*mb
= fb
->get_method
;
1176 MonoReflectionMethodBuilder
*smb
= fb
->set_method
;
1179 if (mb
&& mb
->parameters
)
1180 nparams
= mono_array_length_internal (mb
->parameters
);
1181 if (!mb
&& smb
&& smb
->parameters
)
1182 nparams
= mono_array_length_internal (smb
->parameters
) - 1;
1183 sigbuffer_init (&buf
, 32);
1184 if (fb
->call_conv
& 0x20)
1185 sigbuffer_add_byte (&buf
, 0x28);
1187 sigbuffer_add_byte (&buf
, 0x08);
1188 sigbuffer_add_value (&buf
, nparams
);
1190 encode_reflection_type_raw (assembly
, (MonoReflectionType
*)mb
->rtype
, &buf
, error
);
1193 for (i
= 0; i
< nparams
; ++i
) {
1194 MonoReflectionType
*pt
= mono_array_get_internal (mb
->parameters
, MonoReflectionType
*, i
);
1195 encode_reflection_type_raw (assembly
, pt
, &buf
, error
);
1199 } else if (smb
&& smb
->parameters
) {
1200 /* the property type is the last param */
1201 encode_reflection_type_raw (assembly
, mono_array_get_internal (smb
->parameters
, MonoReflectionType
*, nparams
), &buf
, error
);
1205 for (i
= 0; i
< nparams
; ++i
) {
1206 MonoReflectionType
*pt
= mono_array_get_internal (smb
->parameters
, MonoReflectionType
*, i
);
1207 encode_reflection_type_raw (assembly
, pt
, &buf
, error
);
1212 encode_reflection_type_raw (assembly
, (MonoReflectionType
*)fb
->type
, &buf
, error
);
1217 idx
= sigbuffer_add_to_blob_cached (assembly
, &buf
);
1218 sigbuffer_free (&buf
);
1221 sigbuffer_free (&buf
);
1226 #else /*DISABLE_REFLECTION_EMIT_SAVE*/
1228 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage
*assembly
, MonoReflectionMarshal
*minfo
, MonoError
*error
)
1230 g_assert_not_reached ();
1235 mono_dynimage_save_encode_property_signature (MonoDynamicImage
*assembly
, MonoReflectionPropertyBuilder
*fb
, MonoError
*error
)
1237 g_assert_not_reached ();
1240 #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
1242 #ifndef DISABLE_REFLECTION_EMIT
1244 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig
, MonoError
*error
)
1247 return reflection_sighelper_get_signature_local (sig
, error
);
1251 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig
, MonoError
*error
)
1254 return reflection_sighelper_get_signature_field (sig
, error
);
1256 #else /* DISABLE_REFLECTION_EMIT */
1258 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig
, MonoError
*error
)
1261 g_assert_not_reached ();
1262 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
1266 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig
, MonoError
*error
)
1269 g_assert_not_reached ();
1270 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
1273 #endif /* DISABLE_REFLECTION_EMIT */