3 * Routines for creating an image at runtime
4 * and related System.Reflection.Emit icalls
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.
19 #include "mono/metadata/assembly.h"
20 #include "mono/metadata/class-init.h"
21 #include "mono/metadata/debug-helpers.h"
22 #include "mono/metadata/dynamic-image-internals.h"
23 #include "mono/metadata/dynamic-stream-internals.h"
24 #include "mono/metadata/exception.h"
25 #include "mono/metadata/gc-internals.h"
26 #include "mono/metadata/mono-ptr-array.h"
27 #include "mono/metadata/object-internals.h"
28 #include "mono/metadata/profiler-private.h"
29 #include "mono/metadata/reflection-internals.h"
30 #include "mono/metadata/reflection-cache.h"
31 #include "mono/metadata/sre-internals.h"
32 #include "mono/metadata/custom-attrs-internals.h"
33 #include "mono/metadata/security-manager.h"
34 #include "mono/metadata/security-core-clr.h"
35 #include "mono/metadata/tabledefs.h"
36 #include "mono/metadata/tokentype.h"
37 #include "mono/metadata/abi-details.h"
38 #include "mono/utils/checked-build.h"
39 #include "mono/utils/mono-digest.h"
40 #include "mono/utils/w32api.h"
41 #ifdef MONO_CLASS_DEF_PRIVATE
42 /* Rationale: Some of the code here does MonoClass construction.
43 * FIXME: Move SRE class construction to class-init.c and unify with ordinary class construction.
45 #define REALLY_INCLUDE_CLASS_DEF 1
46 #include <mono/metadata/class-private-definition.h>
47 #undef REALLY_INCLUDE_CLASS_DEF
49 #include "icall-decl.h"
51 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute
, "System.Runtime.InteropServices", "MarshalAsAttribute");
52 static GENERATE_GET_CLASS_WITH_CACHE (module_builder
, "System.Reflection.Emit", "ModuleBuilder");
54 static char* string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s
, MonoError
*error
);
56 #ifndef DISABLE_REFLECTION_EMIT
57 static guint32
mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
);
58 static gboolean
ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
);
59 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
);
60 static gboolean
reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
61 static gboolean
reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
62 static gboolean
reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
);
65 static gpointer
register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
);
68 static char* type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
);
69 static MonoReflectionTypeHandle
mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
);
70 static gboolean
is_sre_array (MonoClass
*klass
);
71 static gboolean
is_sre_byref (MonoClass
*klass
);
72 static gboolean
is_sre_pointer (MonoClass
*klass
);
73 static gboolean
is_sre_generic_instance (MonoClass
*klass
);
74 static gboolean
is_sre_type_builder (MonoClass
*klass
);
75 static gboolean
is_sre_method_builder (MonoClass
*klass
);
76 static gboolean
is_sre_field_builder (MonoClass
*klass
);
77 static gboolean
is_sre_gparam_builder (MonoClass
*klass
);
78 static gboolean
is_sre_enum_builder (MonoClass
*klass
);
79 static gboolean
is_sr_mono_method (MonoClass
*klass
);
80 static gboolean
is_sr_mono_field (MonoClass
*klass
);
82 static guint32
mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
);
83 static guint32
mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
);
84 static guint32
mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
);
87 #ifndef DISABLE_REFLECTION_EMIT
88 static MonoType
* mono_type_array_get_and_resolve_raw (MonoArray
* array
, int idx
, MonoError
* error
);
91 static gboolean
mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module
, MonoError
*error
);
94 mono_reflection_emit_init (void)
96 mono_dynamic_images_init ();
100 string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s_raw
, MonoError
*error
)
102 /* FIXME all callers to string_to_utf8_image_raw should use handles */
103 HANDLE_FUNCTION_ENTER ();
106 MONO_HANDLE_DCL (MonoString
, s
);
107 result
= mono_string_to_utf8_image (image
, s
, error
);
108 HANDLE_FUNCTION_RETURN_VAL (result
);
112 type_get_fully_qualified_name (MonoType
*type
)
114 MONO_REQ_GC_NEUTRAL_MODE
;
116 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
120 type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
)
122 MONO_REQ_GC_UNSAFE_MODE
;
127 klass
= mono_class_from_mono_type_internal (type
);
129 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
130 ta
= klass
->image
->assembly
;
131 if (assembly_is_dynamic (ta
) || (ta
== ass
)) {
132 if (mono_class_is_ginst (klass
) || mono_class_is_gtd (klass
))
133 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
134 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_FULL_NAME
);
136 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
139 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
142 #ifndef DISABLE_REFLECTION_EMIT
146 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
150 image_g_malloc (MonoImage
*image
, guint size
)
152 MONO_REQ_GC_NEUTRAL_MODE
;
155 return mono_image_alloc (image
, size
);
157 return g_malloc (size
);
159 #endif /* !DISABLE_REFLECTION_EMIT */
164 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
168 (mono_image_g_malloc0
) (MonoImage
*image
, guint size
)
170 MONO_REQ_GC_NEUTRAL_MODE
;
173 return mono_image_alloc0 (image
, size
);
175 return g_malloc0 (size
);
180 * @image: a MonoImage
183 * If @image is NULL, free @ptr, otherwise do nothing.
186 image_g_free (MonoImage
*image
, gpointer ptr
)
192 #ifndef DISABLE_REFLECTION_EMIT
194 image_strdup (MonoImage
*image
, const char *s
)
196 MONO_REQ_GC_NEUTRAL_MODE
;
199 return mono_image_strdup (image
, s
);
205 #define image_g_new(image,struct_type, n_structs) \
206 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
208 #define image_g_new0(image,struct_type, n_structs) \
209 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
213 alloc_table (MonoDynamicTable
*table
, guint nrows
)
215 mono_dynimage_alloc_table (table
, nrows
);
219 string_heap_insert (MonoDynamicStream
*sh
, const char *str
)
221 return mono_dynstream_insert_string (sh
, str
);
225 mono_image_add_stream_data (MonoDynamicStream
*stream
, const char *data
, guint32 len
)
227 return mono_dynstream_add_data (stream
, data
, len
);
231 * Despite the name, we handle also TypeSpec (with the above helper).
234 mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
)
236 return mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, TRUE
);
240 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
241 * dest may be misaligned.
244 swap_with_size (gpointer void_dest
, gconstpointer void_val
, int len
, int nelem
)
246 char *dest
= (char*)void_dest
;
247 const char* val
= (const char*)void_val
;
248 MONO_REQ_GC_NEUTRAL_MODE
;
249 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
252 for (elem
= 0; elem
< nelem
; ++elem
) {
278 g_assert_not_reached ();
284 memcpy (dest
, val
, len
* nelem
);
289 mono_reflection_method_count_clauses (MonoReflectionILGen
*ilgen
)
291 MONO_REQ_GC_UNSAFE_MODE
;
293 guint32 num_clauses
= 0;
296 MonoILExceptionInfo
*ex_info
;
297 for (i
= 0; i
< mono_array_length_internal (ilgen
->ex_handlers
); ++i
) {
298 ex_info
= (MonoILExceptionInfo
*)mono_array_addr_internal (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
299 if (ex_info
->handlers
)
300 num_clauses
+= mono_array_length_internal (ex_info
->handlers
);
308 #ifndef DISABLE_REFLECTION_EMIT
309 static MonoExceptionClause
*
310 method_encode_clauses (MonoImage
*image
, MonoDynamicImage
*assembly
, MonoReflectionILGen
*ilgen
, guint32 num_clauses
, MonoError
*error
)
312 MONO_REQ_GC_UNSAFE_MODE
;
316 MonoExceptionClause
*clauses
;
317 MonoExceptionClause
*clause
;
318 MonoILExceptionInfo
*ex_info
;
319 MonoILExceptionBlock
*ex_block
;
320 guint32 finally_start
;
321 int i
, j
, clause_index
;
323 clauses
= image_g_new0 (image
, MonoExceptionClause
, num_clauses
);
326 for (i
= mono_array_length_internal (ilgen
->ex_handlers
) - 1; i
>= 0; --i
) {
327 ex_info
= (MonoILExceptionInfo
*)mono_array_addr_internal (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
328 finally_start
= ex_info
->start
+ ex_info
->len
;
329 if (!ex_info
->handlers
)
331 for (j
= 0; j
< mono_array_length_internal (ex_info
->handlers
); ++j
) {
332 ex_block
= (MonoILExceptionBlock
*)mono_array_addr_internal (ex_info
->handlers
, MonoILExceptionBlock
, j
);
333 clause
= &(clauses
[clause_index
]);
335 clause
->flags
= ex_block
->type
;
336 clause
->try_offset
= ex_info
->start
;
338 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FINALLY
)
339 clause
->try_len
= finally_start
- ex_info
->start
;
341 clause
->try_len
= ex_info
->len
;
342 clause
->handler_offset
= ex_block
->start
;
343 clause
->handler_len
= ex_block
->len
;
344 if (ex_block
->extype
) {
345 MonoType
*extype
= mono_reflection_type_get_handle ((MonoReflectionType
*)ex_block
->extype
, error
);
347 if (!is_ok (error
)) {
348 image_g_free (image
, clauses
);
351 clause
->data
.catch_class
= mono_class_from_mono_type_internal (extype
);
353 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FILTER
)
354 clause
->data
.filter_offset
= ex_block
->filter_offset
;
356 clause
->data
.filter_offset
= 0;
358 finally_start
= ex_block
->start
+ ex_block
->len
;
366 #endif /* !DISABLE_REFLECTION_EMIT */
368 #ifndef DISABLE_REFLECTION_EMIT
370 * LOCKING: Acquires the loader lock.
373 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
375 MONO_REQ_GC_UNSAFE_MODE
;
377 MonoCustomAttrInfo
*ainfo
, *tmp
;
379 if (!cattrs
|| !mono_array_length_internal (cattrs
))
382 ainfo
= mono_custom_attrs_from_builders (image
, image
, cattrs
);
385 tmp
= (MonoCustomAttrInfo
*)mono_image_property_lookup (image
, obj
, MONO_PROP_DYNAMIC_CATTR
);
387 mono_custom_attrs_free (tmp
);
388 mono_image_property_insert (image
, obj
, MONO_PROP_DYNAMIC_CATTR
, ainfo
);
389 mono_loader_unlock ();
393 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
395 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
401 mono_reflection_resolution_scope_from_image (MonoDynamicImage
*assembly
, MonoImage
*image
)
403 MONO_REQ_GC_UNSAFE_MODE
;
405 MonoDynamicTable
*table
;
408 guint32 cols
[MONO_ASSEMBLY_SIZE
];
412 if ((token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, image
))))
415 if (assembly_is_dynamic (image
->assembly
) && (image
->assembly
== assembly
->image
.assembly
)) {
416 table
= &assembly
->tables
[MONO_TABLE_MODULEREF
];
417 token
= table
->next_idx
++;
419 alloc_table (table
, table
->rows
);
420 values
= table
->values
+ token
* MONO_MODULEREF_SIZE
;
421 values
[MONO_MODULEREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->module_name
);
423 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
424 token
|= MONO_RESOLUTION_SCOPE_MODULEREF
;
425 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
430 if (assembly_is_dynamic (image
->assembly
))
432 memset (cols
, 0, sizeof (cols
));
434 /* image->assembly->image is the manifest module */
435 image
= image
->assembly
->image
;
436 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_ASSEMBLY
], 0, cols
, MONO_ASSEMBLY_SIZE
);
439 table
= &assembly
->tables
[MONO_TABLE_ASSEMBLYREF
];
440 token
= table
->next_idx
++;
442 alloc_table (table
, table
->rows
);
443 values
= table
->values
+ token
* MONO_ASSEMBLYREF_SIZE
;
444 values
[MONO_ASSEMBLYREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->assembly_name
);
445 values
[MONO_ASSEMBLYREF_MAJOR_VERSION
] = cols
[MONO_ASSEMBLY_MAJOR_VERSION
];
446 values
[MONO_ASSEMBLYREF_MINOR_VERSION
] = cols
[MONO_ASSEMBLY_MINOR_VERSION
];
447 values
[MONO_ASSEMBLYREF_BUILD_NUMBER
] = cols
[MONO_ASSEMBLY_BUILD_NUMBER
];
448 values
[MONO_ASSEMBLYREF_REV_NUMBER
] = cols
[MONO_ASSEMBLY_REV_NUMBER
];
449 values
[MONO_ASSEMBLYREF_FLAGS
] = 0;
450 values
[MONO_ASSEMBLYREF_CULTURE
] = 0;
451 values
[MONO_ASSEMBLYREF_HASH_VALUE
] = 0;
453 if (strcmp ("", image
->assembly
->aname
.culture
)) {
454 values
[MONO_ASSEMBLYREF_CULTURE
] = string_heap_insert (&assembly
->sheap
,
455 image
->assembly
->aname
.culture
);
458 if ((pubkey
= mono_image_get_public_key (image
, &publen
))) {
461 mono_digest_get_public_token (pubtoken
+ 1, (guchar
*)pubkey
, publen
);
462 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = mono_image_add_stream_data (&assembly
->blob
, (char*)pubtoken
, 9);
464 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = 0;
466 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
467 token
|= MONO_RESOLUTION_SCOPE_ASSEMBLYREF
;
468 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
472 #ifndef DISABLE_REFLECTION_EMIT
474 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
)
476 MONO_REQ_GC_UNSAFE_MODE
;
479 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
481 rmb
->ilgen
= mb
->ilgen
;
482 rmb
->rtype
= (MonoReflectionType
*)mb
->rtype
;
483 return_val_if_nok (error
, FALSE
);
484 rmb
->parameters
= mb
->parameters
;
485 rmb
->generic_params
= mb
->generic_params
;
486 rmb
->generic_container
= mb
->generic_container
;
487 rmb
->opt_types
= NULL
;
488 rmb
->pinfo
= mb
->pinfo
;
489 rmb
->attrs
= mb
->attrs
;
490 rmb
->iattrs
= mb
->iattrs
;
491 rmb
->call_conv
= mb
->call_conv
;
492 rmb
->code
= mb
->code
;
493 rmb
->type
= mb
->type
;
494 rmb
->name
= mb
->name
;
495 rmb
->table_idx
= &mb
->table_idx
;
496 rmb
->init_locals
= mb
->init_locals
;
497 rmb
->skip_visibility
= FALSE
;
498 rmb
->return_modreq
= mb
->return_modreq
;
499 rmb
->return_modopt
= mb
->return_modopt
;
500 rmb
->param_modreq
= mb
->param_modreq
;
501 rmb
->param_modopt
= mb
->param_modopt
;
502 rmb
->permissions
= mb
->permissions
;
503 rmb
->mhandle
= mb
->mhandle
;
508 rmb
->charset
= mb
->charset
;
509 rmb
->extra_flags
= mb
->extra_flags
;
510 rmb
->native_cc
= mb
->native_cc
;
511 rmb
->dllentry
= mb
->dllentry
;
519 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
521 MONO_REQ_GC_UNSAFE_MODE
;
523 const char *name
= mb
->attrs
& METHOD_ATTRIBUTE_STATIC
? ".cctor": ".ctor";
527 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
529 rmb
->ilgen
= mb
->ilgen
;
530 rmb
->rtype
= mono_type_get_object_checked (mono_domain_get (), mono_get_void_type (), error
);
531 return_val_if_nok (error
, FALSE
);
532 rmb
->parameters
= mb
->parameters
;
533 rmb
->generic_params
= NULL
;
534 rmb
->generic_container
= NULL
;
535 rmb
->opt_types
= NULL
;
536 rmb
->pinfo
= mb
->pinfo
;
537 rmb
->attrs
= mb
->attrs
;
538 rmb
->iattrs
= mb
->iattrs
;
539 rmb
->call_conv
= mb
->call_conv
;
541 rmb
->type
= mb
->type
;
542 rmb
->name
= mono_string_new_checked (mono_domain_get (), name
, error
);
543 return_val_if_nok (error
, FALSE
);
544 rmb
->table_idx
= &mb
->table_idx
;
545 rmb
->init_locals
= mb
->init_locals
;
546 rmb
->skip_visibility
= FALSE
;
547 rmb
->return_modreq
= NULL
;
548 rmb
->return_modopt
= NULL
;
549 rmb
->param_modreq
= mb
->param_modreq
;
550 rmb
->param_modopt
= mb
->param_modopt
;
551 rmb
->permissions
= mb
->permissions
;
552 rmb
->mhandle
= mb
->mhandle
;
560 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
)
562 MONO_REQ_GC_UNSAFE_MODE
;
564 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
566 rmb
->ilgen
= mb
->ilgen
;
567 rmb
->rtype
= mb
->rtype
;
568 rmb
->parameters
= mb
->parameters
;
569 rmb
->generic_params
= NULL
;
570 rmb
->generic_container
= NULL
;
571 rmb
->opt_types
= NULL
;
573 rmb
->attrs
= mb
->attrs
;
575 rmb
->call_conv
= mb
->call_conv
;
577 rmb
->type
= (MonoObject
*) mb
->owner
;
578 rmb
->name
= mb
->name
;
579 rmb
->table_idx
= NULL
;
580 rmb
->init_locals
= mb
->init_locals
;
581 rmb
->skip_visibility
= mb
->skip_visibility
;
582 rmb
->return_modreq
= NULL
;
583 rmb
->return_modopt
= NULL
;
584 rmb
->param_modreq
= NULL
;
585 rmb
->param_modopt
= NULL
;
586 rmb
->permissions
= NULL
;
587 rmb
->mhandle
= mb
->mhandle
;
591 #else /* DISABLE_REFLECTION_EMIT */
593 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
) {
594 g_assert_not_reached ();
598 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
600 g_assert_not_reached ();
603 #endif /* DISABLE_REFLECTION_EMIT */
605 #ifndef DISABLE_REFLECTION_EMIT
607 mono_image_add_memberef_row (MonoDynamicImage
*assembly
, guint32 parent
, const char *name
, guint32 sig
)
609 MONO_REQ_GC_NEUTRAL_MODE
;
611 MonoDynamicTable
*table
;
613 guint32 token
, pclass
;
615 switch (parent
& MONO_TYPEDEFORREF_MASK
) {
616 case MONO_TYPEDEFORREF_TYPEREF
:
617 pclass
= MONO_MEMBERREF_PARENT_TYPEREF
;
619 case MONO_TYPEDEFORREF_TYPESPEC
:
620 pclass
= MONO_MEMBERREF_PARENT_TYPESPEC
;
622 case MONO_TYPEDEFORREF_TYPEDEF
:
623 pclass
= MONO_MEMBERREF_PARENT_TYPEDEF
;
626 g_warning ("unknown typeref or def token 0x%08x for %s", parent
, name
);
629 /* extract the index */
630 parent
>>= MONO_TYPEDEFORREF_BITS
;
632 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
634 if (assembly
->save
) {
635 alloc_table (table
, table
->rows
+ 1);
636 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
637 values
[MONO_MEMBERREF_CLASS
] = pclass
| (parent
<< MONO_MEMBERREF_PARENT_BITS
);
638 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
639 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
642 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
649 * Insert a memberef row into the metadata: the token that point to the memberref
650 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
651 * mono_image_get_fieldref_token()).
652 * The sig param is an index to an already built signature.
655 mono_image_get_memberref_token (MonoDynamicImage
*assembly
, MonoType
*type
, const char *name
, guint32 sig
)
657 MONO_REQ_GC_NEUTRAL_MODE
;
659 guint32 parent
= mono_image_typedef_or_ref (assembly
, type
);
660 return mono_image_add_memberef_row (assembly
, parent
, name
, sig
);
665 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
667 MONO_REQ_GC_NEUTRAL_MODE
;
670 MonoMethodSignature
*sig
;
672 create_typespec
= create_typespec
&& method
->is_generic
&& method
->klass
->image
!= &assembly
->image
;
674 if (create_typespec
) {
675 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1)));
680 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
681 if (token
&& !create_typespec
)
684 g_assert (!method
->is_inflated
);
687 * A methodref signature can't contain an unmanaged calling convention.
689 sig
= mono_metadata_signature_dup (mono_method_signature_internal (method
));
690 if ((sig
->call_convention
!= MONO_CALL_DEFAULT
) && (sig
->call_convention
!= MONO_CALL_VARARG
))
691 sig
->call_convention
= MONO_CALL_DEFAULT
;
692 token
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (method
->klass
),
693 method
->name
, mono_dynimage_encode_method_signature (assembly
, sig
));
695 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
698 if (create_typespec
) {
699 MonoDynamicTable
*table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
700 g_assert (mono_metadata_token_table (token
) == MONO_TABLE_MEMBERREF
);
701 token
= (mono_metadata_token_index (token
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
703 if (assembly
->save
) {
706 alloc_table (table
, table
->rows
+ 1);
707 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
708 values
[MONO_METHODSPEC_METHOD
] = token
;
709 values
[MONO_METHODSPEC_SIGNATURE
] = mono_dynimage_encode_generic_method_sig (assembly
, &mono_method_get_generic_container (method
)->context
);
712 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
714 /*methodspec and memberef tokens are diferent, */
715 g_hash_table_insert (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1), GUINT_TO_POINTER (token
));
722 mono_image_get_varargs_method_token (MonoDynamicImage
*assembly
, guint32 original
,
723 const gchar
*name
, guint32 sig
)
725 MonoDynamicTable
*table
;
729 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
731 if (assembly
->save
) {
732 alloc_table (table
, table
->rows
+ 1);
733 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
734 values
[MONO_MEMBERREF_CLASS
] = original
;
735 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
736 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
739 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
745 #else /* DISABLE_REFLECTION_EMIT */
748 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
750 g_assert_not_reached ();
756 is_field_on_inst (MonoClassField
*field
)
758 return mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->is_dynamic
;
762 is_field_on_gtd (MonoClassField
*field
)
764 return mono_class_is_gtd (field
->parent
);
767 #ifndef DISABLE_REFLECTION_EMIT
769 mono_image_get_fieldref_token (MonoDynamicImage
*assembly
, MonoClassField
*field
)
775 g_assert (field
->parent
);
777 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, field
));
781 if (mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->container_class
&& mono_class_get_generic_class (field
->parent
)->container_class
->fields
) {
782 int index
= field
- field
->parent
->fields
;
783 type
= mono_field_get_type_internal (&mono_class_get_generic_class (field
->parent
)->container_class
->fields
[index
]);
785 type
= mono_field_get_type_internal (field
);
787 token
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (field
->parent
),
788 mono_field_get_name (field
),
789 mono_dynimage_encode_fieldref_signature (assembly
, field
->parent
->image
, type
));
790 g_hash_table_insert (assembly
->handleref
, field
, GUINT_TO_POINTER(token
));
795 method_encode_methodspec (MonoDynamicImage
*assembly
, MonoMethod
*method
)
797 MonoDynamicTable
*table
;
799 guint32 token
, mtoken
= 0, sig
;
800 MonoMethodInflated
*imethod
;
801 MonoMethod
*declaring
;
803 table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
805 g_assert (method
->is_inflated
);
806 imethod
= (MonoMethodInflated
*) method
;
807 declaring
= imethod
->declaring
;
809 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature_internal (declaring
));
810 mtoken
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (method
->klass
), declaring
->name
, sig
);
812 if (!mono_method_signature_internal (declaring
)->generic_param_count
)
815 switch (mono_metadata_token_table (mtoken
)) {
816 case MONO_TABLE_MEMBERREF
:
817 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
819 case MONO_TABLE_METHOD
:
820 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODDEF
;
823 g_assert_not_reached ();
826 sig
= mono_dynimage_encode_generic_method_sig (assembly
, mono_method_get_context (method
));
828 if (assembly
->save
) {
829 alloc_table (table
, table
->rows
+ 1);
830 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
831 values
[MONO_METHODSPEC_METHOD
] = mtoken
;
832 values
[MONO_METHODSPEC_SIGNATURE
] = sig
;
835 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
842 mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
)
844 MonoMethodInflated
*imethod
;
847 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
851 g_assert (method
->is_inflated
);
852 imethod
= (MonoMethodInflated
*) method
;
854 if (mono_method_signature_internal (imethod
->declaring
)->generic_param_count
) {
855 token
= method_encode_methodspec (assembly
, method
);
857 guint32 sig
= mono_dynimage_encode_method_signature (
858 assembly
, mono_method_signature_internal (imethod
->declaring
));
859 token
= mono_image_get_memberref_token (
860 assembly
, m_class_get_byval_arg (method
->klass
), method
->name
, sig
);
863 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
868 mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
)
870 MonoMethodInflated
*imethod
= (MonoMethodInflated
*) m
;
873 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature_internal (imethod
->declaring
));
874 token
= mono_image_get_memberref_token (
875 assembly
, m_class_get_byval_arg (m
->klass
), m
->name
, sig
);
881 mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
)
884 MonoDynamicTable
*table
;
889 table
= &assembly
->tables
[MONO_TABLE_STANDALONESIG
];
890 idx
= table
->next_idx
++;
892 alloc_table (table
, table
->rows
);
893 values
= table
->values
+ idx
* MONO_STAND_ALONE_SIGNATURE_SIZE
;
895 values
[MONO_STAND_ALONE_SIGNATURE
] =
896 mono_dynimage_encode_reflection_sighelper (assembly
, helper
, error
);
897 return_val_if_nok (error
, 0);
903 reflection_cc_to_file (int call_conv
) {
904 switch (call_conv
& 0x3) {
906 case 1: return MONO_CALL_DEFAULT
;
907 case 2: return MONO_CALL_VARARG
;
909 g_assert_not_reached ();
913 #endif /* !DISABLE_REFLECTION_EMIT */
915 struct _ArrayMethod
{
917 MonoMethodSignature
*sig
;
923 mono_sre_array_method_free (ArrayMethod
*am
)
930 #ifndef DISABLE_REFLECTION_EMIT
932 mono_image_get_array_token (MonoDynamicImage
*assembly
, MonoReflectionArrayMethodHandle m
, MonoError
*error
)
934 MonoMethodSignature
*sig
= NULL
;
939 MonoArrayHandle parameters
= MONO_HANDLE_NEW_GET (MonoArray
, m
, parameters
);
940 guint32 nparams
= mono_array_handle_length (parameters
);
941 sig
= (MonoMethodSignature
*)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * nparams
);
943 sig
->sentinelpos
= -1;
944 sig
->call_convention
= reflection_cc_to_file (MONO_HANDLE_GETVAL (m
, call_conv
));
945 sig
->param_count
= nparams
;
946 MonoReflectionTypeHandle ret
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, ret
);
947 if (!MONO_HANDLE_IS_NULL (ret
)) {
948 sig
->ret
= mono_reflection_type_handle_mono_type (ret
, error
);
949 goto_if_nok (error
, fail
);
951 sig
->ret
= mono_get_void_type ();
953 MonoReflectionTypeHandle parent
;
954 parent
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, parent
);
956 mtype
= mono_reflection_type_handle_mono_type (parent
, error
);
957 goto_if_nok (error
, fail
);
959 for (int i
= 0; i
< nparams
; ++i
) {
960 sig
->params
[i
] = mono_type_array_get_and_resolve (parameters
, i
, error
);
961 goto_if_nok (error
, fail
);
964 MonoStringHandle mname
;
965 mname
= MONO_HANDLE_NEW_GET (MonoString
, m
, name
);
966 name
= mono_string_handle_to_utf8 (mname
, error
);
967 goto_if_nok (error
, fail
);
971 for (GList
*tmp
= assembly
->array_methods
; tmp
; tmp
= tmp
->next
) {
972 am
= (ArrayMethod
*)tmp
->data
;
973 if (strcmp (name
, am
->name
) == 0 &&
974 mono_metadata_type_equal (am
->parent
, mtype
) &&
975 mono_metadata_signature_equal (am
->sig
, sig
)) {
978 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
982 am
= g_new0 (ArrayMethod
, 1);
986 am
->token
= mono_image_get_memberref_token (assembly
, am
->parent
, name
,
987 mono_dynimage_encode_method_signature (assembly
, sig
));
988 assembly
->array_methods
= g_list_prepend (assembly
->array_methods
, am
);
989 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
999 #ifndef DISABLE_REFLECTION_EMIT
1002 * mono_image_insert_string:
1003 * @module: module builder object
1006 * Insert @str into the user string stream of @module.
1009 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module
, MonoStringHandle str
, MonoError
*error
)
1011 HANDLE_FUNCTION_ENTER ();
1017 MonoDynamicImage
*assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1019 if (!mono_image_module_basic_init (ref_module
, error
))
1022 assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1024 g_assert (assembly
!= NULL
);
1026 if (assembly
->save
) {
1027 int32_t length
= mono_string_length_internal (MONO_HANDLE_RAW (str
));
1028 mono_metadata_encode_value (1 | (length
* 2), b
, &b
);
1029 idx
= mono_image_add_stream_data (&assembly
->us
, buf
, b
-buf
);
1031 uint32_t gchandle
= mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject
, str
), TRUE
);
1032 const char *p
= (const char*)mono_string_chars_internal (MONO_HANDLE_RAW (str
));
1033 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1035 char *swapped
= g_malloc (2 * length
);
1037 swap_with_size (swapped
, p
, 2, length
);
1038 mono_image_add_stream_data (&assembly
->us
, swapped
, length
* 2);
1042 mono_image_add_stream_data (&assembly
->us
, p
, length
* 2);
1044 mono_gchandle_free_internal (gchandle
);
1045 mono_image_add_stream_data (&assembly
->us
, "", 1);
1047 idx
= assembly
->us
.index
++;
1050 token
= MONO_TOKEN_STRING
| idx
;
1051 mono_dynamic_image_register_token (assembly
, token
, MONO_HANDLE_CAST (MonoObject
, str
), MONO_DYN_IMAGE_TOK_NEW
);
1054 HANDLE_FUNCTION_RETURN_VAL (token
);
1058 create_method_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1060 guint32 sig_token
, parent
;
1063 int nargs
= mono_array_handle_length (opt_param_types
);
1064 MonoMethodSignature
*old
= mono_method_signature_internal (method
);
1065 MonoMethodSignature
*sig
= mono_metadata_signature_alloc ( &assembly
->image
, old
->param_count
+ nargs
);
1067 sig
->hasthis
= old
->hasthis
;
1068 sig
->explicit_this
= old
->explicit_this
;
1069 sig
->call_convention
= old
->call_convention
;
1070 sig
->generic_param_count
= old
->generic_param_count
;
1071 sig
->param_count
= old
->param_count
+ nargs
;
1072 sig
->sentinelpos
= old
->param_count
;
1073 sig
->ret
= old
->ret
;
1075 for (int i
= 0; i
< old
->param_count
; i
++)
1076 sig
->params
[i
] = old
->params
[i
];
1078 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1079 for (int i
= 0; i
< nargs
; i
++) {
1080 MONO_HANDLE_ARRAY_GETREF (rt
, opt_param_types
, i
);
1081 sig
->params
[old
->param_count
+ i
] = mono_reflection_type_handle_mono_type (rt
, error
);
1082 goto_if_nok (error
, fail
);
1085 parent
= mono_image_typedef_or_ref (assembly
, m_class_get_byval_arg (method
->klass
));
1086 g_assert ((parent
& MONO_TYPEDEFORREF_MASK
) == MONO_MEMBERREF_PARENT_TYPEREF
);
1087 parent
>>= MONO_TYPEDEFORREF_BITS
;
1089 parent
<<= MONO_MEMBERREF_PARENT_BITS
;
1090 parent
|= MONO_MEMBERREF_PARENT_TYPEREF
;
1092 sig_token
= mono_dynimage_encode_method_signature (assembly
, sig
);
1094 token
= mono_image_get_varargs_method_token (assembly
, parent
, method
->name
, sig_token
);
1095 g_hash_table_insert (assembly
->vararg_aux_hash
, GUINT_TO_POINTER (token
), sig
);
1102 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1108 MonoClass
*klass
= mono_handle_class (obj
);
1109 if (strcmp (klass
->name
, "RuntimeMethodInfo") == 0 || strcmp (klass
->name
, "RuntimeConstructorInfo") == 0) {
1110 MonoReflectionMethodHandle ref_method
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1111 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
1112 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types
) && (mono_method_signature_internal (method
)->sentinelpos
>= 0));
1113 token
= create_method_token (assembly
, method
, opt_param_types
, error
);
1114 goto_if_nok (error
, fail
);
1115 } else if (strcmp (klass
->name
, "MethodBuilder") == 0) {
1116 g_assert_not_reached ();
1118 g_error ("requested method token for %s\n", klass
->name
);
1121 mono_dynamic_image_register_token (assembly
, token
, obj
, MONO_DYN_IMAGE_TOK_NEW
);
1124 g_assert (!mono_error_ok (error
));
1129 * mono_image_create_token:
1130 * @assembly: a dynamic assembly
1132 * @register_token: Whenever to register the token in the assembly->tokens hash.
1134 * Get a token to insert in the IL code stream for the given MemberInfo.
1135 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1136 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1140 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
1141 gboolean create_open_instance
, gboolean register_token
,
1144 HANDLE_FUNCTION_ENTER ();
1149 MonoClass
*klass
= mono_handle_class (obj
);
1150 MonoObjectHandle register_obj
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1151 MONO_HANDLE_ASSIGN (register_obj
, obj
);
1153 /* Check for user defined reflection objects */
1154 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1155 if (klass
->image
!= mono_defaults
.corlib
|| (strcmp (klass
->name
, "TypeDelegator") == 0)) {
1156 mono_error_set_not_supported (error
, "User defined subclasses of System.Type are not yet supported");
1160 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1162 how_collide
= MONO_DYN_IMAGE_TOK_SAME_OK
;
1164 if (strcmp (klass
->name
, "RuntimeType") == 0) {
1165 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, obj
), error
);
1166 goto_if_nok (error
, leave
);
1167 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
1168 token
= mono_metadata_token_from_dor (
1169 mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, !mono_class_is_gtd (mc
) || create_open_instance
));
1170 /* If it's a RuntimeType now, we could have registered a
1171 * TypeBuilder for it before, so replacing is okay. */
1172 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1173 } else if (strcmp (klass
->name
, "RuntimeMethodInfo") == 0 ||
1174 strcmp (klass
->name
, "RuntimeConstructorInfo") == 0) {
1175 MonoReflectionMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1176 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
1177 if (method
->is_inflated
) {
1178 if (create_open_instance
) {
1179 guint32 methodspec_token
= mono_image_get_methodspec_token (assembly
, method
);
1180 MonoReflectionMethodHandle canonical_obj
=
1181 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1182 goto_if_nok (error
, leave
);
1183 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1184 token
= methodspec_token
;
1186 token
= mono_image_get_inflated_method_token (assembly
, method
);
1187 } else if ((method
->klass
->image
== &assembly
->image
) &&
1188 !mono_class_is_ginst (method
->klass
) &&
1189 !mono_class_is_gtd (method
->klass
)) {
1190 static guint32 method_table_idx
= 0xffffff;
1191 if (method
->klass
->wastypebuilder
) {
1192 /* we use the same token as the one that was assigned
1193 * to the Methodbuilder.
1194 * FIXME: do the equivalent for Fields.
1196 token
= method
->token
;
1197 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1200 * Each token should have a unique index, but the indexes are
1201 * assigned by managed code, so we don't know about them. An
1202 * easy solution is to count backwards...
1204 method_table_idx
--;
1205 token
= MONO_TOKEN_METHOD_DEF
| method_table_idx
;
1206 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1209 guint32 methodref_token
= mono_image_get_methodref_token (assembly
, method
, create_open_instance
);
1210 /* We need to register a 'canonical' object. The same
1211 * MonoMethod could have been reflected via different
1212 * classes so the MonoReflectionMethod:reftype could be
1213 * different, and the object lookup in
1214 * dynamic_image_register_token would assert assert. So
1215 * we pick the MonoReflectionMethod object that has the
1216 * reflected type as NULL (ie, take the declaring type
1218 MonoReflectionMethodHandle canonical_obj
=
1219 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1220 goto_if_nok (error
, leave
);
1221 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1222 token
= methodref_token
;
1224 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1225 } else if (strcmp (klass
->name
, "RuntimeFieldInfo") == 0) {
1226 MonoReflectionFieldHandle f
= MONO_HANDLE_CAST (MonoReflectionField
, obj
);
1227 MonoClassField
*field
= MONO_HANDLE_GETVAL (f
, field
);
1228 if ((field
->parent
->image
== &assembly
->image
) &&
1229 !is_field_on_gtd (field
) &&
1230 !is_field_on_inst (field
)) {
1231 static guint32 field_table_idx
= 0xffffff;
1233 token
= MONO_TOKEN_FIELD_DEF
| field_table_idx
;
1234 g_assert (!mono_class_is_gtd (field
->parent
));
1235 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1237 guint32 fieldref_token
= mono_image_get_fieldref_token (assembly
, field
);
1238 /* Same as methodref: get a canonical object to
1239 * register with the token. */
1240 MonoReflectionFieldHandle canonical_obj
=
1241 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj
), field
->parent
, field
, error
);
1242 goto_if_nok (error
, leave
);
1243 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1244 token
= fieldref_token
;
1246 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1247 } else if (strcmp (klass
->name
, "MonoArrayMethod") == 0) {
1248 MonoReflectionArrayMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionArrayMethod
, obj
);
1249 /* mono_image_get_array_token caches tokens by signature */
1250 guint32 array_token
= mono_image_get_array_token (assembly
, m
, error
);
1251 goto_if_nok (error
, leave
);
1252 token
= array_token
;
1253 /* ModuleBuilder:GetArrayMethod() always returns a fresh
1254 * MonoArrayMethod instance even given the same method name and
1255 * signature. But they're all interchangeable, so it's okay to
1258 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1259 } else if (strcmp (klass
->name
, "SignatureHelper") == 0) {
1260 MonoReflectionSigHelperHandle s
= MONO_HANDLE_CAST (MonoReflectionSigHelper
, obj
);
1261 /* always returns a fresh token */
1262 guint32 sig_token
= MONO_TOKEN_SIGNATURE
| mono_image_get_sighelper_token (assembly
, s
, error
);
1263 goto_if_nok (error
, leave
);
1265 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1267 g_error ("requested token for %s\n", klass
->name
);
1271 mono_dynamic_image_register_token (assembly
, token
, register_obj
, how_collide
);
1274 HANDLE_FUNCTION_RETURN_VAL (token
);
1280 #ifndef DISABLE_REFLECTION_EMIT
1283 assemblybuilderaccess_can_refonlyload (guint32 access
)
1285 return (access
& 0x4) != 0;
1289 assemblybuilderaccess_can_run (guint32 access
)
1291 return (access
& MonoAssemblyBuilderAccess_Run
) != 0;
1295 assemblybuilderaccess_can_save (guint32 access
)
1297 return (access
& MonoAssemblyBuilderAccess_Save
) != 0;
1302 * mono_reflection_dynimage_basic_init:
1303 * @assembly: an assembly builder object
1305 * Create the MonoImage that represents the assembly builder and setup some
1306 * of the helper hash table and the basic metadata streams.
1309 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
1312 MonoDynamicAssembly
*assembly
;
1313 MonoDynamicImage
*image
;
1314 MonoDomain
*domain
= mono_object_domain (assemblyb
);
1316 if (assemblyb
->dynamic_assembly
)
1319 assembly
= assemblyb
->dynamic_assembly
= g_new0 (MonoDynamicAssembly
, 1);
1321 MONO_PROFILER_RAISE (assembly_loading
, (&assembly
->assembly
));
1323 assembly
->assembly
.ref_count
= 1;
1324 assembly
->assembly
.dynamic
= TRUE
;
1325 assembly
->assembly
.corlib_internal
= assemblyb
->corlib_internal
;
1326 assemblyb
->assembly
.assembly
= (MonoAssembly
*)assembly
;
1327 assembly
->assembly
.basedir
= mono_string_to_utf8_checked_internal (assemblyb
->dir
, error
);
1328 if (mono_error_set_pending_exception (error
))
1330 if (assemblyb
->culture
) {
1331 assembly
->assembly
.aname
.culture
= mono_string_to_utf8_checked_internal (assemblyb
->culture
, error
);
1332 if (mono_error_set_pending_exception (error
))
1335 assembly
->assembly
.aname
.culture
= g_strdup ("");
1337 if (assemblyb
->version
) {
1338 char *vstr
= mono_string_to_utf8_checked_internal (assemblyb
->version
, error
);
1339 if (mono_error_set_pending_exception (error
))
1341 char **version
= g_strsplit (vstr
, ".", 4);
1342 char **parts
= version
;
1343 assembly
->assembly
.aname
.major
= atoi (*parts
++);
1344 assembly
->assembly
.aname
.minor
= atoi (*parts
++);
1345 assembly
->assembly
.aname
.build
= *parts
!= NULL
? atoi (*parts
++) : 0;
1346 assembly
->assembly
.aname
.revision
= *parts
!= NULL
? atoi (*parts
) : 0;
1348 g_strfreev (version
);
1351 assembly
->assembly
.aname
.major
= 0;
1352 assembly
->assembly
.aname
.minor
= 0;
1353 assembly
->assembly
.aname
.build
= 0;
1354 assembly
->assembly
.aname
.revision
= 0;
1357 /* SRE assemblies are loaded into the individual loading context, ie,
1358 * they only fire AssemblyResolve events, they don't cause probing for
1359 * referenced assemblies to happen. */
1360 assembly
->assembly
.context
.kind
= assemblybuilderaccess_can_refonlyload (assemblyb
->access
) ? MONO_ASMCTX_REFONLY
: MONO_ASMCTX_INDIVIDUAL
;
1361 assembly
->run
= assemblybuilderaccess_can_run (assemblyb
->access
);
1362 assembly
->save
= assemblybuilderaccess_can_save (assemblyb
->access
);
1363 assembly
->domain
= domain
;
1365 char *assembly_name
= mono_string_to_utf8_checked_internal (assemblyb
->name
, error
);
1366 if (mono_error_set_pending_exception (error
))
1368 image
= mono_dynamic_image_create (assembly
, assembly_name
, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1369 image
->initial_image
= TRUE
;
1370 assembly
->assembly
.aname
.name
= image
->image
.name
;
1371 assembly
->assembly
.image
= &image
->image
;
1372 if (assemblyb
->pktoken
&& assemblyb
->pktoken
->max_length
) {
1373 /* -1 to correct for the trailing NULL byte */
1374 if (assemblyb
->pktoken
->max_length
!= MONO_PUBLIC_KEY_TOKEN_LENGTH
- 1) {
1375 g_error ("Public key token length invalid for assembly %s: %i", assembly
->assembly
.aname
.name
, assemblyb
->pktoken
->max_length
);
1377 memcpy (&assembly
->assembly
.aname
.public_key_token
, mono_array_addr_internal (assemblyb
->pktoken
, guint8
, 0), assemblyb
->pktoken
->max_length
);
1380 mono_domain_assemblies_lock (domain
);
1381 domain
->domain_assemblies
= g_slist_append (domain
->domain_assemblies
, assembly
);
1382 mono_domain_assemblies_unlock (domain
);
1384 register_assembly (mono_object_domain (assemblyb
), &assemblyb
->assembly
, &assembly
->assembly
);
1386 MONO_PROFILER_RAISE (assembly_loaded
, (&assembly
->assembly
));
1388 mono_assembly_invoke_load_hook ((MonoAssembly
*)assembly
);
1391 #endif /* !DISABLE_REFLECTION_EMIT */
1393 #ifndef DISABLE_REFLECTION_EMIT
1395 register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
)
1397 return CACHE_OBJECT (MonoReflectionAssembly
*, assembly
, &res
->object
, NULL
);
1400 static MonoReflectionModuleBuilderHandle
1401 register_module (MonoDomain
*domain
, MonoReflectionModuleBuilderHandle res
, MonoDynamicImage
*module
)
1403 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilder
, module
, MONO_HANDLE_CAST (MonoObject
, res
), NULL
);
1407 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1410 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (moduleb
);
1411 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
1412 MonoReflectionAssemblyBuilderHandle ab
= MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder
, NULL
);
1413 MONO_HANDLE_GET (ab
, moduleb
, assemblyb
);
1416 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1417 * we don't know which module it belongs to, since that is only
1418 * determined at assembly save time.
1420 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1421 MonoStringHandle abname
= MONO_HANDLE_NEW_GET (MonoString
, ab
, name
);
1422 char *name
= mono_string_handle_to_utf8 (abname
, error
);
1423 return_val_if_nok (error
, FALSE
);
1424 MonoStringHandle modfqname
= MONO_HANDLE_NEW_GET (MonoString
, MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), fqname
);
1425 char *fqname
= mono_string_handle_to_utf8 (modfqname
, error
);
1426 if (!is_ok (error
)) {
1430 MonoDynamicAssembly
*dynamic_assembly
= MONO_HANDLE_GETVAL (ab
, dynamic_assembly
);
1431 image
= mono_dynamic_image_create (dynamic_assembly
, name
, fqname
);
1433 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), image
, MonoImage
*, &image
->image
);
1434 MONO_HANDLE_SETVAL (moduleb
, dynamic_image
, MonoDynamicImage
*, image
);
1435 register_module (domain
, moduleb
, image
);
1437 /* register the module with the assembly */
1438 MonoImage
*ass
= dynamic_assembly
->assembly
.image
;
1439 int module_count
= ass
->module_count
;
1440 MonoImage
**new_modules
= g_new0 (MonoImage
*, module_count
+ 1);
1443 memcpy (new_modules
, ass
->modules
, module_count
* sizeof (MonoImage
*));
1444 new_modules
[module_count
] = &image
->image
;
1445 mono_image_addref (&image
->image
);
1447 g_free (ass
->modules
);
1448 ass
->modules
= new_modules
;
1449 ass
->module_count
++;
1455 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1458 return image_module_basic_init (moduleb
, error
);
1464 is_corlib_type (MonoClass
*klass
)
1466 return klass
->image
== mono_defaults
.corlib
;
1469 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1470 static MonoClass *cached_class; \
1472 return cached_class == _class; \
1473 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1474 cached_class = _class; \
1482 mono_type_array_get_and_resolve (MonoArrayHandle array
, int idx
, MonoError
*error
)
1484 HANDLE_FUNCTION_ENTER();
1486 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1487 MONO_HANDLE_ARRAY_GETREF (t
, array
, idx
);
1488 MonoType
*result
= mono_reflection_type_handle_mono_type (t
, error
);
1489 HANDLE_FUNCTION_RETURN_VAL (result
);
1493 add_custom_modifiers_to_type (MonoType
*without_mods
, MonoArrayHandle req_array
, MonoArrayHandle opt_array
, MonoImage
*image
, MonoError
*error
)
1495 HANDLE_FUNCTION_ENTER();
1498 int num_req_mods
= 0;
1499 if (!MONO_HANDLE_IS_NULL (req_array
))
1500 num_req_mods
= mono_array_handle_length (req_array
);
1502 int num_opt_mods
= 0;
1503 if (!MONO_HANDLE_IS_NULL (opt_array
))
1504 num_opt_mods
= mono_array_handle_length (opt_array
);
1506 const int total_mods
= num_req_mods
+ num_opt_mods
;
1507 if (total_mods
== 0)
1508 return without_mods
;
1510 MonoTypeWithModifiers
*result
;
1511 result
= mono_image_g_malloc0 (image
, mono_sizeof_type_with_mods (total_mods
, FALSE
));
1512 memcpy (result
, without_mods
, MONO_SIZEOF_TYPE
);
1513 result
->unmodified
.has_cmods
= 1;
1514 MonoCustomModContainer
*cmods
= mono_type_get_cmods ((MonoType
*)result
);
1516 cmods
->count
= total_mods
;
1517 cmods
->image
= image
;
1519 g_assert (image_is_dynamic (image
));
1520 MonoDynamicImage
*allocator
= (MonoDynamicImage
*) image
;
1522 g_assert (total_mods
> 0);
1523 /* store cmods in reverse order from how the API supplies them.
1524 (Assemblies store modifiers in reverse order of IL syntax - and SRE
1525 follows the same order as IL syntax). */
1526 int modifier_index
= total_mods
- 1;
1528 MonoObjectHandle mod_handle
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1529 for (int i
=0; i
< num_req_mods
; i
++) {
1530 cmods
->modifiers
[modifier_index
].required
= TRUE
;
1531 MONO_HANDLE_ARRAY_GETREF (mod_handle
, req_array
, i
);
1532 cmods
->modifiers
[modifier_index
].token
= mono_image_create_token (allocator
, mod_handle
, FALSE
, TRUE
, error
);
1536 for (int i
=0; i
< num_opt_mods
; i
++) {
1537 cmods
->modifiers
[modifier_index
].required
= FALSE
;
1538 MONO_HANDLE_ARRAY_GETREF (mod_handle
, opt_array
, i
);
1539 cmods
->modifiers
[modifier_index
].token
= mono_image_create_token (allocator
, mod_handle
, FALSE
, TRUE
, error
);
1543 g_assert (modifier_index
== -1);
1545 HANDLE_FUNCTION_RETURN_VAL ((MonoType
*) result
);
1550 mono_type_array_get_and_resolve_with_modifiers (MonoArrayHandle types
, MonoArrayHandle required_modifiers
, MonoArrayHandle optional_modifiers
, int idx
, MonoImage
*image
, MonoError
*error
)
1552 HANDLE_FUNCTION_ENTER();
1554 MonoReflectionTypeHandle type
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1555 MonoArrayHandle req_mods_handle
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1556 MonoArrayHandle opt_mods_handle
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1558 if (!MONO_HANDLE_IS_NULL (required_modifiers
))
1559 MONO_HANDLE_ARRAY_GETREF (req_mods_handle
, required_modifiers
, idx
);
1561 if (!MONO_HANDLE_IS_NULL (optional_modifiers
))
1562 MONO_HANDLE_ARRAY_GETREF (opt_mods_handle
, optional_modifiers
, idx
);
1564 MONO_HANDLE_ARRAY_GETREF (type
, types
, idx
);
1566 MonoType
*result
= mono_reflection_type_handle_mono_type (type
, error
);
1567 result
= (MonoType
*) add_custom_modifiers_to_type (result
, req_mods_handle
, opt_mods_handle
, image
, error
);
1569 HANDLE_FUNCTION_RETURN_VAL (result
);
1573 #ifndef DISABLE_REFLECTION_EMIT
1575 is_sre_array (MonoClass
*klass
)
1577 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ArrayType");
1581 is_sre_byref (MonoClass
*klass
)
1583 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ByRefType");
1587 is_sre_pointer (MonoClass
*klass
)
1589 check_corlib_type_cached (klass
, "System.Reflection.Emit", "PointerType");
1593 is_sre_generic_instance (MonoClass
*klass
)
1595 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilderInstantiation");
1599 is_sre_type_builder (MonoClass
*klass
)
1601 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilder");
1605 is_sre_method_builder (MonoClass
*klass
)
1607 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodBuilder");
1611 mono_is_sre_ctor_builder (MonoClass
*klass
)
1613 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorBuilder");
1617 is_sre_field_builder (MonoClass
*klass
)
1619 check_corlib_type_cached (klass
, "System.Reflection.Emit", "FieldBuilder");
1623 is_sre_gparam_builder (MonoClass
*klass
)
1625 check_corlib_type_cached (klass
, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1629 is_sre_enum_builder (MonoClass
*klass
)
1631 check_corlib_type_cached (klass
, "System.Reflection.Emit", "EnumBuilder");
1635 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1637 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1641 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1643 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1646 static MonoReflectionTypeHandle
1647 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
)
1649 static MonoMethod
*method_get_underlying_system_type
= NULL
;
1650 HANDLE_FUNCTION_ENTER ();
1654 if (!method_get_underlying_system_type
) {
1655 method_get_underlying_system_type
= mono_class_get_method_from_name_checked (mono_defaults
.systemtype_class
, "get_UnderlyingSystemType", 0, 0, error
);
1656 mono_error_assert_ok (error
);
1659 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1661 MonoMethod
*usertype_method
= mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject
, t
), method_get_underlying_system_type
, error
);
1662 goto_if_nok (error
, leave
);
1664 MONO_HANDLE_ASSIGN (rt
, MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW (MonoObject
, mono_runtime_invoke_checked (usertype_method
, MONO_HANDLE_RAW (t
), NULL
, error
))));
1667 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType
, rt
);
1671 mono_reflection_type_get_handle (MonoReflectionType
* ref_raw
, MonoError
*error
)
1673 HANDLE_FUNCTION_ENTER ();
1675 MONO_HANDLE_DCL (MonoReflectionType
, ref
);
1676 MonoType
*result
= mono_reflection_type_handle_mono_type (ref
, error
);
1677 HANDLE_FUNCTION_RETURN_VAL (result
);
1681 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass
, MonoError
*error
)
1683 HANDLE_FUNCTION_ENTER ();
1684 MonoType
*result
= NULL
;
1685 MonoType
**types
= NULL
;
1687 MonoArrayHandle typeargs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_gclass
, type_arguments
);
1688 int count
= mono_array_handle_length (typeargs
);
1689 types
= g_new0 (MonoType
*, count
);
1690 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1691 for (int i
= 0; i
< count
; ++i
) {
1692 MONO_HANDLE_ARRAY_GETREF (t
, typeargs
, i
);
1693 types
[i
] = mono_reflection_type_handle_mono_type (t
, error
);
1694 if (!types
[i
] || !is_ok (error
)) {
1698 /* Need to resolve the generic_type in order for it to create its generic context. */
1699 MonoReflectionTypeHandle ref_gtd
;
1700 ref_gtd
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_gclass
, generic_type
);
1702 gtd
= mono_reflection_type_handle_mono_type (ref_gtd
, error
);
1703 goto_if_nok (error
, leave
);
1704 MonoClass
*gtd_klass
;
1705 gtd_klass
= mono_class_from_mono_type_internal (gtd
);
1706 if (is_sre_type_builder (mono_handle_class (ref_gtd
))) {
1707 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_gtd
), error
);
1708 goto_if_nok (error
, leave
);
1710 g_assert (count
== 0 || mono_class_is_gtd (gtd_klass
));
1711 result
= mono_reflection_bind_generic_parameters (ref_gtd
, count
, types
, error
);
1712 goto_if_nok (error
, leave
);
1714 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gclass
), type
, MonoType
*, result
);
1717 HANDLE_FUNCTION_RETURN_VAL (result
);
1721 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam
, MonoError
*error
)
1723 HANDLE_FUNCTION_ENTER ();
1725 MonoType
*result
= NULL
;
1728 MonoReflectionTypeBuilderHandle ref_tbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_gparam
, tbuilder
);
1729 MonoReflectionModuleBuilderHandle ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tbuilder
, module
);
1730 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1731 MonoImage
*image
= &dynamic_image
->image
;
1733 MonoGenericParamFull
*param
= mono_image_new0 (image
, MonoGenericParamFull
, 1);
1735 MonoStringHandle ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_gparam
, name
);
1736 param
->info
.name
= mono_string_to_utf8_image (image
, ref_name
, error
);
1737 mono_error_assert_ok (error
);
1738 param
->num
= MONO_HANDLE_GETVAL (ref_gparam
, index
);
1740 MonoReflectionMethodBuilderHandle ref_mbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder
, ref_gparam
, mbuilder
);
1741 if (!MONO_HANDLE_IS_NULL (ref_mbuilder
)) {
1742 MonoGenericContainer
*generic_container
= MONO_HANDLE_GETVAL (ref_mbuilder
, generic_container
);
1743 if (!generic_container
) {
1744 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (image
, sizeof (MonoGenericContainer
));
1745 generic_container
->is_method
= TRUE
;
1747 * Cannot set owner.method, since the MonoMethod is not created yet.
1748 * Set the image field instead, so type_in_image () works.
1750 generic_container
->is_anonymous
= TRUE
;
1751 generic_container
->owner
.image
= image
;
1752 MONO_HANDLE_SETVAL (ref_mbuilder
, generic_container
, MonoGenericContainer
*, generic_container
);
1754 param
->owner
= generic_container
;
1756 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_tbuilder
), error
);
1757 goto_if_nok (error
, leave
);
1759 owner
= mono_class_from_mono_type_internal (type
);
1760 g_assert (mono_class_is_gtd (owner
));
1761 param
->owner
= mono_class_get_generic_container (owner
);
1765 pklass
= mono_class_create_generic_parameter ((MonoGenericParam
*) param
);
1767 result
= m_class_get_byval_arg (pklass
);
1769 mono_class_set_ref_info (pklass
, MONO_HANDLE_CAST (MonoObject
, ref_gparam
));
1770 mono_image_append_class_to_reflection_info_set (pklass
);
1772 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), type
, MonoType
*, result
);
1775 HANDLE_FUNCTION_RETURN_VAL (result
);
1779 mono_type_array_get_and_resolve_raw (MonoArray
* array_raw
, int idx
, MonoError
*error
)
1781 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1783 MONO_HANDLE_DCL (MonoArray
, array
);
1784 MonoType
*result
= mono_type_array_get_and_resolve (array
, idx
, error
);
1785 HANDLE_FUNCTION_RETURN_VAL (result
);
1789 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
1791 HANDLE_FUNCTION_ENTER ();
1794 MonoType
* result
= NULL
;
1796 g_assert (!MONO_HANDLE_IS_NULL (ref
));
1797 if (MONO_HANDLE_IS_NULL (ref
))
1800 t
= MONO_HANDLE_GETVAL (ref
, type
);
1806 if (mono_reflection_is_usertype (ref
)) {
1807 MONO_HANDLE_ASSIGN (ref
, mono_reflection_type_get_underlying_system_type (ref
, error
));
1808 if (!is_ok (error
) || MONO_HANDLE_IS_NULL (ref
) || mono_reflection_is_usertype (ref
))
1810 t
= MONO_HANDLE_GETVAL (ref
, type
);
1818 klass
= mono_handle_class (ref
);
1820 if (is_sre_array (klass
)) {
1821 MonoReflectionArrayTypeHandle sre_array
= MONO_HANDLE_CAST (MonoReflectionArrayType
, ref
);
1822 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_array
, element_type
);
1823 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1824 goto_if_nok (error
, leave
);
1826 gint32 rank
= MONO_HANDLE_GETVAL (sre_array
, rank
);
1827 MonoClass
*eclass
= mono_class_from_mono_type_internal (base
);
1828 result
= mono_image_new0 (eclass
->image
, MonoType
, 1);
1830 result
->type
= MONO_TYPE_SZARRAY
;
1831 result
->data
.klass
= eclass
;
1833 MonoArrayType
*at
= (MonoArrayType
*)mono_image_alloc0 (eclass
->image
, sizeof (MonoArrayType
));
1834 result
->type
= MONO_TYPE_ARRAY
;
1835 result
->data
.array
= at
;
1836 at
->eklass
= eclass
;
1839 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1840 } else if (is_sre_byref (klass
)) {
1841 MonoReflectionDerivedTypeHandle sre_byref
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1842 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_byref
, element_type
);
1843 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1844 goto_if_nok (error
, leave
);
1846 result
= &mono_class_from_mono_type_internal (base
)->this_arg
;
1847 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1848 } else if (is_sre_pointer (klass
)) {
1849 MonoReflectionDerivedTypeHandle sre_pointer
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1850 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_pointer
, element_type
);
1851 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1852 goto_if_nok (error
, leave
);
1854 result
= m_class_get_byval_arg (mono_class_create_ptr (base
));
1855 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1856 } else if (is_sre_generic_instance (klass
)) {
1857 result
= reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass
, ref
), error
);
1858 } else if (is_sre_gparam_builder (klass
)) {
1859 result
= reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam
, ref
), error
);
1860 } else if (is_sre_enum_builder (klass
)) {
1861 MonoReflectionEnumBuilderHandle ref_ebuilder
= MONO_HANDLE_CAST (MonoReflectionEnumBuilder
, ref
);
1863 MonoReflectionTypeHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_ebuilder
, tb
));
1864 result
= mono_reflection_type_handle_mono_type (ref_tb
, error
);
1865 } else if (is_sre_type_builder (klass
)) {
1866 MonoReflectionTypeBuilderHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref
);
1868 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1869 reflection_setup_internal_class (ref_tb
, error
);
1870 mono_error_assert_ok (error
);
1871 result
= MONO_HANDLE_GETVAL (ref
, type
);
1873 g_error ("Cannot handle corlib user type %s", mono_type_full_name (m_class_get_byval_arg (mono_handle_class (ref
))));
1876 HANDLE_FUNCTION_RETURN_VAL (result
);
1880 * LOCKING: Assumes the loader lock is held.
1882 static MonoMethodSignature
*
1883 parameters_to_signature (MonoImage
*image
, MonoArrayHandle parameters
, MonoArrayHandle required_modifiers
, MonoArrayHandle optional_modifiers
, MonoError
*error
) {
1884 MonoMethodSignature
*sig
;
1889 count
= MONO_HANDLE_IS_NULL (parameters
) ? 0 : mono_array_handle_length (parameters
);
1891 sig
= (MonoMethodSignature
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * count
);
1892 sig
->param_count
= count
;
1893 sig
->sentinelpos
= -1; /* FIXME */
1894 for (i
= 0; i
< count
; ++i
) {
1895 sig
->params
[i
] = mono_type_array_get_and_resolve_with_modifiers (parameters
, required_modifiers
, optional_modifiers
, i
, image
, error
);
1896 if (!is_ok (error
)) {
1897 image_g_free (image
, sig
);
1905 * LOCKING: Assumes the loader lock is held.
1907 static MonoMethodSignature
*
1908 ctor_builder_to_signature (MonoImage
*image
, MonoReflectionCtorBuilderHandle ctor
, MonoError
*error
) {
1909 MonoMethodSignature
*sig
;
1912 MonoArrayHandle params
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, parameters
);
1913 MonoArrayHandle required_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, param_modreq
);
1914 MonoArrayHandle optional_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, param_modopt
);
1916 sig
= parameters_to_signature (image
, params
, required_modifiers
, optional_modifiers
, error
);
1917 return_val_if_nok (error
, NULL
);
1918 sig
->hasthis
= MONO_HANDLE_GETVAL (ctor
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1919 sig
->ret
= mono_get_void_type ();
1923 static MonoMethodSignature
*
1924 ctor_builder_to_signature_raw (MonoImage
*image
, MonoReflectionCtorBuilder
* ctor_raw
, MonoError
*error
) {
1925 HANDLE_FUNCTION_ENTER();
1926 MONO_HANDLE_DCL (MonoReflectionCtorBuilder
, ctor
);
1927 MonoMethodSignature
*sig
= ctor_builder_to_signature (image
, ctor
, error
);
1928 HANDLE_FUNCTION_RETURN_VAL (sig
);
1931 * LOCKING: Assumes the loader lock is held.
1933 static MonoMethodSignature
*
1934 method_builder_to_signature (MonoImage
*image
, MonoReflectionMethodBuilderHandle method
, MonoError
*error
)
1936 MonoMethodSignature
*sig
;
1939 MonoArrayHandle params
= MONO_HANDLE_NEW_GET(MonoArray
, method
, parameters
);
1940 MonoArrayHandle required_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, method
, param_modreq
);
1941 MonoArrayHandle optional_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, method
, param_modopt
);
1942 MonoArrayHandle ret_req_modifiers
= MONO_HANDLE_NEW_GET (MonoArray
, method
, return_modreq
);
1943 MonoArrayHandle ret_opt_modifiers
= MONO_HANDLE_NEW_GET (MonoArray
, method
, return_modopt
);
1945 sig
= parameters_to_signature (image
, params
, required_modifiers
, optional_modifiers
, error
);
1946 return_val_if_nok (error
, NULL
);
1947 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1948 MonoReflectionTypeHandle rtype
;
1949 rtype
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoObject
, method
, rtype
));
1950 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1951 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1952 sig
->ret
= add_custom_modifiers_to_type (sig
->ret
, ret_req_modifiers
, ret_opt_modifiers
, image
, error
);
1953 if (!is_ok (error
)) {
1954 image_g_free (image
, sig
);
1958 sig
->ret
= mono_get_void_type ();
1960 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, method
, generic_params
);
1961 sig
->generic_param_count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
1965 static MonoMethodSignature
*
1966 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method
, MonoError
*error
)
1968 HANDLE_FUNCTION_ENTER ();
1969 MonoMethodSignature
*sig
= NULL
;
1973 sig
= parameters_to_signature (NULL
, MONO_HANDLE_NEW_GET (MonoArray
, method
, parameters
),
1974 MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
), MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
), error
);
1975 goto_if_nok (error
, leave
);
1976 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1977 MonoReflectionTypeHandle rtype
;
1978 rtype
= MONO_HANDLE_NEW_GET (MonoReflectionType
, method
, rtype
);
1979 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1980 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1981 if (!is_ok (error
)) {
1987 sig
->ret
= mono_get_void_type ();
1989 sig
->generic_param_count
= 0;
1991 HANDLE_FUNCTION_RETURN_VAL (sig
);
1995 get_prop_name_and_type (MonoObject
*prop
, char **name
, MonoType
**type
, MonoError
*error
)
1998 MonoClass
*klass
= mono_object_class (prop
);
1999 if (strcmp (klass
->name
, "PropertyBuilder") == 0) {
2000 MonoReflectionPropertyBuilder
*pb
= (MonoReflectionPropertyBuilder
*)prop
;
2001 *name
= mono_string_to_utf8_checked_internal (pb
->name
, error
);
2002 return_if_nok (error
);
2003 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)pb
->type
, error
);
2005 MonoReflectionProperty
*p
= (MonoReflectionProperty
*)prop
;
2006 *name
= g_strdup (p
->property
->name
);
2007 if (p
->property
->get
)
2008 *type
= mono_method_signature_internal (p
->property
->get
)->ret
;
2010 *type
= mono_method_signature_internal (p
->property
->set
)->params
[mono_method_signature_internal (p
->property
->set
)->param_count
- 1];
2015 get_field_name_and_type (MonoObject
*field
, char **name
, MonoType
**type
, MonoError
*error
)
2018 MonoClass
*klass
= mono_object_class (field
);
2019 if (strcmp (klass
->name
, "FieldBuilder") == 0) {
2020 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)field
;
2021 *name
= mono_string_to_utf8_checked_internal (fb
->name
, error
);
2022 return_if_nok (error
);
2023 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
2025 MonoReflectionField
*f
= (MonoReflectionField
*)field
;
2026 *name
= g_strdup (mono_field_get_name (f
->field
));
2027 *type
= f
->field
->type
;
2031 #else /* DISABLE_REFLECTION_EMIT */
2034 is_sre_type_builder (MonoClass
*klass
)
2040 is_sre_generic_instance (MonoClass
*klass
)
2046 mono_is_sre_ctor_builder (MonoClass
*klass
)
2052 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
2058 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
2063 #endif /* !DISABLE_REFLECTION_EMIT */
2067 is_sr_mono_field (MonoClass
*klass
)
2069 check_corlib_type_cached (klass
, "System.Reflection", "RuntimeFieldInfo");
2073 mono_is_sr_mono_property (MonoClass
*klass
)
2075 check_corlib_type_cached (klass
, "System.Reflection", "RuntimePropertyInfo");
2079 is_sr_mono_method (MonoClass
*klass
)
2081 check_corlib_type_cached (klass
, "System.Reflection", "RuntimeMethodInfo");
2085 mono_is_sr_mono_cmethod (MonoClass
*klass
)
2087 check_corlib_type_cached (klass
, "System.Reflection", "RuntimeConstructorInfo");
2091 mono_class_is_reflection_method_or_constructor (MonoClass
*klass
)
2093 return is_sr_mono_method (klass
) || mono_is_sr_mono_cmethod (klass
);
2097 mono_is_sre_type_builder (MonoClass
*klass
)
2099 return is_sre_type_builder (klass
);
2103 mono_is_sre_generic_instance (MonoClass
*klass
)
2105 return is_sre_generic_instance (klass
);
2111 * encode_cattr_value:
2112 * Encode a value in a custom attribute stream of bytes.
2113 * The value to encode is either supplied as an object in argument val
2114 * (valuetypes are boxed), or as a pointer to the data in the
2116 * @type represents the type of the value
2117 * @buffer is the start of the buffer
2118 * @p the current position in the buffer
2119 * @buflen contains the size of the buffer and is used to return the new buffer size
2120 * if this needs to be realloced.
2121 * @retbuffer and @retp return the start and the position of the buffer
2122 * @error set on error.
2125 encode_cattr_value (MonoAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, MonoObject
*arg
, gconstpointer void_argval
, MonoError
*error
)
2127 const char *argval
= (const char*)void_argval
;
2128 MonoTypeEnum simple_type
;
2131 if ((p
-buffer
) + 10 >= *buflen
) {
2134 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2135 p
= newbuf
+ (p
-buffer
);
2139 argval
= (const char*)mono_object_get_data (arg
);
2140 simple_type
= type
->type
;
2142 switch (simple_type
) {
2143 case MONO_TYPE_BOOLEAN
:
2148 case MONO_TYPE_CHAR
:
2151 swap_with_size (p
, argval
, 2, 1);
2157 swap_with_size (p
, argval
, 4, 1);
2161 swap_with_size (p
, argval
, 8, 1);
2166 swap_with_size (p
, argval
, 8, 1);
2169 case MONO_TYPE_VALUETYPE
:
2170 if (type
->data
.klass
->enumtype
) {
2171 simple_type
= mono_class_enum_basetype_internal (type
->data
.klass
)->type
;
2174 g_warning ("generic valutype %s not handled in custom attr value decoding", type
->data
.klass
->name
);
2177 case MONO_TYPE_STRING
: {
2184 str
= mono_string_to_utf8_checked_internal ((MonoString
*)arg
, error
);
2185 return_if_nok (error
);
2186 slen
= strlen (str
);
2187 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2191 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2192 p
= newbuf
+ (p
-buffer
);
2195 mono_metadata_encode_value (slen
, p
, &p
);
2196 memcpy (p
, str
, slen
);
2201 case MONO_TYPE_CLASS
: {
2210 arg_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)arg
, error
);
2211 return_if_nok (error
);
2213 str
= type_get_qualified_name (arg_type
, NULL
);
2214 slen
= strlen (str
);
2215 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2219 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2220 p
= newbuf
+ (p
-buffer
);
2223 mono_metadata_encode_value (slen
, p
, &p
);
2224 memcpy (p
, str
, slen
);
2229 case MONO_TYPE_SZARRAY
: {
2231 MonoClass
*eclass
, *arg_eclass
;
2234 *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff;
2237 len
= mono_array_length_internal ((MonoArray
*)arg
);
2239 *p
++ = (len
>> 8) & 0xff;
2240 *p
++ = (len
>> 16) & 0xff;
2241 *p
++ = (len
>> 24) & 0xff;
2243 *retbuffer
= buffer
;
2244 eclass
= type
->data
.klass
;
2245 arg_eclass
= mono_object_class (arg
)->element_class
;
2248 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2249 eclass
= mono_defaults
.object_class
;
2251 if (eclass
== mono_defaults
.object_class
&& arg_eclass
->valuetype
) {
2252 char *elptr
= mono_array_addr_internal ((MonoArray
*)arg
, char, 0);
2253 int elsize
= mono_class_array_element_size (arg_eclass
);
2254 for (i
= 0; i
< len
; ++i
) {
2255 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (arg_eclass
), NULL
, elptr
, error
);
2256 return_if_nok (error
);
2259 } else if (eclass
->valuetype
&& arg_eclass
->valuetype
) {
2260 char *elptr
= mono_array_addr_internal ((MonoArray
*)arg
, char, 0);
2261 int elsize
= mono_class_array_element_size (eclass
);
2262 for (i
= 0; i
< len
; ++i
) {
2263 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (eclass
), NULL
, elptr
, error
);
2264 return_if_nok (error
);
2268 for (i
= 0; i
< len
; ++i
) {
2269 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (eclass
), mono_array_get_internal ((MonoArray
*)arg
, MonoObject
*, i
), NULL
, error
);
2270 return_if_nok (error
);
2275 case MONO_TYPE_OBJECT
: {
2281 * The parameter type is 'object' but the type of the actual
2282 * argument is not. So we have to add type information to the blob
2283 * too. This is completely undocumented in the spec.
2287 *p
++ = MONO_TYPE_STRING
; // It's same hack as MS uses
2292 klass
= mono_object_class (arg
);
2294 if (mono_object_isinst_checked (arg
, mono_defaults
.systemtype_class
, error
)) {
2298 return_if_nok (error
);
2301 MonoType
*klass_byval_arg
= m_class_get_byval_arg (klass
);
2302 if (klass
->enumtype
) {
2304 } else if (klass
== mono_defaults
.string_class
) {
2305 simple_type
= MONO_TYPE_STRING
;
2308 } else if (klass
->rank
== 1) {
2310 if (m_class_get_byval_arg (m_class_get_element_class (klass
))->type
== MONO_TYPE_OBJECT
)
2311 /* See Partition II, Appendix B3 */
2314 *p
++ = m_class_get_byval_arg (m_class_get_element_class (klass
))->type
;
2315 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, klass_byval_arg
, arg
, NULL
, error
);
2316 return_if_nok (error
);
2318 } else if (klass_byval_arg
->type
>= MONO_TYPE_BOOLEAN
&& klass_byval_arg
->type
<= MONO_TYPE_R8
) {
2319 *p
++ = simple_type
= klass_byval_arg
->type
;
2322 mono_error_set_not_supported (error
, "unhandled type in custom attr");
2325 str
= type_get_qualified_name (m_class_get_byval_arg (klass
), NULL
);
2326 slen
= strlen (str
);
2327 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2331 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2332 p
= newbuf
+ (p
-buffer
);
2335 mono_metadata_encode_value (slen
, p
, &p
);
2336 memcpy (p
, str
, slen
);
2339 simple_type
= mono_class_enum_basetype_internal (klass
)->type
;
2343 mono_error_set_not_supported (error
, "type 0x%02x not yet supported in custom attr encoder", simple_type
);
2346 *retbuffer
= buffer
;
2350 encode_field_or_prop_type (MonoType
*type
, char *p
, char **retp
)
2352 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2353 char *str
= type_get_qualified_name (type
, NULL
);
2354 int slen
= strlen (str
);
2358 * This seems to be optional...
2361 mono_metadata_encode_value (slen
, p
, &p
);
2362 memcpy (p
, str
, slen
);
2365 } else if (type
->type
== MONO_TYPE_OBJECT
) {
2367 } else if (type
->type
== MONO_TYPE_CLASS
) {
2368 /* it should be a type: encode_cattr_value () has the check */
2371 mono_metadata_encode_value (type
->type
, p
, &p
);
2372 if (type
->type
== MONO_TYPE_SZARRAY
)
2373 /* See the examples in Partition VI, Annex B */
2374 encode_field_or_prop_type (m_class_get_byval_arg (type
->data
.klass
), p
, &p
);
2380 #ifndef DISABLE_REFLECTION_EMIT
2382 encode_named_val (MonoReflectionAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, char *name
, MonoObject
*value
, MonoError
*error
)
2388 /* Preallocate a large enough buffer */
2389 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2390 char *str
= type_get_qualified_name (type
, NULL
);
2393 } else if (type
->type
== MONO_TYPE_SZARRAY
&& type
->data
.klass
->enumtype
) {
2394 char *str
= type_get_qualified_name (m_class_get_byval_arg (type
->data
.klass
), NULL
);
2400 len
+= strlen (name
);
2402 if ((p
-buffer
) + 20 + len
>= *buflen
) {
2406 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2407 p
= newbuf
+ (p
-buffer
);
2411 encode_field_or_prop_type (type
, p
, &p
);
2413 len
= strlen (name
);
2414 mono_metadata_encode_value (len
, p
, &p
);
2415 memcpy (p
, name
, len
);
2417 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, buflen
, type
, value
, NULL
, error
);
2418 return_if_nok (error
);
2420 *retbuffer
= buffer
;
2424 * mono_reflection_get_custom_attrs_blob:
2425 * \param ctor custom attribute constructor
2426 * \param ctorArgs arguments o the constructor
2430 * \param fieldValues
2431 * Creates the blob of data that needs to be saved in the metadata and that represents
2432 * the custom attributed described by \p ctor, \p ctorArgs etc.
2433 * \returns a \c Byte array representing the blob of data.
2436 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
2439 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, error
);
2440 mono_error_cleanup (error
);
2445 * mono_reflection_get_custom_attrs_blob_checked:
2446 * \param ctor custom attribute constructor
2447 * \param ctorArgs arguments o the constructor
2451 * \param fieldValues
2452 * \param error set on error
2453 * Creates the blob of data that needs to be saved in the metadata and that represents
2454 * the custom attributed described by \p ctor, \p ctorArgs etc.
2455 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2458 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
, MonoError
*error
)
2460 MonoArray
*result
= NULL
;
2461 MonoMethodSignature
*sig
;
2468 if (strcmp (ctor
->vtable
->klass
->name
, "RuntimeConstructorInfo")) {
2469 /* sig is freed later so allocate it in the heap */
2470 sig
= ctor_builder_to_signature_raw (NULL
, (MonoReflectionCtorBuilder
*)ctor
, error
); /* FIXME use handles */
2471 if (!is_ok (error
)) {
2476 sig
= mono_method_signature_internal (((MonoReflectionMethod
*)ctor
)->method
);
2479 g_assert (mono_array_length_internal (ctorArgs
) == sig
->param_count
);
2481 p
= buffer
= (char *)g_malloc (buflen
);
2482 /* write the prolog */
2485 for (i
= 0; i
< sig
->param_count
; ++i
) {
2486 arg
= mono_array_get_internal (ctorArgs
, MonoObject
*, i
);
2487 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, &buflen
, sig
->params
[i
], arg
, NULL
, error
);
2488 goto_if_nok (error
, leave
);
2492 i
+= mono_array_length_internal (properties
);
2494 i
+= mono_array_length_internal (fields
);
2496 *p
++ = (i
>> 8) & 0xff;
2499 for (i
= 0; i
< mono_array_length_internal (properties
); ++i
) {
2503 prop
= (MonoObject
*)mono_array_get_internal (properties
, gpointer
, i
);
2504 get_prop_name_and_type (prop
, &pname
, &ptype
, error
);
2505 goto_if_nok (error
, leave
);
2506 *p
++ = 0x54; /* PROPERTY signature */
2507 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ptype
, pname
, (MonoObject
*)mono_array_get_internal (propValues
, gpointer
, i
), error
);
2509 goto_if_nok (error
, leave
);
2515 for (i
= 0; i
< mono_array_length_internal (fields
); ++i
) {
2519 field
= (MonoObject
*)mono_array_get_internal (fields
, gpointer
, i
);
2520 get_field_name_and_type (field
, &fname
, &ftype
, error
);
2521 goto_if_nok (error
, leave
);
2522 *p
++ = 0x53; /* FIELD signature */
2523 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ftype
, fname
, (MonoObject
*)mono_array_get_internal (fieldValues
, gpointer
, i
), error
);
2525 goto_if_nok (error
, leave
);
2529 g_assert (p
- buffer
<= buflen
);
2530 buflen
= p
- buffer
;
2531 result
= mono_array_new_checked (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
2532 goto_if_nok (error
, leave
);
2533 p
= mono_array_addr_internal (result
, char, 0);
2534 memcpy (p
, buffer
, buflen
);
2537 if (strcmp (ctor
->vtable
->klass
->name
, "RuntimeConstructorInfo"))
2543 reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
)
2547 mono_loader_lock ();
2549 MonoType
*parent_type
;
2550 MonoType
*child_type
;
2551 GHashTableIter iter
;
2553 g_hash_table_iter_init (&iter
, unparented
);
2555 while (g_hash_table_iter_next (&iter
, (gpointer
*) &child_type
, (gpointer
*) &parent_type
)) {
2556 MonoClass
*child_class
= mono_class_from_mono_type_internal (child_type
);
2557 if (parent_type
!= NULL
) {
2558 MonoClass
*parent_class
= mono_class_from_mono_type_internal (parent_type
);
2559 child_class
->parent
= NULL
;
2560 /* fool mono_class_setup_parent */
2561 child_class
->supertypes
= NULL
;
2562 mono_class_setup_parent (child_class
, parent_class
);
2563 } else if (strcmp (child_class
->name
, "Object") == 0 && strcmp (child_class
->name_space
, "System") == 0) {
2564 const char *old_n
= child_class
->name
;
2565 /* trick to get relative numbering right when compiling corlib */
2566 child_class
->name
= "BuildingObject";
2567 mono_class_setup_parent (child_class
, mono_defaults
.object_class
);
2568 child_class
->name
= old_n
;
2570 mono_class_setup_mono_type (child_class
);
2571 mono_class_setup_supertypes (child_class
);
2574 mono_loader_unlock ();
2575 return is_ok (error
);
2579 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2581 HANDLE_FUNCTION_ENTER ();
2584 mono_loader_lock ();
2586 gint32 entering_state
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_tb
), state
);
2587 if (entering_state
!= MonoTypeBuilderNew
) {
2588 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
));
2592 MONO_HANDLE_SETVAL (ref_tb
, state
, gint32
/*MonoTypeBuilderState*/, MonoTypeBuilderEntered
);
2593 MonoReflectionModuleBuilderHandle module_ref
;
2594 module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2595 GHashTable
*unparented_classes
;
2596 unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
2598 // If this type is already setup, exit. We'll fix the parenting later
2600 type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2604 MonoReflectionModuleBuilderHandle ref_module
;
2605 ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2606 MonoDynamicImage
*dynamic_image
;
2607 dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
2609 MonoStringHandle ref_name
;
2610 ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, name
);
2611 MonoStringHandle ref_nspace
;
2612 ref_nspace
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, nspace
);
2615 table_idx
= MONO_HANDLE_GETVAL (ref_tb
, table_idx
);
2617 * The size calculation here warrants some explaining.
2618 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2619 * meaning we need to alloc enough space to morth a def into a gtd.
2622 klass
= (MonoClass
*)mono_image_alloc0 (&dynamic_image
->image
, MAX (sizeof (MonoClassDef
), sizeof (MonoClassGtd
)));
2623 klass
->class_kind
= MONO_CLASS_DEF
;
2625 klass
->image
= &dynamic_image
->image
;
2627 klass
->inited
= 1; /* we lie to the runtime */
2628 klass
->name
= mono_string_to_utf8_image (klass
->image
, ref_name
, error
);
2629 goto_if_nok (error
, leave
);
2630 klass
->name_space
= mono_string_to_utf8_image (klass
->image
, ref_nspace
, error
);
2631 goto_if_nok (error
, leave
);
2632 klass
->type_token
= MONO_TOKEN_TYPE_DEF
| table_idx
;
2633 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
2635 MONO_PROFILER_RAISE (class_loading
, (klass
));
2637 klass
->element_class
= klass
;
2639 g_assert (!mono_class_has_ref_info (klass
));
2640 mono_class_set_ref_info (klass
, MONO_HANDLE_CAST (MonoObject
, ref_tb
));
2642 MonoReflectionTypeHandle ref_nesting_type
;
2643 ref_nesting_type
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_tb
, nesting_type
);
2644 /* Put into cache so mono_class_get_checked () will find it.
2645 Skip nested types as those should not be available on the global scope. */
2646 if (MONO_HANDLE_IS_NULL (ref_nesting_type
))
2647 mono_image_add_to_name_cache (klass
->image
, klass
->name_space
, klass
->name
, table_idx
);
2650 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2651 by performing a mono_class_get which does the full resolution.
2653 Working around this semantics would require us to write a lot of code for no clear advantage.
2655 mono_image_append_class_to_reflection_info_set (klass
);
2657 mono_dynamic_image_register_token (dynamic_image
, MONO_TOKEN_TYPE_DEF
| table_idx
, MONO_HANDLE_CAST (MonoObject
, ref_tb
), MONO_DYN_IMAGE_TOK_NEW
);
2659 if ((!strcmp (klass
->name
, "ValueType") && !strcmp (klass
->name_space
, "System")) ||
2660 (!strcmp (klass
->name
, "Object") && !strcmp (klass
->name_space
, "System")) ||
2661 (!strcmp (klass
->name
, "Enum") && !strcmp (klass
->name_space
, "System"))) {
2662 klass
->instance_size
= MONO_ABI_SIZEOF (MonoObject
);
2663 klass
->size_inited
= 1;
2664 mono_class_setup_vtable_general (klass
, NULL
, 0, NULL
);
2667 mono_class_setup_mono_type (klass
);
2670 * FIXME: handle interfaces.
2672 MonoReflectionTypeHandle ref_tb_type
;
2673 ref_tb_type
= MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
);
2674 MONO_HANDLE_SETVAL (ref_tb_type
, type
, MonoType
*, m_class_get_byval_arg (klass
));
2675 MONO_HANDLE_SETVAL (ref_tb
, state
, gint32
, MonoTypeBuilderFinished
);
2677 reflection_init_generic_class (ref_tb
, error
);
2678 goto_if_nok (error
, leave
);
2680 // Do here so that the search inside of the parent can see the above type that's been set.
2681 MonoReflectionTypeHandle ref_parent
;
2682 ref_parent
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoObject
, ref_tb
, parent
));
2683 MonoType
*parent_type
;
2685 if (!MONO_HANDLE_IS_NULL (ref_parent
)) {
2686 MonoClass
*parent_klass
= mono_handle_class (ref_parent
);
2687 gboolean recursive_init
= TRUE
;
2689 if (is_sre_type_builder (parent_klass
)) {
2690 MonoTypeBuilderState parent_state
= (MonoTypeBuilderState
)MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_parent
), state
);
2692 if (parent_state
!= MonoTypeBuilderNew
) {
2693 // Initialize types reachable from parent recursively
2694 // We'll fix the type hierarchy later
2695 recursive_init
= FALSE
;
2699 if (recursive_init
) {
2700 // If we haven't encountered a cycle, force the creation of ref_parent's type
2701 mono_reflection_type_handle_mono_type (ref_parent
, error
);
2702 goto_if_nok (error
, leave
);
2705 parent_type
= MONO_HANDLE_GETVAL (ref_parent
, type
);
2707 // If we failed to create the parent, fail the child
2712 // Push the child type and parent type to process later
2713 // Note: parent_type may be null.
2714 g_assert (!g_hash_table_lookup (unparented_classes
, m_class_get_byval_arg (klass
)));
2715 g_hash_table_insert (unparented_classes
, m_class_get_byval_arg (klass
), parent_type
);
2717 if (!MONO_HANDLE_IS_NULL (ref_nesting_type
)) {
2718 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_nesting_type
), error
))
2721 MonoType
*nesting_type
= mono_reflection_type_handle_mono_type (ref_nesting_type
, error
);
2722 goto_if_nok (error
, leave
);
2723 klass
->nested_in
= mono_class_from_mono_type_internal (nesting_type
);
2726 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2728 MONO_PROFILER_RAISE (class_loaded
, (klass
));
2731 mono_loader_unlock ();
2732 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2736 * reflection_init_generic_class:
2737 * @tb: a TypeBuilder object
2738 * @error: set on error
2740 * Creates the generic class after all generic parameters have been added.
2741 * On success returns TRUE, on failure returns FALSE and sets @error.
2743 * This assumes that reflection_setup_internal_class has already set up
2747 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2749 HANDLE_FUNCTION_ENTER ();
2753 MonoTypeBuilderState ref_state
= (MonoTypeBuilderState
)MONO_HANDLE_GETVAL (ref_tb
, state
);
2754 g_assert (ref_state
== MonoTypeBuilderFinished
);
2756 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2757 MonoClass
*klass
= mono_class_from_mono_type_internal (type
);
2759 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
2760 int count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
2765 if (mono_class_try_get_generic_container (klass
) != NULL
)
2766 goto leave
; /* already setup */
2768 MonoGenericContainer
*generic_container
;
2769 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2771 generic_container
->owner
.klass
= klass
;
2772 generic_container
->type_argc
= count
;
2773 generic_container
->type_params
= (MonoGenericParamFull
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericParamFull
) * count
);
2775 klass
->class_kind
= MONO_CLASS_GTD
;
2776 mono_class_set_generic_container (klass
, generic_container
);
2779 MonoReflectionGenericParamHandle ref_gparam
;
2780 ref_gparam
= MONO_HANDLE_NEW (MonoReflectionGenericParam
, NULL
);
2781 for (int i
= 0; i
< count
; i
++) {
2782 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
2783 MonoType
*param_type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), error
);
2784 goto_if_nok (error
, leave
);
2785 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) param_type
->data
.generic_param
;
2786 generic_container
->type_params
[i
] = *param
;
2787 /*Make sure we are a diferent type instance */
2788 generic_container
->type_params
[i
].owner
= generic_container
;
2789 generic_container
->type_params
[i
].info
.pklass
= NULL
;
2790 generic_container
->type_params
[i
].info
.flags
= MONO_HANDLE_GETVAL (ref_gparam
, attrs
);
2792 g_assert (generic_container
->type_params
[i
].owner
);
2795 generic_container
->context
.class_inst
= mono_get_shared_generic_inst (generic_container
);
2796 MonoGenericContext
* context
;
2797 context
= &generic_container
->context
;
2798 MonoType
*canonical_inst
;
2799 canonical_inst
= &((MonoClassGtd
*)klass
)->canonical_inst
;
2800 canonical_inst
->type
= MONO_TYPE_GENERICINST
;
2801 canonical_inst
->data
.generic_class
= mono_metadata_lookup_generic_class (klass
, context
->class_inst
, FALSE
);
2804 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2807 static MonoMarshalSpec
*
2808 mono_marshal_spec_from_builder (MonoImage
*image
, MonoAssembly
*assembly
,
2809 MonoReflectionMarshal
*minfo
, MonoError
*error
)
2811 MonoMarshalSpec
*res
;
2815 res
= image_g_new0 (image
, MonoMarshalSpec
, 1);
2816 res
->native
= (MonoMarshalNative
)minfo
->type
;
2818 switch (minfo
->type
) {
2819 case MONO_NATIVE_LPARRAY
:
2820 res
->data
.array_data
.elem_type
= (MonoMarshalNative
)minfo
->eltype
;
2821 if (minfo
->has_size
) {
2822 res
->data
.array_data
.param_num
= minfo
->param_num
;
2823 res
->data
.array_data
.num_elem
= minfo
->count
;
2824 res
->data
.array_data
.elem_mult
= minfo
->param_num
== -1 ? 0 : 1;
2827 res
->data
.array_data
.param_num
= -1;
2828 res
->data
.array_data
.num_elem
= -1;
2829 res
->data
.array_data
.elem_mult
= -1;
2833 case MONO_NATIVE_BYVALTSTR
:
2834 case MONO_NATIVE_BYVALARRAY
:
2835 res
->data
.array_data
.num_elem
= minfo
->count
;
2838 case MONO_NATIVE_CUSTOM
:
2839 if (minfo
->marshaltyperef
) {
2840 MonoType
*marshaltyperef
= mono_reflection_type_get_handle ((MonoReflectionType
*)minfo
->marshaltyperef
, error
);
2841 if (!is_ok (error
)) {
2842 image_g_free (image
, res
);
2845 res
->data
.custom_data
.custom_name
=
2846 type_get_fully_qualified_name (marshaltyperef
);
2848 if (minfo
->mcookie
) {
2849 res
->data
.custom_data
.cookie
= mono_string_to_utf8_checked_internal (minfo
->mcookie
, error
);
2850 if (!is_ok (error
)) {
2851 image_g_free (image
, res
);
2863 #endif /* !DISABLE_REFLECTION_EMIT */
2865 MonoReflectionMarshalAsAttributeHandle
2866 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain
*domain
, MonoClass
*klass
,
2867 MonoMarshalSpec
*spec
, MonoError
*error
)
2871 MonoReflectionMarshalAsAttributeHandle minfo
= MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, mono_object_new_handle (domain
, mono_class_get_marshal_as_attribute_class (), error
));
2872 goto_if_nok (error
, fail
);
2874 utype
= spec
->native
;
2875 MONO_HANDLE_SETVAL (minfo
, utype
, guint32
, utype
);
2878 case MONO_NATIVE_LPARRAY
:
2879 MONO_HANDLE_SETVAL (minfo
, array_subtype
, guint32
, spec
->data
.array_data
.elem_type
);
2880 if (spec
->data
.array_data
.num_elem
!= -1)
2881 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2882 if (spec
->data
.array_data
.param_num
!= -1)
2883 MONO_HANDLE_SETVAL (minfo
, size_param_index
, gint16
, spec
->data
.array_data
.param_num
);
2886 case MONO_NATIVE_BYVALTSTR
:
2887 case MONO_NATIVE_BYVALARRAY
:
2888 if (spec
->data
.array_data
.num_elem
!= -1)
2889 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2892 case MONO_NATIVE_CUSTOM
:
2893 if (spec
->data
.custom_data
.custom_name
) {
2894 MonoType
*mtype
= mono_reflection_type_from_name_checked (spec
->data
.custom_data
.custom_name
, klass
->image
, error
);
2895 goto_if_nok (error
, fail
);
2898 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, mtype
, error
);
2899 goto_if_nok (error
, fail
);
2901 MONO_HANDLE_SET (minfo
, marshal_type_ref
, rt
);
2904 MonoStringHandle custom_name
= mono_string_new_handle (domain
, spec
->data
.custom_data
.custom_name
, error
);
2905 goto_if_nok (error
, fail
);
2906 MONO_HANDLE_SET (minfo
, marshal_type
, custom_name
);
2908 if (spec
->data
.custom_data
.cookie
) {
2909 MonoStringHandle cookie
= mono_string_new_handle (domain
, spec
->data
.custom_data
.cookie
, error
);
2910 goto_if_nok (error
, fail
);
2911 MONO_HANDLE_SET (minfo
, marshal_cookie
, cookie
);
2921 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, NULL
);
2924 #ifndef DISABLE_REFLECTION_EMIT
2926 reflection_methodbuilder_to_mono_method (MonoClass
*klass
,
2927 ReflectionMethodBuilder
*rmb
,
2928 MonoMethodSignature
*sig
,
2932 MonoMethodWrapper
*wrapperm
;
2933 MonoMarshalSpec
**specs
= NULL
;
2934 MonoReflectionMethodAux
*method_aux
;
2941 * Methods created using a MethodBuilder should have their memory allocated
2942 * inside the image mempool, while dynamic methods should have their memory
2945 dynamic
= rmb
->refs
!= NULL
;
2946 image
= dynamic
? NULL
: klass
->image
;
2949 g_assert (!mono_class_is_ginst (klass
));
2951 mono_loader_lock ();
2953 if ((rmb
->attrs
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
2954 (rmb
->iattrs
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
2955 m
= (MonoMethod
*)image_g_new0 (image
, MonoMethodPInvoke
, 1);
2957 m
= (MonoMethod
*)image_g_new0 (image
, MonoDynamicMethod
, 1);
2959 wrapperm
= (MonoMethodWrapper
*)m
;
2961 m
->dynamic
= dynamic
;
2963 m
->flags
= rmb
->attrs
;
2964 m
->iflags
= rmb
->iattrs
;
2965 m
->name
= string_to_utf8_image_raw (image
, rmb
->name
, error
);
2966 goto_if_nok (error
, fail
);
2969 m
->sre_method
= TRUE
;
2970 m
->skip_visibility
= rmb
->skip_visibility
;
2972 m
->token
= MONO_TOKEN_METHOD_DEF
| (*rmb
->table_idx
);
2974 if (m
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) {
2975 if (klass
== mono_defaults
.string_class
&& !strcmp (m
->name
, ".ctor"))
2978 m
->signature
->pinvoke
= 1;
2979 } else if (m
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) {
2980 m
->signature
->pinvoke
= 1;
2982 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2984 method_aux
->dllentry
= rmb
->dllentry
? string_to_utf8_image_raw (image
, rmb
->dllentry
, error
) : image_strdup (image
, m
->name
);
2985 mono_error_assert_ok (error
);
2986 method_aux
->dll
= string_to_utf8_image_raw (image
, rmb
->dll
, error
);
2987 mono_error_assert_ok (error
);
2989 ((MonoMethodPInvoke
*)m
)->piflags
= (rmb
->native_cc
<< 8) | (rmb
->charset
? (rmb
->charset
- 1) * 2 : 0) | rmb
->extra_flags
;
2991 if (image_is_dynamic (klass
->image
))
2992 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
2996 } else if (!(m
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) &&
2997 !(m
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
)) {
2998 MonoMethodHeader
*header
;
3000 gint32 max_stack
, i
;
3001 gint32 num_locals
= 0;
3002 gint32 num_clauses
= 0;
3006 code
= mono_array_addr_internal (rmb
->ilgen
->code
, guint8
, 0);
3007 code_size
= rmb
->ilgen
->code_len
;
3008 max_stack
= rmb
->ilgen
->max_stack
;
3009 num_locals
= rmb
->ilgen
->locals
? mono_array_length_internal (rmb
->ilgen
->locals
) : 0;
3010 if (rmb
->ilgen
->ex_handlers
)
3011 num_clauses
= mono_reflection_method_count_clauses (rmb
->ilgen
);
3014 code
= mono_array_addr_internal (rmb
->code
, guint8
, 0);
3015 code_size
= mono_array_length_internal (rmb
->code
);
3016 /* we probably need to run a verifier on the code... */
3026 header
= (MonoMethodHeader
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_HEADER
+ num_locals
* sizeof (MonoType
*));
3027 header
->code_size
= code_size
;
3028 header
->code
= (const unsigned char *)image_g_malloc (image
, code_size
);
3029 memcpy ((char*)header
->code
, code
, code_size
);
3030 header
->max_stack
= max_stack
;
3031 header
->init_locals
= rmb
->init_locals
;
3032 header
->num_locals
= num_locals
;
3034 for (i
= 0; i
< num_locals
; ++i
) {
3035 MonoReflectionLocalBuilder
*lb
=
3036 mono_array_get_internal (rmb
->ilgen
->locals
, MonoReflectionLocalBuilder
*, i
);
3038 header
->locals
[i
] = image_g_new0 (image
, MonoType
, 1);
3039 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)lb
->type
, error
);
3040 mono_error_assert_ok (error
);
3041 memcpy (header
->locals
[i
], type
, mono_sizeof_type (type
));
3044 header
->num_clauses
= num_clauses
;
3046 header
->clauses
= method_encode_clauses (image
, (MonoDynamicImage
*)klass
->image
,
3047 rmb
->ilgen
, num_clauses
, error
);
3048 mono_error_assert_ok (error
);
3051 wrapperm
->header
= header
;
3052 MonoDynamicMethod
*dm
= (MonoDynamicMethod
*)wrapperm
;
3053 dm
->assembly
= klass
->image
->assembly
;
3056 if (rmb
->generic_params
) {
3057 int count
= mono_array_length_internal (rmb
->generic_params
);
3058 MonoGenericContainer
*container
;
3060 container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
3061 container
->is_method
= TRUE
;
3062 container
->is_anonymous
= FALSE
;
3063 container
->type_argc
= count
;
3064 container
->type_params
= image_g_new0 (image
, MonoGenericParamFull
, count
);
3065 container
->owner
.method
= m
;
3067 m
->is_generic
= TRUE
;
3068 mono_method_set_generic_container (m
, container
);
3070 for (i
= 0; i
< count
; i
++) {
3071 MonoReflectionGenericParam
*gp
=
3072 mono_array_get_internal (rmb
->generic_params
, MonoReflectionGenericParam
*, i
);
3073 MonoType
*gp_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gp
, error
);
3074 mono_error_assert_ok (error
);
3075 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) gp_type
->data
.generic_param
;
3076 container
->type_params
[i
] = *param
;
3077 container
->type_params
[i
].owner
= container
;
3079 gp
->type
.type
->data
.generic_param
= (MonoGenericParam
*)&container
->type_params
[i
];
3081 MonoClass
*gklass
= mono_class_from_mono_type_internal (gp_type
);
3082 gklass
->wastypebuilder
= TRUE
;
3086 * The method signature might have pointers to generic parameters that belong to other methods.
3087 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3088 * generic parameters.
3090 for (i
= 0; i
< m
->signature
->param_count
; ++i
) {
3091 MonoType
*t
= m
->signature
->params
[i
];
3092 if (t
->type
== MONO_TYPE_MVAR
) {
3093 MonoGenericParam
*gparam
= t
->data
.generic_param
;
3094 if (gparam
->num
< count
) {
3095 m
->signature
->params
[i
] = mono_metadata_type_dup (image
, m
->signature
->params
[i
]);
3096 m
->signature
->params
[i
]->data
.generic_param
= mono_generic_container_get_param (container
, gparam
->num
);
3102 if (mono_class_is_gtd (klass
)) {
3103 container
->parent
= mono_class_get_generic_container (klass
);
3104 container
->context
.class_inst
= mono_class_get_generic_container (klass
)->context
.class_inst
;
3106 container
->context
.method_inst
= mono_get_shared_generic_inst (container
);
3110 MonoMethodWrapper
*mw
= (MonoMethodWrapper
*)m
;
3114 m
->wrapper_type
= MONO_WRAPPER_DYNAMIC_METHOD
;
3116 mw
->method_data
= data
= image_g_new (image
, gpointer
, rmb
->nrefs
+ 1);
3117 data
[0] = GUINT_TO_POINTER (rmb
->nrefs
);
3118 for (i
= 0; i
< rmb
->nrefs
; ++i
)
3119 data
[i
+ 1] = rmb
->refs
[i
];
3124 /* Parameter info */
3127 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3128 method_aux
->param_names
= image_g_new0 (image
, char *, mono_method_signature_internal (m
)->param_count
+ 1);
3129 for (i
= 0; i
<= m
->signature
->param_count
; ++i
) {
3130 MonoReflectionParamBuilder
*pb
;
3131 if ((pb
= mono_array_get_internal (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3132 if ((i
> 0) && (pb
->attrs
)) {
3133 /* Make a copy since it might point to a shared type structure */
3134 m
->signature
->params
[i
- 1] = mono_metadata_type_dup (klass
->image
, m
->signature
->params
[i
- 1]);
3135 m
->signature
->params
[i
- 1]->attrs
= pb
->attrs
;
3138 if (pb
->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
) {
3139 MonoDynamicImage
*assembly
;
3141 MonoTypeEnum def_type
;
3145 if (!method_aux
->param_defaults
) {
3146 method_aux
->param_defaults
= image_g_new0 (image
, guint8
*, m
->signature
->param_count
+ 1);
3147 method_aux
->param_default_types
= image_g_new0 (image
, guint32
, m
->signature
->param_count
+ 1);
3149 assembly
= (MonoDynamicImage
*)klass
->image
;
3150 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &def_type
);
3151 /* Copy the data from the blob since it might get realloc-ed */
3152 p
= assembly
->blob
.data
+ idx
;
3153 len
= mono_metadata_decode_blob_size (p
, &p2
);
3155 method_aux
->param_defaults
[i
] = (uint8_t *)image_g_malloc (image
, len
);
3156 method_aux
->param_default_types
[i
] = def_type
;
3157 memcpy ((gpointer
)method_aux
->param_defaults
[i
], p
, len
);
3161 method_aux
->param_names
[i
] = string_to_utf8_image_raw (image
, pb
->name
, error
);
3162 mono_error_assert_ok (error
);
3165 if (!method_aux
->param_cattr
)
3166 method_aux
->param_cattr
= image_g_new0 (image
, MonoCustomAttrInfo
*, m
->signature
->param_count
+ 1);
3167 method_aux
->param_cattr
[i
] = mono_custom_attrs_from_builders (image
, klass
->image
, pb
->cattrs
);
3173 /* Parameter marshalling */
3175 for (i
= 0; i
< mono_array_length_internal (rmb
->pinfo
); ++i
) {
3176 MonoReflectionParamBuilder
*pb
;
3177 if ((pb
= mono_array_get_internal (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3178 if (pb
->marshal_info
) {
3180 specs
= image_g_new0 (image
, MonoMarshalSpec
*, sig
->param_count
+ 1);
3181 specs
[pb
->position
] =
3182 mono_marshal_spec_from_builder (image
, klass
->image
->assembly
, pb
->marshal_info
, error
);
3183 goto_if_nok (error
, fail
);
3187 if (specs
!= NULL
) {
3189 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3190 method_aux
->param_marshall
= specs
;
3193 if (image_is_dynamic (klass
->image
) && method_aux
)
3194 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
3197 mono_loader_unlock ();
3198 if (!m
) // FIXME: This leaks if image is not NULL.
3199 image_g_free (image
, specs
);
3208 ctorbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionCtorBuilder
* mb
, MonoError
*error
)
3210 ReflectionMethodBuilder rmb
;
3211 MonoMethodSignature
*sig
;
3213 mono_loader_lock ();
3215 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb
, mb
, error
)) {
3216 mono_loader_unlock ();
3220 g_assert (klass
->image
!= NULL
);
3221 sig
= ctor_builder_to_signature_raw (klass
->image
, mb
, error
); /* FIXME use handles */
3222 mono_loader_unlock ();
3223 return_val_if_nok (error
, NULL
);
3225 mb
->mhandle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3226 return_val_if_nok (error
, NULL
);
3227 mono_save_custom_attrs (klass
->image
, mb
->mhandle
, mb
->cattrs
);
3229 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
) {
3230 /* ilgen is no longer needed */
3238 methodbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionMethodBuilderHandle ref_mb
, MonoError
*error
)
3240 ReflectionMethodBuilder rmb
;
3241 MonoMethodSignature
*sig
;
3245 mono_loader_lock ();
3247 MonoReflectionMethodBuilder
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME use handles */
3248 if (!mono_reflection_methodbuilder_from_method_builder (&rmb
, mb
, error
)) {
3249 mono_loader_unlock ();
3253 g_assert (klass
->image
!= NULL
);
3254 sig
= method_builder_to_signature (klass
->image
, ref_mb
, error
);
3255 mono_loader_unlock ();
3256 return_val_if_nok (error
, NULL
);
3258 MonoMethod
*method
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3259 return_val_if_nok (error
, NULL
);
3260 MONO_HANDLE_SETVAL (ref_mb
, mhandle
, MonoMethod
*, method
);
3261 mono_save_custom_attrs (klass
->image
, method
, mb
->cattrs
);
3263 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
)
3264 /* ilgen is no longer needed */
3270 methodbuilder_to_mono_method_raw (MonoClass
*klass
, MonoReflectionMethodBuilder
* mb_raw
, MonoError
*error
)
3272 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3274 MONO_HANDLE_DCL (MonoReflectionMethodBuilder
, mb
);
3275 MonoMethod
*result
= methodbuilder_to_mono_method (klass
, mb
, error
);
3276 HANDLE_FUNCTION_RETURN_VAL (result
);
3281 #ifndef DISABLE_REFLECTION_EMIT
3284 * fix_partial_generic_class:
3285 * @klass: a generic instantiation MonoClass
3286 * @error: set on error
3288 * Assumes that the generic container of @klass has its vtable
3289 * initialized, and updates the parent class, interfaces, methods and
3290 * fields of @klass by inflating the types using the generic context.
3292 * On success returns TRUE, on failure returns FALSE and sets @error.
3296 fix_partial_generic_class (MonoClass
*klass
, MonoError
*error
)
3298 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3303 if (klass
->wastypebuilder
)
3306 if (klass
->parent
!= gklass
->parent
) {
3307 MonoType
*parent_type
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (m_class_get_parent (gklass
)), &mono_class_get_generic_class (klass
)->context
, error
);
3308 if (mono_error_ok (error
)) {
3309 MonoClass
*parent
= mono_class_from_mono_type_internal (parent_type
);
3310 mono_metadata_free_type (parent_type
);
3311 if (parent
!= klass
->parent
) {
3312 /*fool mono_class_setup_parent*/
3313 klass
->supertypes
= NULL
;
3314 mono_class_setup_parent (klass
, parent
);
3317 if (gklass
->wastypebuilder
)
3318 klass
->wastypebuilder
= TRUE
;
3323 if (!mono_class_get_generic_class (klass
)->need_sync
)
3326 int mcount
= mono_class_get_method_count (klass
);
3327 int gmcount
= mono_class_get_method_count (gklass
);
3328 if (mcount
!= gmcount
) {
3329 mono_class_set_method_count (klass
, gmcount
);
3330 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * (gmcount
+ 1));
3332 for (i
= 0; i
< gmcount
; i
++) {
3333 klass
->methods
[i
] = mono_class_inflate_generic_method_full_checked (
3334 gklass
->methods
[i
], klass
, mono_class_get_context (klass
), error
);
3335 mono_error_assert_ok (error
);
3339 if (klass
->interface_count
&& klass
->interface_count
!= gklass
->interface_count
) {
3340 klass
->interface_count
= gklass
->interface_count
;
3341 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * gklass
->interface_count
);
3342 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3344 MonoClass
**gklass_interfaces
= m_class_get_interfaces (gklass
);
3345 for (i
= 0; i
< gklass
->interface_count
; ++i
) {
3346 MonoType
*iface_type
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (gklass_interfaces
[i
]), mono_class_get_context (klass
), error
);
3347 return_val_if_nok (error
, FALSE
);
3349 klass
->interfaces
[i
] = mono_class_from_mono_type_internal (iface_type
);
3350 mono_metadata_free_type (iface_type
);
3352 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3355 klass
->interfaces_inited
= 1;
3358 int fcount
= mono_class_get_field_count (klass
);
3359 int gfcount
= mono_class_get_field_count (gklass
);
3360 if (fcount
!= gfcount
) {
3361 mono_class_set_field_count (klass
, gfcount
);
3362 klass
->fields
= image_g_new0 (klass
->image
, MonoClassField
, gfcount
);
3364 for (i
= 0; i
< gfcount
; i
++) {
3365 klass
->fields
[i
] = gklass
->fields
[i
];
3366 klass
->fields
[i
].parent
= klass
;
3367 klass
->fields
[i
].type
= mono_class_inflate_generic_type_checked (gklass
->fields
[i
].type
, mono_class_get_context (klass
), error
);
3368 return_val_if_nok (error
, FALSE
);
3372 /*We can only finish with this klass once it's parent has as well*/
3373 if (gklass
->wastypebuilder
)
3374 klass
->wastypebuilder
= TRUE
;
3379 * ensure_generic_class_runtime_vtable:
3380 * @klass a generic class
3381 * @error set on error
3383 * Ensures that the generic container of @klass has a vtable and
3384 * returns TRUE on success. On error returns FALSE and sets @error.
3387 ensure_generic_class_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3389 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3393 if (!ensure_runtime_vtable (gklass
, error
))
3396 return fix_partial_generic_class (klass
, error
);
3400 * ensure_runtime_vtable:
3402 * @error set on error
3404 * Ensures that @klass has a vtable and returns TRUE on success. On
3405 * error returns FALSE and sets @error.
3408 ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3410 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3415 if (!image_is_dynamic (klass
->image
) || (!tb
&& !mono_class_is_ginst (klass
)) || klass
->wastypebuilder
)
3418 if (!ensure_runtime_vtable (klass
->parent
, error
))
3422 num
= tb
->ctors
? mono_array_length_internal (tb
->ctors
): 0;
3423 num
+= tb
->num_methods
;
3424 mono_class_set_method_count (klass
, num
);
3425 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * num
);
3426 num
= tb
->ctors
? mono_array_length_internal (tb
->ctors
): 0;
3427 for (i
= 0; i
< num
; ++i
) {
3428 MonoMethod
*ctor
= ctorbuilder_to_mono_method (klass
, mono_array_get_internal (tb
->ctors
, MonoReflectionCtorBuilder
*, i
), error
);
3431 klass
->methods
[i
] = ctor
;
3433 num
= tb
->num_methods
;
3435 for (i
= 0; i
< num
; ++i
) {
3436 MonoMethod
*meth
= methodbuilder_to_mono_method_raw (klass
, mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
), error
); /* FIXME use handles */
3439 klass
->methods
[j
++] = meth
;
3442 if (tb
->interfaces
) {
3443 klass
->interface_count
= mono_array_length_internal (tb
->interfaces
);
3444 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * klass
->interface_count
);
3445 for (i
= 0; i
< klass
->interface_count
; ++i
) {
3446 MonoType
*iface
= mono_type_array_get_and_resolve_raw (tb
->interfaces
, i
, error
); /* FIXME use handles */
3447 return_val_if_nok (error
, FALSE
);
3448 klass
->interfaces
[i
] = mono_class_from_mono_type_internal (iface
);
3449 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3452 klass
->interfaces_inited
= 1;
3454 } else if (mono_class_is_ginst (klass
)){
3455 if (!ensure_generic_class_runtime_vtable (klass
, error
)) {
3456 mono_class_set_type_load_failure (klass
, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error
));
3461 if (mono_class_is_interface (klass
) && !mono_class_is_ginst (klass
)) {
3463 int mcount
= mono_class_get_method_count (klass
);
3464 for (i
= 0; i
< mcount
; ++i
) {
3465 MonoMethod
*im
= klass
->methods
[i
];
3466 if (!(im
->flags
& METHOD_ATTRIBUTE_STATIC
))
3467 im
->slot
= slot_num
++;
3470 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3471 mono_class_setup_interface_offsets (klass
);
3472 mono_class_setup_interface_id (klass
);
3476 * The generic vtable is needed even if image->run is not set since some
3477 * runtime code like ves_icall_Type_GetMethodsByName depends on
3478 * method->slot being defined.
3482 * tb->methods could not be freed since it is used for determining
3483 * overrides during dynamic vtable construction.
3490 mono_reflection_method_get_handle (MonoObject
*method
, MonoError
*error
)
3493 MonoClass
*klass
= mono_object_class (method
);
3494 if (is_sr_mono_method (klass
)) {
3495 MonoReflectionMethod
*sr_method
= (MonoReflectionMethod
*)method
;
3496 return sr_method
->method
;
3498 if (is_sre_method_builder (klass
)) {
3499 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)method
;
3502 if (mono_is_sre_method_on_tb_inst (klass
)) {
3503 MonoClass
*handle_class
;
3505 MonoMethod
*result
= (MonoMethod
*)mono_reflection_resolve_object (NULL
, method
, &handle_class
, NULL
, error
);
3506 return_val_if_nok (error
, NULL
);
3511 g_error ("Can't handle methods of type %s:%s", klass
->name_space
, klass
->name
);
3516 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
3518 MonoReflectionTypeBuilder
*tb
;
3520 MonoReflectionMethod
*m
;
3526 g_assert (image_is_dynamic (klass
->image
));
3528 if (!mono_class_has_ref_info (klass
))
3531 tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3532 g_assert (strcmp (mono_object_class (tb
)->name
, "TypeBuilder") == 0);
3536 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3537 MonoReflectionMethodBuilder
*mb
=
3538 mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3539 if (mb
->override_methods
)
3540 onum
+= mono_array_length_internal (mb
->override_methods
);
3545 *overrides
= g_new0 (MonoMethod
*, onum
* 2);
3548 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3549 MonoReflectionMethodBuilder
*mb
=
3550 mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3551 if (mb
->override_methods
) {
3552 for (j
= 0; j
< mono_array_length_internal (mb
->override_methods
); ++j
) {
3553 m
= mono_array_get_internal (mb
->override_methods
, MonoReflectionMethod
*, j
);
3555 (*overrides
) [onum
* 2] = mono_reflection_method_get_handle ((MonoObject
*)m
, error
);
3556 return_if_nok (error
);
3557 (*overrides
) [onum
* 2 + 1] = mb
->mhandle
;
3559 g_assert (mb
->mhandle
);
3567 *num_overrides
= onum
;
3571 modulebuilder_get_next_table_index (MonoReflectionModuleBuilder
*mb
, gint32 table
, gint32 num_fields
, MonoError
*error
)
3575 if (mb
->table_indexes
== NULL
) {
3576 MonoArray
*arr
= mono_array_new_checked (mono_object_domain (&mb
->module
.obj
), mono_defaults
.int_class
, 64, error
);
3577 return_val_if_nok (error
, 0);
3578 for (int i
= 0; i
< 64; i
++) {
3579 mono_array_set_internal (arr
, int, i
, 1);
3581 MONO_OBJECT_SETREF_INTERNAL (mb
, table_indexes
, arr
);
3583 gint32 index
= mono_array_get_internal (mb
->table_indexes
, gint32
, table
);
3584 gint32 next_index
= index
+ num_fields
;
3585 mono_array_set_internal (mb
->table_indexes
, gint32
, table
, next_index
);
3589 /* This initializes the same data as mono_class_setup_fields () */
3591 typebuilder_setup_fields (MonoClass
*klass
, MonoError
*error
)
3593 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3594 MonoReflectionFieldBuilder
*fb
;
3595 MonoClassField
*field
;
3596 MonoFieldDefaultValue
*def_values
;
3597 MonoImage
*image
= klass
->image
;
3599 int i
, instance_size
, packing_size
= 0;
3604 if (klass
->parent
) {
3605 if (!klass
->parent
->size_inited
)
3606 mono_class_init_internal (klass
->parent
);
3607 instance_size
= klass
->parent
->instance_size
;
3609 instance_size
= MONO_ABI_SIZEOF (MonoObject
);
3612 int fcount
= tb
->num_fields
;
3613 mono_class_set_field_count (klass
, fcount
);
3615 gint32 first_idx
= 0;
3616 if (tb
->num_fields
> 0) {
3617 first_idx
= modulebuilder_get_next_table_index (tb
->module
, MONO_TABLE_FIELD
, (gint32
)tb
->num_fields
, error
);
3618 return_if_nok (error
);
3620 mono_class_set_first_field_idx (klass
, first_idx
- 1); /* Why do we subtract 1? because mono_class_create_from_typedef does it, too. */
3622 if (tb
->class_size
) {
3623 packing_size
= tb
->packing_size
;
3624 instance_size
+= tb
->class_size
;
3627 klass
->fields
= image_g_new0 (image
, MonoClassField
, fcount
);
3628 def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, fcount
);
3629 mono_class_set_field_def_values (klass
, def_values
);
3631 This is, guess what, a hack.
3632 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3633 On the static path no field class is resolved, only types are built. This is the right thing to do
3635 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3637 klass
->size_inited
= 1;
3639 for (i
= 0; i
< fcount
; ++i
) {
3640 MonoArray
*rva_data
;
3641 fb
= (MonoReflectionFieldBuilder
*)mono_array_get_internal (tb
->fields
, gpointer
, i
);
3642 field
= &klass
->fields
[i
];
3643 field
->parent
= klass
;
3644 field
->name
= string_to_utf8_image_raw (image
, fb
->name
, error
); /* FIXME use handles */
3645 if (!mono_error_ok (error
))
3648 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3649 return_if_nok (error
);
3650 field
->type
= mono_metadata_type_dup (klass
->image
, type
);
3651 field
->type
->attrs
= fb
->attrs
;
3653 field
->type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3654 return_if_nok (error
);
3657 if (!klass
->enumtype
&& !mono_type_get_underlying_type (field
->type
)) {
3658 mono_class_set_type_load_failure (klass
, "Field '%s' is an enum type with a bad underlying type", field
->name
);
3662 if ((fb
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
) && (rva_data
= fb
->rva_data
)) {
3663 char *base
= mono_array_addr_internal (rva_data
, char, 0);
3664 size_t size
= mono_array_length_internal (rva_data
);
3665 char *data
= (char *)mono_image_alloc (klass
->image
, size
);
3666 memcpy (data
, base
, size
);
3667 def_values
[i
].data
= data
;
3669 if (fb
->offset
!= -1)
3670 field
->offset
= fb
->offset
;
3672 mono_save_custom_attrs (klass
->image
, field
, fb
->cattrs
);
3674 if (fb
->def_value
) {
3675 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3676 field
->type
->attrs
|= FIELD_ATTRIBUTE_HAS_DEFAULT
;
3677 idx
= mono_dynimage_encode_constant (assembly
, fb
->def_value
, &def_values
[i
].def_type
);
3678 /* Copy the data from the blob since it might get realloc-ed */
3679 p
= assembly
->blob
.data
+ idx
;
3680 len
= mono_metadata_decode_blob_size (p
, &p2
);
3682 def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3683 memcpy ((gpointer
)def_values
[i
].data
, p
, len
);
3686 MonoObjectHandle field_builder_handle
= MONO_HANDLE_CAST (MonoObject
, MONO_HANDLE_NEW (MonoReflectionFieldBuilder
, fb
));
3687 mono_dynamic_image_register_token (tb
->module
->dynamic_image
, mono_metadata_make_token (MONO_TABLE_FIELD
, first_idx
+ i
), field_builder_handle
, MONO_DYN_IMAGE_TOK_NEW
);
3690 if (!mono_class_has_failure (klass
))
3691 mono_class_layout_fields (klass
, instance_size
, packing_size
, tb
->class_size
, TRUE
);
3695 typebuilder_setup_properties (MonoClass
*klass
, MonoError
*error
)
3697 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3698 MonoReflectionPropertyBuilder
*pb
;
3699 MonoImage
*image
= klass
->image
;
3700 MonoProperty
*properties
;
3701 MonoClassPropertyInfo
*info
;
3706 info
= (MonoClassPropertyInfo
*)mono_class_get_property_info (klass
);
3708 info
= mono_class_alloc0 (klass
, sizeof (MonoClassPropertyInfo
));
3709 mono_class_set_property_info (klass
, info
);
3712 info
->count
= tb
->properties
? mono_array_length_internal (tb
->properties
) : 0;
3715 properties
= image_g_new0 (image
, MonoProperty
, info
->count
);
3716 info
->properties
= properties
;
3717 for (i
= 0; i
< info
->count
; ++i
) {
3718 pb
= mono_array_get_internal (tb
->properties
, MonoReflectionPropertyBuilder
*, i
);
3719 properties
[i
].parent
= klass
;
3720 properties
[i
].attrs
= pb
->attrs
;
3721 properties
[i
].name
= string_to_utf8_image_raw (image
, pb
->name
, error
); /* FIXME use handles */
3722 if (!mono_error_ok (error
))
3725 properties
[i
].get
= pb
->get_method
->mhandle
;
3727 properties
[i
].set
= pb
->set_method
->mhandle
;
3729 mono_save_custom_attrs (klass
->image
, &properties
[i
], pb
->cattrs
);
3730 if (pb
->def_value
) {
3733 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3734 if (!info
->def_values
)
3735 info
->def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, info
->count
);
3736 properties
[i
].attrs
|= PROPERTY_ATTRIBUTE_HAS_DEFAULT
;
3737 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &info
->def_values
[i
].def_type
);
3738 /* Copy the data from the blob since it might get realloc-ed */
3739 p
= assembly
->blob
.data
+ idx
;
3740 len
= mono_metadata_decode_blob_size (p
, &p2
);
3742 info
->def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3743 memcpy ((gpointer
)info
->def_values
[i
].data
, p
, len
);
3749 typebuilder_setup_events (MonoClass
*klass
, MonoError
*error
)
3751 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3752 MonoReflectionEventBuilder
*eb
;
3753 MonoImage
*image
= klass
->image
;
3755 MonoClassEventInfo
*info
;
3760 info
= mono_class_alloc0 (klass
, sizeof (MonoClassEventInfo
));
3761 mono_class_set_event_info (klass
, info
);
3763 info
->count
= tb
->events
? mono_array_length_internal (tb
->events
) : 0;
3766 events
= image_g_new0 (image
, MonoEvent
, info
->count
);
3767 info
->events
= events
;
3768 for (i
= 0; i
< info
->count
; ++i
) {
3769 eb
= mono_array_get_internal (tb
->events
, MonoReflectionEventBuilder
*, i
);
3770 events
[i
].parent
= klass
;
3771 events
[i
].attrs
= eb
->attrs
;
3772 events
[i
].name
= string_to_utf8_image_raw (image
, eb
->name
, error
); /* FIXME use handles */
3773 if (!mono_error_ok (error
))
3776 events
[i
].add
= eb
->add_method
->mhandle
;
3777 if (eb
->remove_method
)
3778 events
[i
].remove
= eb
->remove_method
->mhandle
;
3779 if (eb
->raise_method
)
3780 events
[i
].raise
= eb
->raise_method
->mhandle
;
3782 #ifndef MONO_SMALL_CONFIG
3783 if (eb
->other_methods
) {
3785 events
[i
].other
= image_g_new0 (image
, MonoMethod
*, mono_array_length_internal (eb
->other_methods
) + 1);
3786 for (j
= 0; j
< mono_array_length_internal (eb
->other_methods
); ++j
) {
3787 MonoReflectionMethodBuilder
*mb
=
3788 mono_array_get_internal (eb
->other_methods
,
3789 MonoReflectionMethodBuilder
*, j
);
3790 events
[i
].other
[j
] = mb
->mhandle
;
3794 mono_save_custom_attrs (klass
->image
, &events
[i
], eb
->cattrs
);
3798 struct remove_instantiations_user_data
3805 remove_instantiations_of_and_ensure_contents (gpointer key
,
3809 struct remove_instantiations_user_data
*data
= (struct remove_instantiations_user_data
*)user_data
;
3810 MonoType
*type
= (MonoType
*)key
;
3811 MonoClass
*klass
= data
->klass
;
3812 gboolean already_failed
= !is_ok (data
->error
);
3813 ERROR_DECL (lerror
);
3814 MonoError
*error
= already_failed
? lerror
: data
->error
;
3816 if ((type
->type
== MONO_TYPE_GENERICINST
) && (type
->data
.generic_class
->container_class
== klass
)) {
3817 MonoClass
*inst_klass
= mono_class_from_mono_type_internal (type
);
3818 //Ensure it's safe to use it.
3819 if (!fix_partial_generic_class (inst_klass
, error
)) {
3820 mono_class_set_type_load_failure (inst_klass
, "Could not initialized generic type instance due to: %s", mono_error_get_message (error
));
3821 // Marked the class with failure, but since some other instantiation already failed,
3822 // just report that one, and swallow the error from this one.
3824 mono_error_cleanup (error
);
3832 * reflection_setup_internal_class:
3833 * @tb: a TypeBuilder object
3834 * @error: set on error
3836 * Creates a MonoClass that represents the TypeBuilder.
3837 * This is a trick that lets us simplify a lot of reflection code
3838 * (and will allow us to support Build and Run assemblies easier).
3840 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3843 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3845 MonoReflectionModuleBuilderHandle module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
3846 GHashTable
*unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
3848 if (unparented_classes
) {
3849 return reflection_setup_internal_class_internal (ref_tb
, error
);
3851 // If we're not being called recursively
3852 unparented_classes
= g_hash_table_new (NULL
, NULL
);
3853 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, unparented_classes
);
3855 gboolean ret_val
= reflection_setup_internal_class_internal (ref_tb
, error
);
3856 mono_error_assert_ok (error
);
3858 // Fix the relationship between the created classes and their parents
3859 reflection_setup_class_hierarchy (unparented_classes
, error
);
3860 mono_error_assert_ok (error
);
3862 g_hash_table_destroy (unparented_classes
);
3863 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, NULL
);
3869 MonoReflectionTypeHandle
3870 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3874 reflection_setup_internal_class (ref_tb
, error
);
3875 mono_error_assert_ok (error
);
3877 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_tb
);
3878 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
3879 MonoClass
*klass
= mono_class_from_mono_type_internal (type
);
3881 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, cattrs
);
3882 mono_save_custom_attrs (klass
->image
, klass
, MONO_HANDLE_RAW (cattrs
)); /* FIXME use handles */
3885 * we need to lock the domain because the lock will be taken inside
3886 * So, we need to keep the locking order correct.
3888 mono_loader_lock ();
3889 mono_domain_lock (domain
);
3890 if (klass
->wastypebuilder
) {
3891 mono_domain_unlock (domain
);
3892 mono_loader_unlock ();
3894 return mono_type_get_object_handle (domain
, m_class_get_byval_arg (klass
), error
);
3897 * Fields to set in klass:
3898 * the various flags: delegate/unicode/contextbound etc.
3900 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
3901 klass
->has_cctor
= 1;
3903 mono_class_setup_parent (klass
, klass
->parent
);
3904 /* fool mono_class_setup_supertypes */
3905 klass
->supertypes
= NULL
;
3906 mono_class_setup_supertypes (klass
);
3907 mono_class_setup_mono_type (klass
);
3909 /* enums are done right away */
3910 if (!klass
->enumtype
)
3911 if (!ensure_runtime_vtable (klass
, error
))
3914 MonoArrayHandle nested_types
;
3915 nested_types
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, subtypes
);
3916 if (!MONO_HANDLE_IS_NULL (nested_types
)) {
3917 GList
*nested
= NULL
;
3918 int num_nested
= mono_array_handle_length (nested_types
);
3919 MonoReflectionTypeHandle nested_tb
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
3920 for (int i
= 0; i
< num_nested
; ++i
) {
3921 MONO_HANDLE_ARRAY_GETREF (nested_tb
, nested_types
, i
);
3923 if (MONO_HANDLE_GETVAL (nested_tb
, type
) == NULL
) {
3924 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, nested_tb
), error
);
3925 mono_error_assert_ok (error
);
3928 MonoType
*subtype
= mono_reflection_type_handle_mono_type (nested_tb
, error
);
3929 goto_if_nok (error
, failure
);
3930 nested
= mono_g_list_prepend_image (klass
->image
, nested
, mono_class_from_mono_type_internal (subtype
));
3932 mono_class_set_nested_classes_property (klass
, nested
);
3935 klass
->nested_classes_inited
= TRUE
;
3937 typebuilder_setup_fields (klass
, error
);
3938 goto_if_nok (error
, failure
);
3939 typebuilder_setup_properties (klass
, error
);
3940 goto_if_nok (error
, failure
);
3942 typebuilder_setup_events (klass
, error
);
3943 goto_if_nok (error
, failure
);
3945 klass
->wastypebuilder
= TRUE
;
3947 MonoArrayHandle generic_params
;
3948 generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
3949 if (!MONO_HANDLE_IS_NULL (generic_params
)) {
3950 int num_params
= mono_array_handle_length (generic_params
);
3951 MonoReflectionTypeHandle ref_gparam
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
3952 for (int i
= 0; i
< num_params
; i
++) {
3953 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
3954 MonoType
*param_type
= mono_reflection_type_handle_mono_type (ref_gparam
, error
);
3955 goto_if_nok (error
, failure
);
3956 MonoClass
*gklass
= mono_class_from_mono_type_internal (param_type
);
3958 gklass
->wastypebuilder
= TRUE
;
3963 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3964 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3965 * we want to return normal System.MonoType objects, so clear these out from the cache.
3967 * Together with this we must ensure the contents of all instances to match the created type.
3969 if (domain
->type_hash
&& mono_class_is_gtd (klass
)) {
3970 struct remove_instantiations_user_data data
;
3973 mono_error_assert_ok (error
);
3974 mono_g_hash_table_foreach_remove (domain
->type_hash
, remove_instantiations_of_and_ensure_contents
, &data
);
3975 goto_if_nok (error
, failure
);
3978 mono_domain_unlock (domain
);
3979 mono_loader_unlock ();
3981 if (klass
->enumtype
&& !mono_class_is_valid_enum (klass
)) {
3982 mono_class_set_type_load_failure (klass
, "Not a valid enumeration");
3983 mono_error_set_type_load_class (error
, klass
, "Not a valid enumeration");
3984 goto failure_unlocked
;
3987 MonoReflectionTypeHandle res
;
3988 res
= mono_type_get_object_handle (domain
, m_class_get_byval_arg (klass
), error
);
3989 goto_if_nok (error
, failure_unlocked
);
3994 mono_class_set_type_load_failure (klass
, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error
));
3995 klass
->wastypebuilder
= TRUE
;
3996 mono_domain_unlock (domain
);
3997 mono_loader_unlock ();
3999 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4005 } DynamicMethodReleaseData
;
4008 * The runtime automatically clean up those after finalization.
4010 static MonoReferenceQueue
*dynamic_method_queue
;
4013 free_dynamic_method (void *dynamic_method
)
4015 DynamicMethodReleaseData
*data
= (DynamicMethodReleaseData
*)dynamic_method
;
4016 MonoDomain
*domain
= data
->domain
;
4017 MonoMethod
*method
= data
->handle
;
4020 mono_domain_lock (domain
);
4021 dis_link
= (guint32
)(size_t)g_hash_table_lookup (domain
->method_to_dyn_method
, method
);
4022 g_hash_table_remove (domain
->method_to_dyn_method
, method
);
4023 mono_domain_unlock (domain
);
4024 g_assert (dis_link
);
4025 mono_gchandle_free_internal (dis_link
);
4027 mono_runtime_free_method (domain
, method
);
4032 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb
, MonoError
*error
)
4034 MonoReferenceQueue
*queue
;
4036 DynamicMethodReleaseData
*release_data
;
4037 ReflectionMethodBuilder rmb
;
4038 MonoMethodSignature
*sig
;
4046 if (mono_runtime_is_shutting_down ()) {
4047 mono_error_set_generic_error (error
, "System", "InvalidOperationException", "");
4051 if (!(queue
= dynamic_method_queue
)) {
4052 mono_loader_lock ();
4053 if (!(queue
= dynamic_method_queue
))
4054 queue
= dynamic_method_queue
= mono_gc_reference_queue_new_internal (free_dynamic_method
);
4055 mono_loader_unlock ();
4058 sig
= dynamic_method_to_signature (ref_mb
, error
);
4059 return_val_if_nok (error
, FALSE
);
4061 MonoReflectionDynamicMethod
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME convert reflection_create_dynamic_method to use handles */
4062 reflection_methodbuilder_from_dynamic_method (&rmb
, mb
);
4065 * Resolve references.
4068 * Every second entry in the refs array is reserved for storing handle_class,
4069 * which is needed by the ldtoken implementation in the JIT.
4071 rmb
.nrefs
= mb
->nrefs
;
4072 rmb
.refs
= g_new0 (gpointer
, mb
->nrefs
+ 1);
4073 for (i
= 0; i
< mb
->nrefs
; i
+= 2) {
4074 MonoClass
*handle_class
;
4076 MonoObject
*obj
= mono_array_get_internal (mb
->refs
, MonoObject
*, i
);
4078 if (strcmp (obj
->vtable
->klass
->name
, "DynamicMethod") == 0) {
4079 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4081 * The referenced DynamicMethod should already be created by the managed
4082 * code, except in the case of circular references. In that case, we store
4083 * method in the refs array, and fix it up later when the referenced
4084 * DynamicMethod is created.
4086 if (method
->mhandle
) {
4087 ref
= method
->mhandle
;
4089 /* FIXME: GC object stored in unmanaged memory */
4092 /* FIXME: GC object stored in unmanaged memory */
4093 method
->referenced_by
= g_slist_append (method
->referenced_by
, mb
);
4095 handle_class
= mono_defaults
.methodhandle_class
;
4097 MonoException
*ex
= NULL
;
4098 ref
= mono_reflection_resolve_object (mb
->module
->image
, obj
, &handle_class
, NULL
, error
);
4099 if (!is_ok (error
)) {
4104 ex
= mono_get_exception_type_load (NULL
, NULL
);
4105 else if (mono_security_core_clr_enabled ())
4106 ex
= mono_security_core_clr_ensure_dynamic_method_resolved_object (ref
, handle_class
);
4110 mono_error_set_exception_instance (error
, ex
);
4115 rmb
.refs
[i
] = ref
; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4116 rmb
.refs
[i
+ 1] = handle_class
;
4119 MonoAssembly
*ass
= NULL
;
4121 MonoType
*owner_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)mb
->owner
, error
);
4122 if (!is_ok (error
)) {
4126 klass
= mono_class_from_mono_type_internal (owner_type
);
4127 ass
= klass
->image
->assembly
;
4129 klass
= mono_defaults
.object_class
;
4130 ass
= (mb
->module
&& mb
->module
->image
) ? mb
->module
->image
->assembly
: NULL
;
4133 mb
->mhandle
= handle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
4134 ((MonoDynamicMethod
*)handle
)->assembly
= ass
;
4136 return_val_if_nok (error
, FALSE
);
4138 release_data
= g_new (DynamicMethodReleaseData
, 1);
4139 release_data
->handle
= handle
;
4140 release_data
->domain
= mono_object_get_domain_internal ((MonoObject
*)mb
);
4141 if (!mono_gc_reference_queue_add_internal (queue
, (MonoObject
*)mb
, release_data
))
4142 g_free (release_data
);
4144 /* Fix up refs entries pointing at us */
4145 for (l
= mb
->referenced_by
; l
; l
= l
->next
) {
4146 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)l
->data
;
4147 MonoMethodWrapper
*wrapper
= (MonoMethodWrapper
*)method
->mhandle
;
4150 g_assert (method
->mhandle
);
4152 data
= (gpointer
*)wrapper
->method_data
;
4153 for (i
= 0; i
< GPOINTER_TO_UINT (data
[0]); i
+= 2) {
4154 if ((data
[i
+ 1] == mb
) && (data
[i
+ 1 + 1] == mono_defaults
.methodhandle_class
))
4155 data
[i
+ 1] = mb
->mhandle
;
4158 g_slist_free (mb
->referenced_by
);
4160 /* ilgen is no longer needed */
4163 domain
= mono_domain_get ();
4164 mono_domain_lock (domain
);
4165 if (!domain
->method_to_dyn_method
)
4166 domain
->method_to_dyn_method
= g_hash_table_new (NULL
, NULL
);
4167 g_hash_table_insert (domain
->method_to_dyn_method
, handle
, (gpointer
)(size_t)mono_gchandle_new_weakref_internal ((MonoObject
*)mb
, TRUE
));
4168 mono_domain_unlock (domain
);
4174 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4176 (void) reflection_create_dynamic_method (mb
, error
);
4179 #endif /* DISABLE_REFLECTION_EMIT */
4181 MonoMethodSignature
*
4182 mono_reflection_lookup_signature (MonoImage
*image
, MonoMethod
*method
, guint32 token
, MonoError
*error
)
4184 MonoMethodSignature
*sig
;
4185 g_assert (image_is_dynamic (image
));
4189 sig
= (MonoMethodSignature
*)g_hash_table_lookup (((MonoDynamicImage
*)image
)->vararg_aux_hash
, GUINT_TO_POINTER (token
));
4193 return mono_method_signature_checked (method
, error
);
4196 #ifndef DISABLE_REFLECTION_EMIT
4199 * ensure_complete_type:
4201 * Ensure that KLASS is completed if it is a dynamic type, or references
4205 ensure_complete_type (MonoClass
*klass
, MonoError
*error
)
4207 HANDLE_FUNCTION_ENTER ();
4211 if (image_is_dynamic (klass
->image
) && !klass
->wastypebuilder
&& mono_class_has_ref_info (klass
)) {
4212 MonoReflectionTypeBuilderHandle tb
= mono_class_get_ref_info (klass
);
4214 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4215 goto_if_nok (error
, exit
);
4217 // Asserting here could break a lot of code
4218 //g_assert (klass->wastypebuilder);
4221 if (mono_class_is_ginst (klass
)) {
4222 MonoGenericInst
*inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
4225 for (i
= 0; i
< inst
->type_argc
; ++i
) {
4226 ensure_complete_type (mono_class_from_mono_type_internal (inst
->type_argv
[i
]), error
);
4227 goto_if_nok (error
, exit
);
4232 HANDLE_FUNCTION_RETURN ();
4236 mono_reflection_resolve_object (MonoImage
*image
, MonoObject
*obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4238 HANDLE_FUNCTION_ENTER ();
4240 MonoClass
*oklass
= obj
->vtable
->klass
;
4241 gpointer result
= NULL
;
4245 if (strcmp (oklass
->name
, "String") == 0) {
4246 result
= MONO_HANDLE_RAW (mono_string_intern_checked (MONO_HANDLE_NEW (MonoString
, (MonoString
*)obj
), error
));
4247 goto_if_nok (error
, return_null
);
4248 *handle_class
= mono_defaults
.string_class
;
4250 } else if (strcmp (oklass
->name
, "RuntimeType") == 0) {
4251 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
4252 goto_if_nok (error
, return_null
);
4253 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
4254 if (!mono_class_init_internal (mc
)) {
4255 mono_error_set_for_class_failure (error
, mc
);
4260 MonoType
*inflated
= mono_class_inflate_generic_type_checked (type
, context
, error
);
4261 goto_if_nok (error
, return_null
);
4263 result
= mono_class_from_mono_type_internal (inflated
);
4264 mono_metadata_free_type (inflated
);
4266 result
= mono_class_from_mono_type_internal (type
);
4268 *handle_class
= mono_defaults
.typehandle_class
;
4270 } else if (strcmp (oklass
->name
, "RuntimeMethodInfo") == 0 ||
4271 strcmp (oklass
->name
, "RuntimeConstructorInfo") == 0) {
4272 result
= ((MonoReflectionMethod
*)obj
)->method
;
4274 result
= mono_class_inflate_generic_method_checked ((MonoMethod
*)result
, context
, error
);
4275 mono_error_assert_ok (error
);
4277 *handle_class
= mono_defaults
.methodhandle_class
;
4279 } else if (strcmp (oklass
->name
, "RuntimeFieldInfo") == 0) {
4280 MonoClassField
*field
= ((MonoReflectionField
*)obj
)->field
;
4282 ensure_complete_type (field
->parent
, error
);
4283 goto_if_nok (error
, return_null
);
4286 MonoType
*inflated
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (field
->parent
), context
, error
);
4287 goto_if_nok (error
, return_null
);
4290 klass
= mono_class_from_mono_type_internal (inflated
);
4291 MonoClassField
*inflated_field
;
4292 gpointer iter
= NULL
;
4293 mono_metadata_free_type (inflated
);
4294 while ((inflated_field
= mono_class_get_fields_internal (klass
, &iter
))) {
4295 if (!strcmp (field
->name
, inflated_field
->name
))
4298 g_assert (inflated_field
&& !strcmp (field
->name
, inflated_field
->name
));
4299 result
= inflated_field
;
4303 *handle_class
= mono_defaults
.fieldhandle_class
;
4305 } else if (strcmp (oklass
->name
, "TypeBuilder") == 0) {
4306 MonoReflectionTypeBuilderHandle tb
= MONO_HANDLE_NEW (MonoReflectionTypeBuilder
, (MonoReflectionTypeBuilder
*)obj
);
4307 MonoType
*type
= mono_reflection_type_get_handle (&MONO_HANDLE_RAW (tb
)->type
, error
);
4308 goto_if_nok (error
, return_null
);
4311 klass
= type
->data
.klass
;
4312 if (klass
->wastypebuilder
) {
4313 /* Already created */
4317 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4318 goto_if_nok (error
, return_null
);
4319 result
= type
->data
.klass
;
4322 *handle_class
= mono_defaults
.typehandle_class
;
4323 } else if (strcmp (oklass
->name
, "SignatureHelper") == 0) {
4324 MonoReflectionSigHelper
*helper
= (MonoReflectionSigHelper
*)obj
;
4325 MonoMethodSignature
*sig
;
4328 if (helper
->arguments
)
4329 nargs
= mono_array_length_internal (helper
->arguments
);
4333 sig
= mono_metadata_signature_alloc (image
, nargs
);
4334 sig
->explicit_this
= helper
->call_conv
& 64 ? 1 : 0;
4335 sig
->hasthis
= helper
->call_conv
& 32 ? 1 : 0;
4337 if (helper
->unmanaged_call_conv
) { /* unmanaged */
4338 sig
->call_convention
= helper
->unmanaged_call_conv
- 1;
4339 sig
->pinvoke
= TRUE
;
4340 } else if (helper
->call_conv
& 0x02) {
4341 sig
->call_convention
= MONO_CALL_VARARG
;
4343 sig
->call_convention
= MONO_CALL_DEFAULT
;
4346 sig
->param_count
= nargs
;
4347 /* TODO: Copy type ? */
4348 sig
->ret
= helper
->return_type
->type
;
4349 for (i
= 0; i
< nargs
; ++i
) {
4350 sig
->params
[i
] = mono_type_array_get_and_resolve_raw (helper
->arguments
, i
, error
); /* FIXME use handles */
4351 if (!is_ok (error
)) {
4352 image_g_free (image
, sig
);
4358 *handle_class
= NULL
;
4359 } else if (strcmp (oklass
->name
, "DynamicMethod") == 0) {
4360 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4361 /* Already created by the managed code */
4362 g_assert (method
->mhandle
);
4363 result
= method
->mhandle
;
4364 *handle_class
= mono_defaults
.methodhandle_class
;
4365 } else if (strcmp (oklass
->name
, "MonoArrayMethod") == 0) {
4366 MonoReflectionArrayMethod
*m
= (MonoReflectionArrayMethod
*)obj
;
4373 mtype
= mono_reflection_type_get_handle (m
->parent
, error
);
4374 goto_if_nok (error
, return_null
);
4375 klass
= mono_class_from_mono_type_internal (mtype
);
4377 /* Find the method */
4379 name
= mono_string_to_utf8_checked_internal (m
->name
, error
);
4380 goto_if_nok (error
, return_null
);
4382 while ((method
= mono_class_get_methods (klass
, &iter
))) {
4383 if (!strcmp (method
->name
, name
))
4390 // FIXME: Check parameters/return value etc. match
4393 *handle_class
= mono_defaults
.methodhandle_class
;
4394 } else if (is_sre_method_builder (oklass
) ||
4395 mono_is_sre_ctor_builder (oklass
) ||
4396 is_sre_field_builder (oklass
) ||
4397 is_sre_gparam_builder (oklass
) ||
4398 is_sre_generic_instance (oklass
) ||
4399 is_sre_array (oklass
) ||
4400 is_sre_byref (oklass
) ||
4401 is_sre_pointer (oklass
) ||
4402 !strcmp (oklass
->name
, "FieldOnTypeBuilderInst") ||
4403 !strcmp (oklass
->name
, "MethodOnTypeBuilderInst") ||
4404 !strcmp (oklass
->name
, "ConstructorOnTypeBuilderInst")) {
4405 static MonoMethod
*resolve_method
;
4406 if (!resolve_method
) {
4407 MonoMethod
*m
= mono_class_get_method_from_name_checked (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0, error
);
4408 mono_error_assert_ok (error
);
4410 mono_memory_barrier ();
4415 obj
= mono_runtime_invoke_checked (resolve_method
, NULL
, args
, error
);
4416 goto_if_nok (error
, return_null
);
4418 result
= mono_reflection_resolve_object (image
, obj
, handle_class
, context
, error
);
4421 g_print ("%s\n", obj
->vtable
->klass
->name
);
4422 g_assert_not_reached ();
4430 HANDLE_FUNCTION_RETURN_VAL (result
);
4434 mono_reflection_resolve_object_handle (MonoImage
*image
, MonoObjectHandle obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4436 return mono_reflection_resolve_object (image
, MONO_HANDLE_RAW (obj
), handle_class
, context
, error
);
4439 #else /* DISABLE_REFLECTION_EMIT */
4442 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4444 g_assert_not_reached ();
4449 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4451 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4455 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4457 g_assert_not_reached ();
4462 mono_image_insert_string (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4464 g_assert_not_reached ();
4469 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
4471 g_assert_not_reached ();
4476 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
4477 gboolean create_open_instance
, gboolean register_token
, MonoError
*error
)
4479 g_assert_not_reached ();
4484 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
4491 MonoReflectionTypeHandle
4492 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
)
4494 g_assert_not_reached ();
4495 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4499 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4505 mono_reflection_type_get_handle (MonoReflectionType
* ref
, MonoError
*error
)
4514 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
4517 if (MONO_HANDLE_IS_NULL (ref
))
4519 return MONO_HANDLE_GETVAL (ref
, type
);
4523 #endif /* DISABLE_REFLECTION_EMIT */
4526 mono_sre_generic_param_table_entry_free (GenericParamTableEntry
*entry
)
4528 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry
->gparam
);
4533 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, MonoBoolean create_open_instance
, MonoError
*error
)
4536 if (MONO_HANDLE_IS_NULL (obj
)) {
4537 mono_error_set_argument_null (error
, "obj", "");
4540 return mono_image_create_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), obj
, create_open_instance
, TRUE
, error
);
4544 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb
,
4545 MonoReflectionMethodHandle method
,
4546 MonoArrayHandle opt_param_types
,
4550 if (MONO_HANDLE_IS_NULL (method
)) {
4551 mono_error_set_argument_null (error
, "method", "");
4555 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), MONO_HANDLE_CAST (MonoObject
, method
), opt_param_types
, error
);
4559 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
4562 mono_image_create_pefile (mb
, file
, error
);
4563 mono_error_set_pending_exception (error
);
4567 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
4570 mono_image_build_metadata (mb
, error
);
4571 mono_error_set_pending_exception (error
);
4575 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, guint32 token
, MonoError
*error
)
4578 /* This function may be called by ModuleBuilder.FixupTokens to update
4579 * an existing token, so replace is okay here. */
4580 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), token
, obj
, MONO_DYN_IMAGE_TOK_REPLACE
);
4584 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb
, guint32 token
, MonoError
*error
)
4586 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
4587 return mono_dynamic_image_get_registered_token (dynamic_image
, token
, error
);
4590 #ifndef DISABLE_REFLECTION_EMIT
4592 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4595 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, error
);
4596 mono_error_set_pending_exception (error
);
4602 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4604 mono_reflection_dynimage_basic_init (assemblyb
);
4608 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb
, MonoError
*error
)
4610 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, assemblyb
, cattrs
);
4612 MonoReflectionAssemblyHandle assembly_handle
= MONO_HANDLE_CAST (MonoReflectionAssembly
, assemblyb
);
4613 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_handle
, assembly
);
4614 g_assert (assembly
);
4616 mono_save_custom_attrs (assembly
->image
, assembly
, MONO_HANDLE_RAW (cattrs
));
4620 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype
,
4621 MonoReflectionTypeHandle t
,
4625 MONO_HANDLE_SETVAL (enumtype
, type
, MonoType
*, MONO_HANDLE_GETVAL (t
, type
));
4629 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4632 mono_image_module_basic_init (moduleb
, error
);
4636 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4638 return mono_image_insert_string (module
, str
, error
);
4642 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb
, MonoReflectionTypeHandle ref_type
, MonoError
*error
)
4645 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
4646 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4649 image
->wrappers_type
= mono_class_from_mono_type_internal (type
);