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
50 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute
, "System.Runtime.InteropServices", "MarshalAsAttribute");
51 static GENERATE_GET_CLASS_WITH_CACHE (module_builder
, "System.Reflection.Emit", "ModuleBuilder");
53 static char* string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s
, MonoError
*error
);
55 #ifndef DISABLE_REFLECTION_EMIT
56 static guint32
mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
);
57 static gboolean
ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
);
58 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
);
59 static gboolean
reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
60 static gboolean
reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
61 static gboolean
reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
);
64 static gpointer
register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
);
67 static char* type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
);
68 static MonoReflectionTypeHandle
mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
);
69 static gboolean
is_sre_array (MonoClass
*klass
);
70 static gboolean
is_sre_byref (MonoClass
*klass
);
71 static gboolean
is_sre_pointer (MonoClass
*klass
);
72 static gboolean
is_sre_generic_instance (MonoClass
*klass
);
73 static gboolean
is_sre_type_builder (MonoClass
*klass
);
74 static gboolean
is_sre_method_builder (MonoClass
*klass
);
75 static gboolean
is_sre_field_builder (MonoClass
*klass
);
76 static gboolean
is_sre_gparam_builder (MonoClass
*klass
);
77 static gboolean
is_sre_enum_builder (MonoClass
*klass
);
78 static gboolean
is_sr_mono_method (MonoClass
*klass
);
79 static gboolean
is_sr_mono_field (MonoClass
*klass
);
81 static guint32
mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
);
82 static guint32
mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
);
83 static guint32
mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
);
86 #ifndef DISABLE_REFLECTION_EMIT
87 static MonoType
* mono_type_array_get_and_resolve_raw (MonoArray
* array
, int idx
, MonoError
* error
);
90 static gboolean
mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module
, MonoError
*error
);
93 mono_reflection_emit_init (void)
95 mono_dynamic_images_init ();
99 string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s_raw
, MonoError
*error
)
101 /* FIXME all callers to string_to_utf8_image_raw should use handles */
102 HANDLE_FUNCTION_ENTER ();
105 MONO_HANDLE_DCL (MonoString
, s
);
106 result
= mono_string_to_utf8_image (image
, s
, error
);
107 HANDLE_FUNCTION_RETURN_VAL (result
);
111 type_get_fully_qualified_name (MonoType
*type
)
113 MONO_REQ_GC_NEUTRAL_MODE
;
115 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
119 type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
)
121 MONO_REQ_GC_UNSAFE_MODE
;
126 klass
= mono_class_from_mono_type_internal (type
);
128 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
129 ta
= klass
->image
->assembly
;
130 if (assembly_is_dynamic (ta
) || (ta
== ass
)) {
131 if (mono_class_is_ginst (klass
) || mono_class_is_gtd (klass
))
132 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
133 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_FULL_NAME
);
135 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
138 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
141 #ifndef DISABLE_REFLECTION_EMIT
145 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
149 image_g_malloc (MonoImage
*image
, guint size
)
151 MONO_REQ_GC_NEUTRAL_MODE
;
154 return mono_image_alloc (image
, size
);
156 return g_malloc (size
);
158 #endif /* !DISABLE_REFLECTION_EMIT */
163 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
167 (mono_image_g_malloc0
) (MonoImage
*image
, guint size
)
169 MONO_REQ_GC_NEUTRAL_MODE
;
172 return mono_image_alloc0 (image
, size
);
174 return g_malloc0 (size
);
179 * @image: a MonoImage
182 * If @image is NULL, free @ptr, otherwise do nothing.
185 image_g_free (MonoImage
*image
, gpointer ptr
)
191 #ifndef DISABLE_REFLECTION_EMIT
193 image_strdup (MonoImage
*image
, const char *s
)
195 MONO_REQ_GC_NEUTRAL_MODE
;
198 return mono_image_strdup (image
, s
);
204 #define image_g_new(image,struct_type, n_structs) \
205 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
207 #define image_g_new0(image,struct_type, n_structs) \
208 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
212 alloc_table (MonoDynamicTable
*table
, guint nrows
)
214 mono_dynimage_alloc_table (table
, nrows
);
218 string_heap_insert (MonoDynamicStream
*sh
, const char *str
)
220 return mono_dynstream_insert_string (sh
, str
);
224 mono_image_add_stream_data (MonoDynamicStream
*stream
, const char *data
, guint32 len
)
226 return mono_dynstream_add_data (stream
, data
, len
);
230 * Despite the name, we handle also TypeSpec (with the above helper).
233 mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
)
235 return mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, TRUE
);
239 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
240 * dest may be misaligned.
243 swap_with_size (gpointer void_dest
, gconstpointer void_val
, int len
, int nelem
)
245 char *dest
= (char*)void_dest
;
246 const char* val
= (const char*)void_val
;
247 MONO_REQ_GC_NEUTRAL_MODE
;
248 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
251 for (elem
= 0; elem
< nelem
; ++elem
) {
277 g_assert_not_reached ();
283 memcpy (dest
, val
, len
* nelem
);
288 mono_reflection_method_count_clauses (MonoReflectionILGen
*ilgen
)
290 MONO_REQ_GC_UNSAFE_MODE
;
292 guint32 num_clauses
= 0;
295 MonoILExceptionInfo
*ex_info
;
296 for (i
= 0; i
< mono_array_length_internal (ilgen
->ex_handlers
); ++i
) {
297 ex_info
= (MonoILExceptionInfo
*)mono_array_addr_internal (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
298 if (ex_info
->handlers
)
299 num_clauses
+= mono_array_length_internal (ex_info
->handlers
);
307 #ifndef DISABLE_REFLECTION_EMIT
308 static MonoExceptionClause
*
309 method_encode_clauses (MonoImage
*image
, MonoDynamicImage
*assembly
, MonoReflectionILGen
*ilgen
, guint32 num_clauses
, MonoError
*error
)
311 MONO_REQ_GC_UNSAFE_MODE
;
315 MonoExceptionClause
*clauses
;
316 MonoExceptionClause
*clause
;
317 MonoILExceptionInfo
*ex_info
;
318 MonoILExceptionBlock
*ex_block
;
319 guint32 finally_start
;
320 int i
, j
, clause_index
;;
322 clauses
= image_g_new0 (image
, MonoExceptionClause
, num_clauses
);
325 for (i
= mono_array_length_internal (ilgen
->ex_handlers
) - 1; i
>= 0; --i
) {
326 ex_info
= (MonoILExceptionInfo
*)mono_array_addr_internal (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
327 finally_start
= ex_info
->start
+ ex_info
->len
;
328 if (!ex_info
->handlers
)
330 for (j
= 0; j
< mono_array_length_internal (ex_info
->handlers
); ++j
) {
331 ex_block
= (MonoILExceptionBlock
*)mono_array_addr_internal (ex_info
->handlers
, MonoILExceptionBlock
, j
);
332 clause
= &(clauses
[clause_index
]);
334 clause
->flags
= ex_block
->type
;
335 clause
->try_offset
= ex_info
->start
;
337 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FINALLY
)
338 clause
->try_len
= finally_start
- ex_info
->start
;
340 clause
->try_len
= ex_info
->len
;
341 clause
->handler_offset
= ex_block
->start
;
342 clause
->handler_len
= ex_block
->len
;
343 if (ex_block
->extype
) {
344 MonoType
*extype
= mono_reflection_type_get_handle ((MonoReflectionType
*)ex_block
->extype
, error
);
346 if (!is_ok (error
)) {
347 image_g_free (image
, clauses
);
350 clause
->data
.catch_class
= mono_class_from_mono_type_internal (extype
);
352 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FILTER
)
353 clause
->data
.filter_offset
= ex_block
->filter_offset
;
355 clause
->data
.filter_offset
= 0;
357 finally_start
= ex_block
->start
+ ex_block
->len
;
365 #endif /* !DISABLE_REFLECTION_EMIT */
367 #ifndef DISABLE_REFLECTION_EMIT
369 * LOCKING: Acquires the loader lock.
372 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
374 MONO_REQ_GC_UNSAFE_MODE
;
376 MonoCustomAttrInfo
*ainfo
, *tmp
;
378 if (!cattrs
|| !mono_array_length_internal (cattrs
))
381 ainfo
= mono_custom_attrs_from_builders (image
, image
, cattrs
);
384 tmp
= (MonoCustomAttrInfo
*)mono_image_property_lookup (image
, obj
, MONO_PROP_DYNAMIC_CATTR
);
386 mono_custom_attrs_free (tmp
);
387 mono_image_property_insert (image
, obj
, MONO_PROP_DYNAMIC_CATTR
, ainfo
);
388 mono_loader_unlock ();
392 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
394 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
400 mono_reflection_resolution_scope_from_image (MonoDynamicImage
*assembly
, MonoImage
*image
)
402 MONO_REQ_GC_UNSAFE_MODE
;
404 MonoDynamicTable
*table
;
407 guint32 cols
[MONO_ASSEMBLY_SIZE
];
411 if ((token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, image
))))
414 if (assembly_is_dynamic (image
->assembly
) && (image
->assembly
== assembly
->image
.assembly
)) {
415 table
= &assembly
->tables
[MONO_TABLE_MODULEREF
];
416 token
= table
->next_idx
++;
418 alloc_table (table
, table
->rows
);
419 values
= table
->values
+ token
* MONO_MODULEREF_SIZE
;
420 values
[MONO_MODULEREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->module_name
);
422 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
423 token
|= MONO_RESOLUTION_SCOPE_MODULEREF
;
424 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
429 if (assembly_is_dynamic (image
->assembly
))
431 memset (cols
, 0, sizeof (cols
));
433 /* image->assembly->image is the manifest module */
434 image
= image
->assembly
->image
;
435 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_ASSEMBLY
], 0, cols
, MONO_ASSEMBLY_SIZE
);
438 table
= &assembly
->tables
[MONO_TABLE_ASSEMBLYREF
];
439 token
= table
->next_idx
++;
441 alloc_table (table
, table
->rows
);
442 values
= table
->values
+ token
* MONO_ASSEMBLYREF_SIZE
;
443 values
[MONO_ASSEMBLYREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->assembly_name
);
444 values
[MONO_ASSEMBLYREF_MAJOR_VERSION
] = cols
[MONO_ASSEMBLY_MAJOR_VERSION
];
445 values
[MONO_ASSEMBLYREF_MINOR_VERSION
] = cols
[MONO_ASSEMBLY_MINOR_VERSION
];
446 values
[MONO_ASSEMBLYREF_BUILD_NUMBER
] = cols
[MONO_ASSEMBLY_BUILD_NUMBER
];
447 values
[MONO_ASSEMBLYREF_REV_NUMBER
] = cols
[MONO_ASSEMBLY_REV_NUMBER
];
448 values
[MONO_ASSEMBLYREF_FLAGS
] = 0;
449 values
[MONO_ASSEMBLYREF_CULTURE
] = 0;
450 values
[MONO_ASSEMBLYREF_HASH_VALUE
] = 0;
452 if (strcmp ("", image
->assembly
->aname
.culture
)) {
453 values
[MONO_ASSEMBLYREF_CULTURE
] = string_heap_insert (&assembly
->sheap
,
454 image
->assembly
->aname
.culture
);
457 if ((pubkey
= mono_image_get_public_key (image
, &publen
))) {
460 mono_digest_get_public_token (pubtoken
+ 1, (guchar
*)pubkey
, publen
);
461 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = mono_image_add_stream_data (&assembly
->blob
, (char*)pubtoken
, 9);
463 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = 0;
465 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
466 token
|= MONO_RESOLUTION_SCOPE_ASSEMBLYREF
;
467 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
471 #ifndef DISABLE_REFLECTION_EMIT
473 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
)
475 MONO_REQ_GC_UNSAFE_MODE
;
478 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
480 rmb
->ilgen
= mb
->ilgen
;
481 rmb
->rtype
= (MonoReflectionType
*)mb
->rtype
;
482 return_val_if_nok (error
, FALSE
);
483 rmb
->parameters
= mb
->parameters
;
484 rmb
->generic_params
= mb
->generic_params
;
485 rmb
->generic_container
= mb
->generic_container
;
486 rmb
->opt_types
= NULL
;
487 rmb
->pinfo
= mb
->pinfo
;
488 rmb
->attrs
= mb
->attrs
;
489 rmb
->iattrs
= mb
->iattrs
;
490 rmb
->call_conv
= mb
->call_conv
;
491 rmb
->code
= mb
->code
;
492 rmb
->type
= mb
->type
;
493 rmb
->name
= mb
->name
;
494 rmb
->table_idx
= &mb
->table_idx
;
495 rmb
->init_locals
= mb
->init_locals
;
496 rmb
->skip_visibility
= FALSE
;
497 rmb
->return_modreq
= mb
->return_modreq
;
498 rmb
->return_modopt
= mb
->return_modopt
;
499 rmb
->param_modreq
= mb
->param_modreq
;
500 rmb
->param_modopt
= mb
->param_modopt
;
501 rmb
->permissions
= mb
->permissions
;
502 rmb
->mhandle
= mb
->mhandle
;
507 rmb
->charset
= mb
->charset
;
508 rmb
->extra_flags
= mb
->extra_flags
;
509 rmb
->native_cc
= mb
->native_cc
;
510 rmb
->dllentry
= mb
->dllentry
;
518 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
520 MONO_REQ_GC_UNSAFE_MODE
;
522 const char *name
= mb
->attrs
& METHOD_ATTRIBUTE_STATIC
? ".cctor": ".ctor";
526 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
528 rmb
->ilgen
= mb
->ilgen
;
529 rmb
->rtype
= mono_type_get_object_checked (mono_domain_get (), mono_get_void_type (), error
);
530 return_val_if_nok (error
, FALSE
);
531 rmb
->parameters
= mb
->parameters
;
532 rmb
->generic_params
= NULL
;
533 rmb
->generic_container
= NULL
;
534 rmb
->opt_types
= NULL
;
535 rmb
->pinfo
= mb
->pinfo
;
536 rmb
->attrs
= mb
->attrs
;
537 rmb
->iattrs
= mb
->iattrs
;
538 rmb
->call_conv
= mb
->call_conv
;
540 rmb
->type
= mb
->type
;
541 rmb
->name
= mono_string_new_checked (mono_domain_get (), name
, error
);
542 return_val_if_nok (error
, FALSE
);
543 rmb
->table_idx
= &mb
->table_idx
;
544 rmb
->init_locals
= mb
->init_locals
;
545 rmb
->skip_visibility
= FALSE
;
546 rmb
->return_modreq
= NULL
;
547 rmb
->return_modopt
= NULL
;
548 rmb
->param_modreq
= mb
->param_modreq
;
549 rmb
->param_modopt
= mb
->param_modopt
;
550 rmb
->permissions
= mb
->permissions
;
551 rmb
->mhandle
= mb
->mhandle
;
559 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
)
561 MONO_REQ_GC_UNSAFE_MODE
;
563 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
565 rmb
->ilgen
= mb
->ilgen
;
566 rmb
->rtype
= mb
->rtype
;
567 rmb
->parameters
= mb
->parameters
;
568 rmb
->generic_params
= NULL
;
569 rmb
->generic_container
= NULL
;
570 rmb
->opt_types
= NULL
;
572 rmb
->attrs
= mb
->attrs
;
574 rmb
->call_conv
= mb
->call_conv
;
576 rmb
->type
= (MonoObject
*) mb
->owner
;
577 rmb
->name
= mb
->name
;
578 rmb
->table_idx
= NULL
;
579 rmb
->init_locals
= mb
->init_locals
;
580 rmb
->skip_visibility
= mb
->skip_visibility
;
581 rmb
->return_modreq
= NULL
;
582 rmb
->return_modopt
= NULL
;
583 rmb
->param_modreq
= NULL
;
584 rmb
->param_modopt
= NULL
;
585 rmb
->permissions
= NULL
;
586 rmb
->mhandle
= mb
->mhandle
;
590 #else /* DISABLE_REFLECTION_EMIT */
592 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
) {
593 g_assert_not_reached ();
597 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
599 g_assert_not_reached ();
602 #endif /* DISABLE_REFLECTION_EMIT */
604 #ifndef DISABLE_REFLECTION_EMIT
606 mono_image_add_memberef_row (MonoDynamicImage
*assembly
, guint32 parent
, const char *name
, guint32 sig
)
608 MONO_REQ_GC_NEUTRAL_MODE
;
610 MonoDynamicTable
*table
;
612 guint32 token
, pclass
;
614 switch (parent
& MONO_TYPEDEFORREF_MASK
) {
615 case MONO_TYPEDEFORREF_TYPEREF
:
616 pclass
= MONO_MEMBERREF_PARENT_TYPEREF
;
618 case MONO_TYPEDEFORREF_TYPESPEC
:
619 pclass
= MONO_MEMBERREF_PARENT_TYPESPEC
;
621 case MONO_TYPEDEFORREF_TYPEDEF
:
622 pclass
= MONO_MEMBERREF_PARENT_TYPEDEF
;
625 g_warning ("unknown typeref or def token 0x%08x for %s", parent
, name
);
628 /* extract the index */
629 parent
>>= MONO_TYPEDEFORREF_BITS
;
631 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
633 if (assembly
->save
) {
634 alloc_table (table
, table
->rows
+ 1);
635 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
636 values
[MONO_MEMBERREF_CLASS
] = pclass
| (parent
<< MONO_MEMBERREF_PARENT_BITS
);
637 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
638 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
641 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
648 * Insert a memberef row into the metadata: the token that point to the memberref
649 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
650 * mono_image_get_fieldref_token()).
651 * The sig param is an index to an already built signature.
654 mono_image_get_memberref_token (MonoDynamicImage
*assembly
, MonoType
*type
, const char *name
, guint32 sig
)
656 MONO_REQ_GC_NEUTRAL_MODE
;
658 guint32 parent
= mono_image_typedef_or_ref (assembly
, type
);
659 return mono_image_add_memberef_row (assembly
, parent
, name
, sig
);
664 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
666 MONO_REQ_GC_NEUTRAL_MODE
;
669 MonoMethodSignature
*sig
;
671 create_typespec
= create_typespec
&& method
->is_generic
&& method
->klass
->image
!= &assembly
->image
;
673 if (create_typespec
) {
674 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1)));
679 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
680 if (token
&& !create_typespec
)
683 g_assert (!method
->is_inflated
);
686 * A methodref signature can't contain an unmanaged calling convention.
688 sig
= mono_metadata_signature_dup (mono_method_signature_internal (method
));
689 if ((sig
->call_convention
!= MONO_CALL_DEFAULT
) && (sig
->call_convention
!= MONO_CALL_VARARG
))
690 sig
->call_convention
= MONO_CALL_DEFAULT
;
691 token
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (method
->klass
),
692 method
->name
, mono_dynimage_encode_method_signature (assembly
, sig
));
694 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
697 if (create_typespec
) {
698 MonoDynamicTable
*table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
699 g_assert (mono_metadata_token_table (token
) == MONO_TABLE_MEMBERREF
);
700 token
= (mono_metadata_token_index (token
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
702 if (assembly
->save
) {
705 alloc_table (table
, table
->rows
+ 1);
706 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
707 values
[MONO_METHODSPEC_METHOD
] = token
;
708 values
[MONO_METHODSPEC_SIGNATURE
] = mono_dynimage_encode_generic_method_sig (assembly
, &mono_method_get_generic_container (method
)->context
);
711 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
713 /*methodspec and memberef tokens are diferent, */
714 g_hash_table_insert (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1), GUINT_TO_POINTER (token
));
721 mono_image_get_varargs_method_token (MonoDynamicImage
*assembly
, guint32 original
,
722 const gchar
*name
, guint32 sig
)
724 MonoDynamicTable
*table
;
728 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
730 if (assembly
->save
) {
731 alloc_table (table
, table
->rows
+ 1);
732 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
733 values
[MONO_MEMBERREF_CLASS
] = original
;
734 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
735 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
738 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
744 #else /* DISABLE_REFLECTION_EMIT */
747 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
749 g_assert_not_reached ();
755 is_field_on_inst (MonoClassField
*field
)
757 return mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->is_dynamic
;
761 is_field_on_gtd (MonoClassField
*field
)
763 return mono_class_is_gtd (field
->parent
);
766 #ifndef DISABLE_REFLECTION_EMIT
768 mono_image_get_fieldref_token (MonoDynamicImage
*assembly
, MonoClassField
*field
)
774 g_assert (field
->parent
);
776 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, field
));
780 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
) {
781 int index
= field
- field
->parent
->fields
;
782 type
= mono_field_get_type_internal (&mono_class_get_generic_class (field
->parent
)->container_class
->fields
[index
]);
784 type
= mono_field_get_type_internal (field
);
786 token
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (field
->parent
),
787 mono_field_get_name (field
),
788 mono_dynimage_encode_fieldref_signature (assembly
, field
->parent
->image
, type
));
789 g_hash_table_insert (assembly
->handleref
, field
, GUINT_TO_POINTER(token
));
794 method_encode_methodspec (MonoDynamicImage
*assembly
, MonoMethod
*method
)
796 MonoDynamicTable
*table
;
798 guint32 token
, mtoken
= 0, sig
;
799 MonoMethodInflated
*imethod
;
800 MonoMethod
*declaring
;
802 table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
804 g_assert (method
->is_inflated
);
805 imethod
= (MonoMethodInflated
*) method
;
806 declaring
= imethod
->declaring
;
808 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature_internal (declaring
));
809 mtoken
= mono_image_get_memberref_token (assembly
, m_class_get_byval_arg (method
->klass
), declaring
->name
, sig
);
811 if (!mono_method_signature_internal (declaring
)->generic_param_count
)
814 switch (mono_metadata_token_table (mtoken
)) {
815 case MONO_TABLE_MEMBERREF
:
816 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
818 case MONO_TABLE_METHOD
:
819 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODDEF
;
822 g_assert_not_reached ();
825 sig
= mono_dynimage_encode_generic_method_sig (assembly
, mono_method_get_context (method
));
827 if (assembly
->save
) {
828 alloc_table (table
, table
->rows
+ 1);
829 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
830 values
[MONO_METHODSPEC_METHOD
] = mtoken
;
831 values
[MONO_METHODSPEC_SIGNATURE
] = sig
;
834 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
841 mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
)
843 MonoMethodInflated
*imethod
;
846 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
850 g_assert (method
->is_inflated
);
851 imethod
= (MonoMethodInflated
*) method
;
853 if (mono_method_signature_internal (imethod
->declaring
)->generic_param_count
) {
854 token
= method_encode_methodspec (assembly
, method
);
856 guint32 sig
= mono_dynimage_encode_method_signature (
857 assembly
, mono_method_signature_internal (imethod
->declaring
));
858 token
= mono_image_get_memberref_token (
859 assembly
, m_class_get_byval_arg (method
->klass
), method
->name
, sig
);
862 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
867 mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
)
869 MonoMethodInflated
*imethod
= (MonoMethodInflated
*) m
;
872 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature_internal (imethod
->declaring
));
873 token
= mono_image_get_memberref_token (
874 assembly
, m_class_get_byval_arg (m
->klass
), m
->name
, sig
);
880 mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
)
883 MonoDynamicTable
*table
;
888 table
= &assembly
->tables
[MONO_TABLE_STANDALONESIG
];
889 idx
= table
->next_idx
++;
891 alloc_table (table
, table
->rows
);
892 values
= table
->values
+ idx
* MONO_STAND_ALONE_SIGNATURE_SIZE
;
894 values
[MONO_STAND_ALONE_SIGNATURE
] =
895 mono_dynimage_encode_reflection_sighelper (assembly
, helper
, error
);
896 return_val_if_nok (error
, 0);
902 reflection_cc_to_file (int call_conv
) {
903 switch (call_conv
& 0x3) {
905 case 1: return MONO_CALL_DEFAULT
;
906 case 2: return MONO_CALL_VARARG
;
908 g_assert_not_reached ();
912 #endif /* !DISABLE_REFLECTION_EMIT */
914 struct _ArrayMethod
{
916 MonoMethodSignature
*sig
;
922 mono_sre_array_method_free (ArrayMethod
*am
)
929 #ifndef DISABLE_REFLECTION_EMIT
931 mono_image_get_array_token (MonoDynamicImage
*assembly
, MonoReflectionArrayMethodHandle m
, MonoError
*error
)
933 MonoMethodSignature
*sig
= NULL
;
938 MonoArrayHandle parameters
= MONO_HANDLE_NEW_GET (MonoArray
, m
, parameters
);
939 guint32 nparams
= mono_array_handle_length (parameters
);
940 sig
= (MonoMethodSignature
*)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * nparams
);
942 sig
->sentinelpos
= -1;
943 sig
->call_convention
= reflection_cc_to_file (MONO_HANDLE_GETVAL (m
, call_conv
));
944 sig
->param_count
= nparams
;
945 MonoReflectionTypeHandle ret
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, ret
);
946 if (!MONO_HANDLE_IS_NULL (ret
)) {
947 sig
->ret
= mono_reflection_type_handle_mono_type (ret
, error
);
948 goto_if_nok (error
, fail
);
950 sig
->ret
= mono_get_void_type ();
952 MonoReflectionTypeHandle parent
;
953 parent
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, parent
);
955 mtype
= mono_reflection_type_handle_mono_type (parent
, error
);
956 goto_if_nok (error
, fail
);
958 for (int i
= 0; i
< nparams
; ++i
) {
959 sig
->params
[i
] = mono_type_array_get_and_resolve (parameters
, i
, error
);
960 goto_if_nok (error
, fail
);
963 MonoStringHandle mname
;
964 mname
= MONO_HANDLE_NEW_GET (MonoString
, m
, name
);
965 name
= mono_string_handle_to_utf8 (mname
, error
);
966 goto_if_nok (error
, fail
);
970 for (GList
*tmp
= assembly
->array_methods
; tmp
; tmp
= tmp
->next
) {
971 am
= (ArrayMethod
*)tmp
->data
;
972 if (strcmp (name
, am
->name
) == 0 &&
973 mono_metadata_type_equal (am
->parent
, mtype
) &&
974 mono_metadata_signature_equal (am
->sig
, sig
)) {
977 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
981 am
= g_new0 (ArrayMethod
, 1);
985 am
->token
= mono_image_get_memberref_token (assembly
, am
->parent
, name
,
986 mono_dynimage_encode_method_signature (assembly
, sig
));
987 assembly
->array_methods
= g_list_prepend (assembly
->array_methods
, am
);
988 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
998 #ifndef DISABLE_REFLECTION_EMIT
1001 * mono_image_insert_string:
1002 * @module: module builder object
1005 * Insert @str into the user string stream of @module.
1008 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module
, MonoStringHandle str
, MonoError
*error
)
1010 HANDLE_FUNCTION_ENTER ();
1016 MonoDynamicImage
*assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1018 if (!mono_image_module_basic_init (ref_module
, error
))
1021 assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1023 g_assert (assembly
!= NULL
);
1025 if (assembly
->save
) {
1026 int32_t length
= mono_string_length_internal (MONO_HANDLE_RAW (str
));
1027 mono_metadata_encode_value (1 | (length
* 2), b
, &b
);
1028 idx
= mono_image_add_stream_data (&assembly
->us
, buf
, b
-buf
);
1030 uint32_t gchandle
= mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject
, str
), TRUE
);
1031 const char *p
= (const char*)mono_string_chars_internal (MONO_HANDLE_RAW (str
));
1032 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1034 char *swapped
= g_malloc (2 * length
);
1036 swap_with_size (swapped
, p
, 2, length
);
1037 mono_image_add_stream_data (&assembly
->us
, swapped
, length
* 2);
1041 mono_image_add_stream_data (&assembly
->us
, p
, length
* 2);
1043 mono_gchandle_free_internal (gchandle
);
1044 mono_image_add_stream_data (&assembly
->us
, "", 1);
1046 idx
= assembly
->us
.index
++;
1049 token
= MONO_TOKEN_STRING
| idx
;
1050 mono_dynamic_image_register_token (assembly
, token
, MONO_HANDLE_CAST (MonoObject
, str
), MONO_DYN_IMAGE_TOK_NEW
);
1053 HANDLE_FUNCTION_RETURN_VAL (token
);
1057 create_method_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1059 guint32 sig_token
, parent
;
1062 int nargs
= mono_array_handle_length (opt_param_types
);
1063 MonoMethodSignature
*old
= mono_method_signature_internal (method
);
1064 MonoMethodSignature
*sig
= mono_metadata_signature_alloc ( &assembly
->image
, old
->param_count
+ nargs
);
1066 sig
->hasthis
= old
->hasthis
;
1067 sig
->explicit_this
= old
->explicit_this
;
1068 sig
->call_convention
= old
->call_convention
;
1069 sig
->generic_param_count
= old
->generic_param_count
;
1070 sig
->param_count
= old
->param_count
+ nargs
;
1071 sig
->sentinelpos
= old
->param_count
;
1072 sig
->ret
= old
->ret
;
1074 for (int i
= 0; i
< old
->param_count
; i
++)
1075 sig
->params
[i
] = old
->params
[i
];
1077 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1078 for (int i
= 0; i
< nargs
; i
++) {
1079 MONO_HANDLE_ARRAY_GETREF (rt
, opt_param_types
, i
);
1080 sig
->params
[old
->param_count
+ i
] = mono_reflection_type_handle_mono_type (rt
, error
);
1081 goto_if_nok (error
, fail
);
1084 parent
= mono_image_typedef_or_ref (assembly
, m_class_get_byval_arg (method
->klass
));
1085 g_assert ((parent
& MONO_TYPEDEFORREF_MASK
) == MONO_MEMBERREF_PARENT_TYPEREF
);
1086 parent
>>= MONO_TYPEDEFORREF_BITS
;
1088 parent
<<= MONO_MEMBERREF_PARENT_BITS
;
1089 parent
|= MONO_MEMBERREF_PARENT_TYPEREF
;
1091 sig_token
= mono_dynimage_encode_method_signature (assembly
, sig
);
1093 token
= mono_image_get_varargs_method_token (assembly
, parent
, method
->name
, sig_token
);
1094 g_hash_table_insert (assembly
->vararg_aux_hash
, GUINT_TO_POINTER (token
), sig
);
1101 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1107 MonoClass
*klass
= mono_handle_class (obj
);
1108 if (strcmp (klass
->name
, "MonoMethod") == 0 || strcmp (klass
->name
, "MonoCMethod") == 0) {
1109 MonoReflectionMethodHandle ref_method
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1110 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
1111 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types
) && (mono_method_signature_internal (method
)->sentinelpos
>= 0));
1112 token
= create_method_token (assembly
, method
, opt_param_types
, error
);
1113 goto_if_nok (error
, fail
);
1114 } else if (strcmp (klass
->name
, "MethodBuilder") == 0) {
1115 g_assert_not_reached ();
1117 g_error ("requested method token for %s\n", klass
->name
);
1120 mono_dynamic_image_register_token (assembly
, token
, obj
, MONO_DYN_IMAGE_TOK_NEW
);
1123 g_assert (!mono_error_ok (error
));
1128 * mono_image_create_token:
1129 * @assembly: a dynamic assembly
1131 * @register_token: Whenever to register the token in the assembly->tokens hash.
1133 * Get a token to insert in the IL code stream for the given MemberInfo.
1134 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1135 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1139 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
1140 gboolean create_open_instance
, gboolean register_token
,
1143 HANDLE_FUNCTION_ENTER ();
1148 MonoClass
*klass
= mono_handle_class (obj
);
1149 MonoObjectHandle register_obj
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1150 MONO_HANDLE_ASSIGN (register_obj
, obj
);
1152 /* Check for user defined reflection objects */
1153 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1154 if (klass
->image
!= mono_defaults
.corlib
|| (strcmp (klass
->name
, "TypeDelegator") == 0)) {
1155 mono_error_set_not_supported (error
, "User defined subclasses of System.Type are not yet supported");
1159 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1161 how_collide
= MONO_DYN_IMAGE_TOK_SAME_OK
;
1163 if (strcmp (klass
->name
, "RuntimeType") == 0) {
1164 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, obj
), error
);
1165 goto_if_nok (error
, leave
);
1166 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
1167 token
= mono_metadata_token_from_dor (
1168 mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, !mono_class_is_gtd (mc
) || create_open_instance
));
1169 /* If it's a RuntimeType now, we could have registered a
1170 * TypeBuilder for it before, so replacing is okay. */
1171 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1172 } else if (strcmp (klass
->name
, "MonoCMethod") == 0 ||
1173 strcmp (klass
->name
, "MonoMethod") == 0) {
1174 MonoReflectionMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1175 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
1176 if (method
->is_inflated
) {
1177 if (create_open_instance
) {
1178 guint32 methodspec_token
= mono_image_get_methodspec_token (assembly
, method
);
1179 MonoReflectionMethodHandle canonical_obj
=
1180 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1181 goto_if_nok (error
, leave
);
1182 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1183 token
= methodspec_token
;
1185 token
= mono_image_get_inflated_method_token (assembly
, method
);
1186 } else if ((method
->klass
->image
== &assembly
->image
) &&
1187 !mono_class_is_ginst (method
->klass
) &&
1188 !mono_class_is_gtd (method
->klass
)) {
1189 static guint32 method_table_idx
= 0xffffff;
1190 if (method
->klass
->wastypebuilder
) {
1191 /* we use the same token as the one that was assigned
1192 * to the Methodbuilder.
1193 * FIXME: do the equivalent for Fields.
1195 token
= method
->token
;
1196 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1199 * Each token should have a unique index, but the indexes are
1200 * assigned by managed code, so we don't know about them. An
1201 * easy solution is to count backwards...
1203 method_table_idx
--;
1204 token
= MONO_TOKEN_METHOD_DEF
| method_table_idx
;
1205 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1208 guint32 methodref_token
= mono_image_get_methodref_token (assembly
, method
, create_open_instance
);
1209 /* We need to register a 'canonical' object. The same
1210 * MonoMethod could have been reflected via different
1211 * classes so the MonoReflectionMethod:reftype could be
1212 * different, and the object lookup in
1213 * dynamic_image_register_token would assert assert. So
1214 * we pick the MonoReflectionMethod object that has the
1215 * reflected type as NULL (ie, take the declaring type
1217 MonoReflectionMethodHandle canonical_obj
=
1218 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1219 goto_if_nok (error
, leave
);
1220 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1221 token
= methodref_token
;
1223 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1224 } else if (strcmp (klass
->name
, "MonoField") == 0) {
1225 MonoReflectionFieldHandle f
= MONO_HANDLE_CAST (MonoReflectionField
, obj
);
1226 MonoClassField
*field
= MONO_HANDLE_GETVAL (f
, field
);
1227 if ((field
->parent
->image
== &assembly
->image
) &&
1228 !is_field_on_gtd (field
) &&
1229 !is_field_on_inst (field
)) {
1230 static guint32 field_table_idx
= 0xffffff;
1232 token
= MONO_TOKEN_FIELD_DEF
| field_table_idx
;
1233 g_assert (!mono_class_is_gtd (field
->parent
));
1234 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1236 guint32 fieldref_token
= mono_image_get_fieldref_token (assembly
, field
);
1237 /* Same as methodref: get a canonical object to
1238 * register with the token. */
1239 MonoReflectionFieldHandle canonical_obj
=
1240 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj
), field
->parent
, field
, error
);
1241 goto_if_nok (error
, leave
);
1242 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1243 token
= fieldref_token
;
1245 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1246 } else if (strcmp (klass
->name
, "MonoArrayMethod") == 0) {
1247 MonoReflectionArrayMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionArrayMethod
, obj
);
1248 /* mono_image_get_array_token caches tokens by signature */
1249 guint32 array_token
= mono_image_get_array_token (assembly
, m
, error
);
1250 goto_if_nok (error
, leave
);
1251 token
= array_token
;
1252 /* ModuleBuilder:GetArrayMethod() always returns a fresh
1253 * MonoArrayMethod instance even given the same method name and
1254 * signature. But they're all interchangeable, so it's okay to
1257 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1258 } else if (strcmp (klass
->name
, "SignatureHelper") == 0) {
1259 MonoReflectionSigHelperHandle s
= MONO_HANDLE_CAST (MonoReflectionSigHelper
, obj
);
1260 /* always returns a fresh token */
1261 guint32 sig_token
= MONO_TOKEN_SIGNATURE
| mono_image_get_sighelper_token (assembly
, s
, error
);
1262 goto_if_nok (error
, leave
);
1264 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1266 g_error ("requested token for %s\n", klass
->name
);
1270 mono_dynamic_image_register_token (assembly
, token
, register_obj
, how_collide
);
1273 HANDLE_FUNCTION_RETURN_VAL (token
);
1279 #ifndef DISABLE_REFLECTION_EMIT
1282 assemblybuilderaccess_can_refonlyload (guint32 access
)
1284 return (access
& 0x4) != 0;
1288 assemblybuilderaccess_can_run (guint32 access
)
1290 return (access
& MonoAssemblyBuilderAccess_Run
) != 0;
1294 assemblybuilderaccess_can_save (guint32 access
)
1296 return (access
& MonoAssemblyBuilderAccess_Save
) != 0;
1301 * mono_reflection_dynimage_basic_init:
1302 * @assembly: an assembly builder object
1304 * Create the MonoImage that represents the assembly builder and setup some
1305 * of the helper hash table and the basic metadata streams.
1308 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
1311 MonoDynamicAssembly
*assembly
;
1312 MonoDynamicImage
*image
;
1313 MonoDomain
*domain
= mono_object_domain (assemblyb
);
1315 if (assemblyb
->dynamic_assembly
)
1318 assembly
= assemblyb
->dynamic_assembly
= g_new0 (MonoDynamicAssembly
, 1);
1320 MONO_PROFILER_RAISE (assembly_loading
, (&assembly
->assembly
));
1322 assembly
->assembly
.ref_count
= 1;
1323 assembly
->assembly
.dynamic
= TRUE
;
1324 assembly
->assembly
.corlib_internal
= assemblyb
->corlib_internal
;
1325 assemblyb
->assembly
.assembly
= (MonoAssembly
*)assembly
;
1326 assembly
->assembly
.basedir
= mono_string_to_utf8_checked_internal (assemblyb
->dir
, error
);
1327 if (mono_error_set_pending_exception (error
))
1329 if (assemblyb
->culture
) {
1330 assembly
->assembly
.aname
.culture
= mono_string_to_utf8_checked_internal (assemblyb
->culture
, error
);
1331 if (mono_error_set_pending_exception (error
))
1334 assembly
->assembly
.aname
.culture
= g_strdup ("");
1336 if (assemblyb
->version
) {
1337 char *vstr
= mono_string_to_utf8_checked_internal (assemblyb
->version
, error
);
1338 if (mono_error_set_pending_exception (error
))
1340 char **version
= g_strsplit (vstr
, ".", 4);
1341 char **parts
= version
;
1342 assembly
->assembly
.aname
.major
= atoi (*parts
++);
1343 assembly
->assembly
.aname
.minor
= atoi (*parts
++);
1344 assembly
->assembly
.aname
.build
= *parts
!= NULL
? atoi (*parts
++) : 0;
1345 assembly
->assembly
.aname
.revision
= *parts
!= NULL
? atoi (*parts
) : 0;
1347 g_strfreev (version
);
1350 assembly
->assembly
.aname
.major
= 0;
1351 assembly
->assembly
.aname
.minor
= 0;
1352 assembly
->assembly
.aname
.build
= 0;
1353 assembly
->assembly
.aname
.revision
= 0;
1356 /* SRE assemblies are loaded into the individual loading context, ie,
1357 * they only fire AssemblyResolve events, they don't cause probing for
1358 * referenced assemblies to happen. */
1359 assembly
->assembly
.context
.kind
= assemblybuilderaccess_can_refonlyload (assemblyb
->access
) ? MONO_ASMCTX_REFONLY
: MONO_ASMCTX_INDIVIDUAL
;
1360 assembly
->run
= assemblybuilderaccess_can_run (assemblyb
->access
);
1361 assembly
->save
= assemblybuilderaccess_can_save (assemblyb
->access
);
1362 assembly
->domain
= domain
;
1364 char *assembly_name
= mono_string_to_utf8_checked_internal (assemblyb
->name
, error
);
1365 if (mono_error_set_pending_exception (error
))
1367 image
= mono_dynamic_image_create (assembly
, assembly_name
, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1368 image
->initial_image
= TRUE
;
1369 assembly
->assembly
.aname
.name
= image
->image
.name
;
1370 assembly
->assembly
.image
= &image
->image
;
1371 if (assemblyb
->pktoken
&& assemblyb
->pktoken
->max_length
) {
1372 /* -1 to correct for the trailing NULL byte */
1373 if (assemblyb
->pktoken
->max_length
!= MONO_PUBLIC_KEY_TOKEN_LENGTH
- 1) {
1374 g_error ("Public key token length invalid for assembly %s: %i", assembly
->assembly
.aname
.name
, assemblyb
->pktoken
->max_length
);
1376 memcpy (&assembly
->assembly
.aname
.public_key_token
, mono_array_addr_internal (assemblyb
->pktoken
, guint8
, 0), assemblyb
->pktoken
->max_length
);
1379 mono_domain_assemblies_lock (domain
);
1380 domain
->domain_assemblies
= g_slist_append (domain
->domain_assemblies
, assembly
);
1381 mono_domain_assemblies_unlock (domain
);
1383 register_assembly (mono_object_domain (assemblyb
), &assemblyb
->assembly
, &assembly
->assembly
);
1385 MONO_PROFILER_RAISE (assembly_loaded
, (&assembly
->assembly
));
1387 mono_assembly_invoke_load_hook ((MonoAssembly
*)assembly
);
1390 #endif /* !DISABLE_REFLECTION_EMIT */
1392 #ifndef DISABLE_REFLECTION_EMIT
1394 register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
)
1396 return CACHE_OBJECT (MonoReflectionAssembly
*, assembly
, &res
->object
, NULL
);
1399 static MonoReflectionModuleBuilderHandle
1400 register_module (MonoDomain
*domain
, MonoReflectionModuleBuilderHandle res
, MonoDynamicImage
*module
)
1402 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilder
, module
, MONO_HANDLE_CAST (MonoObject
, res
), NULL
);
1406 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1409 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (moduleb
);
1410 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
1411 MonoReflectionAssemblyBuilderHandle ab
= MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder
, NULL
);
1412 MONO_HANDLE_GET (ab
, moduleb
, assemblyb
);
1415 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1416 * we don't know which module it belongs to, since that is only
1417 * determined at assembly save time.
1419 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1420 MonoStringHandle abname
= MONO_HANDLE_NEW_GET (MonoString
, ab
, name
);
1421 char *name
= mono_string_handle_to_utf8 (abname
, error
);
1422 return_val_if_nok (error
, FALSE
);
1423 MonoStringHandle modfqname
= MONO_HANDLE_NEW_GET (MonoString
, MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), fqname
);
1424 char *fqname
= mono_string_handle_to_utf8 (modfqname
, error
);
1425 if (!is_ok (error
)) {
1429 MonoDynamicAssembly
*dynamic_assembly
= MONO_HANDLE_GETVAL (ab
, dynamic_assembly
);
1430 image
= mono_dynamic_image_create (dynamic_assembly
, name
, fqname
);
1432 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), image
, MonoImage
*, &image
->image
);
1433 MONO_HANDLE_SETVAL (moduleb
, dynamic_image
, MonoDynamicImage
*, image
);
1434 register_module (domain
, moduleb
, image
);
1436 /* register the module with the assembly */
1437 MonoImage
*ass
= dynamic_assembly
->assembly
.image
;
1438 int module_count
= ass
->module_count
;
1439 MonoImage
**new_modules
= g_new0 (MonoImage
*, module_count
+ 1);
1442 memcpy (new_modules
, ass
->modules
, module_count
* sizeof (MonoImage
*));
1443 new_modules
[module_count
] = &image
->image
;
1444 mono_image_addref (&image
->image
);
1446 g_free (ass
->modules
);
1447 ass
->modules
= new_modules
;
1448 ass
->module_count
++;
1454 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1457 return image_module_basic_init (moduleb
, error
);
1463 is_corlib_type (MonoClass
*klass
)
1465 return klass
->image
== mono_defaults
.corlib
;
1468 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1469 static MonoClass *cached_class; \
1471 return cached_class == _class; \
1472 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1473 cached_class = _class; \
1481 mono_type_array_get_and_resolve (MonoArrayHandle array
, int idx
, MonoError
*error
)
1483 HANDLE_FUNCTION_ENTER();
1485 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1486 MONO_HANDLE_ARRAY_GETREF (t
, array
, idx
);
1487 MonoType
*result
= mono_reflection_type_handle_mono_type (t
, error
);
1488 HANDLE_FUNCTION_RETURN_VAL (result
);
1492 add_custom_modifiers_to_type (MonoType
*without_mods
, MonoArrayHandle req_array
, MonoArrayHandle opt_array
, MonoImage
*image
, MonoError
*error
)
1494 HANDLE_FUNCTION_ENTER();
1497 int num_req_mods
= 0;
1498 if (!MONO_HANDLE_IS_NULL (req_array
))
1499 num_req_mods
= mono_array_handle_length (req_array
);
1501 int num_opt_mods
= 0;
1502 if (!MONO_HANDLE_IS_NULL (opt_array
))
1503 num_opt_mods
= mono_array_handle_length (opt_array
);
1505 if (!(num_opt_mods
|| num_req_mods
))
1506 return without_mods
;
1508 MonoTypeWithModifiers
*result
;
1509 result
= mono_image_g_malloc0 (image
, mono_sizeof_type_with_mods (num_req_mods
+ num_opt_mods
));
1510 memcpy (result
, without_mods
, MONO_SIZEOF_TYPE
);
1511 result
->unmodified
.has_cmods
= 1;
1512 MonoCustomModContainer
*cmods
= mono_type_get_cmods ((MonoType
*)result
);
1514 cmods
->count
= num_req_mods
+ num_opt_mods
;
1515 cmods
->image
= image
;
1517 g_assert (image_is_dynamic (image
));
1518 MonoDynamicImage
*allocator
= (MonoDynamicImage
*) image
;
1520 int modifier_index
= 0;
1522 MonoObjectHandle mod_handle
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1523 for (int i
=0; i
< num_req_mods
; i
++) {
1524 cmods
->modifiers
[modifier_index
].required
= TRUE
;
1525 MONO_HANDLE_ARRAY_GETREF (mod_handle
, req_array
, i
);
1526 cmods
->modifiers
[modifier_index
].token
= mono_image_create_token (allocator
, mod_handle
, FALSE
, TRUE
, error
);
1530 for (int i
=0; i
< num_opt_mods
; i
++) {
1531 cmods
->modifiers
[modifier_index
].required
= FALSE
;
1532 MONO_HANDLE_ARRAY_GETREF (mod_handle
, opt_array
, i
);
1533 cmods
->modifiers
[modifier_index
].token
= mono_image_create_token (allocator
, mod_handle
, FALSE
, TRUE
, error
);
1537 HANDLE_FUNCTION_RETURN_VAL ((MonoType
*) result
);
1542 mono_type_array_get_and_resolve_with_modifiers (MonoArrayHandle types
, MonoArrayHandle required_modifiers
, MonoArrayHandle optional_modifiers
, int idx
, MonoImage
*image
, MonoError
*error
)
1544 HANDLE_FUNCTION_ENTER();
1546 MonoReflectionTypeHandle type
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1547 MonoArrayHandle req_mods_handle
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1548 MonoArrayHandle opt_mods_handle
= MONO_HANDLE_NEW (MonoArray
, NULL
);
1550 if (!MONO_HANDLE_IS_NULL (required_modifiers
))
1551 MONO_HANDLE_ARRAY_GETREF (req_mods_handle
, required_modifiers
, idx
);
1553 if (!MONO_HANDLE_IS_NULL (optional_modifiers
))
1554 MONO_HANDLE_ARRAY_GETREF (opt_mods_handle
, optional_modifiers
, idx
);
1556 MONO_HANDLE_ARRAY_GETREF (type
, types
, idx
);
1558 MonoType
*result
= mono_reflection_type_handle_mono_type (type
, error
);
1559 result
= (MonoType
*) add_custom_modifiers_to_type (result
, req_mods_handle
, opt_mods_handle
, image
, error
);
1561 HANDLE_FUNCTION_RETURN_VAL (result
);
1565 #ifndef DISABLE_REFLECTION_EMIT
1567 is_sre_array (MonoClass
*klass
)
1569 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ArrayType");
1573 is_sre_byref (MonoClass
*klass
)
1575 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ByRefType");
1579 is_sre_pointer (MonoClass
*klass
)
1581 check_corlib_type_cached (klass
, "System.Reflection.Emit", "PointerType");
1585 is_sre_generic_instance (MonoClass
*klass
)
1587 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilderInstantiation");
1591 is_sre_type_builder (MonoClass
*klass
)
1593 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilder");
1597 is_sre_method_builder (MonoClass
*klass
)
1599 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodBuilder");
1603 mono_is_sre_ctor_builder (MonoClass
*klass
)
1605 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorBuilder");
1609 is_sre_field_builder (MonoClass
*klass
)
1611 check_corlib_type_cached (klass
, "System.Reflection.Emit", "FieldBuilder");
1615 is_sre_gparam_builder (MonoClass
*klass
)
1617 check_corlib_type_cached (klass
, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1621 is_sre_enum_builder (MonoClass
*klass
)
1623 check_corlib_type_cached (klass
, "System.Reflection.Emit", "EnumBuilder");
1627 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1629 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1633 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1635 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1638 static MonoReflectionTypeHandle
1639 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
)
1641 static MonoMethod
*method_get_underlying_system_type
= NULL
;
1642 HANDLE_FUNCTION_ENTER ();
1646 if (!method_get_underlying_system_type
) {
1647 method_get_underlying_system_type
= mono_class_get_method_from_name_checked (mono_defaults
.systemtype_class
, "get_UnderlyingSystemType", 0, 0, error
);
1648 mono_error_assert_ok (error
);
1651 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1653 MonoMethod
*usertype_method
= mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject
, t
), method_get_underlying_system_type
, error
);
1654 goto_if_nok (error
, leave
);
1656 MONO_HANDLE_ASSIGN (rt
, MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW (MonoObject
, mono_runtime_invoke_checked (usertype_method
, MONO_HANDLE_RAW (t
), NULL
, error
))));
1659 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType
, rt
);
1663 mono_reflection_type_get_handle (MonoReflectionType
* ref_raw
, MonoError
*error
)
1665 HANDLE_FUNCTION_ENTER ();
1667 MONO_HANDLE_DCL (MonoReflectionType
, ref
);
1668 MonoType
*result
= mono_reflection_type_handle_mono_type (ref
, error
);
1669 HANDLE_FUNCTION_RETURN_VAL (result
);
1673 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass
, MonoError
*error
)
1675 HANDLE_FUNCTION_ENTER ();
1676 MonoType
*result
= NULL
;
1677 MonoType
**types
= NULL
;
1679 MonoArrayHandle typeargs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_gclass
, type_arguments
);
1680 int count
= mono_array_handle_length (typeargs
);
1681 types
= g_new0 (MonoType
*, count
);
1682 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1683 for (int i
= 0; i
< count
; ++i
) {
1684 MONO_HANDLE_ARRAY_GETREF (t
, typeargs
, i
);
1685 types
[i
] = mono_reflection_type_handle_mono_type (t
, error
);
1686 if (!types
[i
] || !is_ok (error
)) {
1690 /* Need to resolve the generic_type in order for it to create its generic context. */
1691 MonoReflectionTypeHandle ref_gtd
;
1692 ref_gtd
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_gclass
, generic_type
);
1694 gtd
= mono_reflection_type_handle_mono_type (ref_gtd
, error
);
1695 goto_if_nok (error
, leave
);
1696 MonoClass
*gtd_klass
;
1697 gtd_klass
= mono_class_from_mono_type_internal (gtd
);
1698 if (is_sre_type_builder (mono_handle_class (ref_gtd
))) {
1699 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_gtd
), error
);
1700 goto_if_nok (error
, leave
);
1702 g_assert (count
== 0 || mono_class_is_gtd (gtd_klass
));
1703 result
= mono_reflection_bind_generic_parameters (ref_gtd
, count
, types
, error
);
1704 goto_if_nok (error
, leave
);
1706 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gclass
), type
, MonoType
*, result
);
1709 HANDLE_FUNCTION_RETURN_VAL (result
);
1713 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam
, MonoError
*error
)
1715 HANDLE_FUNCTION_ENTER ();
1717 MonoType
*result
= NULL
;
1720 MonoReflectionTypeBuilderHandle ref_tbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_gparam
, tbuilder
);
1721 MonoReflectionModuleBuilderHandle ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tbuilder
, module
);
1722 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1723 MonoImage
*image
= &dynamic_image
->image
;
1725 MonoGenericParamFull
*param
= mono_image_new0 (image
, MonoGenericParamFull
, 1);
1727 MonoStringHandle ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_gparam
, name
);
1728 param
->info
.name
= mono_string_to_utf8_image (image
, ref_name
, error
);
1729 mono_error_assert_ok (error
);
1730 param
->num
= MONO_HANDLE_GETVAL (ref_gparam
, index
);
1732 MonoReflectionMethodBuilderHandle ref_mbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder
, ref_gparam
, mbuilder
);
1733 if (!MONO_HANDLE_IS_NULL (ref_mbuilder
)) {
1734 MonoGenericContainer
*generic_container
= MONO_HANDLE_GETVAL (ref_mbuilder
, generic_container
);
1735 if (!generic_container
) {
1736 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (image
, sizeof (MonoGenericContainer
));
1737 generic_container
->is_method
= TRUE
;
1739 * Cannot set owner.method, since the MonoMethod is not created yet.
1740 * Set the image field instead, so type_in_image () works.
1742 generic_container
->is_anonymous
= TRUE
;
1743 generic_container
->owner
.image
= image
;
1744 MONO_HANDLE_SETVAL (ref_mbuilder
, generic_container
, MonoGenericContainer
*, generic_container
);
1746 param
->owner
= generic_container
;
1748 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_tbuilder
), error
);
1749 goto_if_nok (error
, leave
);
1751 owner
= mono_class_from_mono_type_internal (type
);
1752 g_assert (mono_class_is_gtd (owner
));
1753 param
->owner
= mono_class_get_generic_container (owner
);
1757 pklass
= mono_class_create_generic_parameter ((MonoGenericParam
*) param
);
1759 result
= m_class_get_byval_arg (pklass
);
1761 mono_class_set_ref_info (pklass
, MONO_HANDLE_CAST (MonoObject
, ref_gparam
));
1762 mono_image_append_class_to_reflection_info_set (pklass
);
1764 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), type
, MonoType
*, result
);
1767 HANDLE_FUNCTION_RETURN_VAL (result
);
1771 mono_type_array_get_and_resolve_raw (MonoArray
* array_raw
, int idx
, MonoError
*error
)
1773 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1775 MONO_HANDLE_DCL (MonoArray
, array
);
1776 MonoType
*result
= mono_type_array_get_and_resolve (array
, idx
, error
);
1777 HANDLE_FUNCTION_RETURN_VAL (result
);
1781 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
1783 HANDLE_FUNCTION_ENTER ();
1786 MonoType
* result
= NULL
;
1788 g_assert (!MONO_HANDLE_IS_NULL (ref
));
1789 if (MONO_HANDLE_IS_NULL (ref
))
1792 t
= MONO_HANDLE_GETVAL (ref
, type
);
1798 if (mono_reflection_is_usertype (ref
)) {
1799 MONO_HANDLE_ASSIGN (ref
, mono_reflection_type_get_underlying_system_type (ref
, error
));
1800 if (!is_ok (error
) || MONO_HANDLE_IS_NULL (ref
) || mono_reflection_is_usertype (ref
))
1802 t
= MONO_HANDLE_GETVAL (ref
, type
);
1810 klass
= mono_handle_class (ref
);
1812 if (is_sre_array (klass
)) {
1813 MonoReflectionArrayTypeHandle sre_array
= MONO_HANDLE_CAST (MonoReflectionArrayType
, ref
);
1814 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_array
, element_type
);
1815 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1816 goto_if_nok (error
, leave
);
1818 gint32 rank
= MONO_HANDLE_GETVAL (sre_array
, rank
);
1819 MonoClass
*eclass
= mono_class_from_mono_type_internal (base
);
1820 result
= mono_image_new0 (eclass
->image
, MonoType
, 1);
1822 result
->type
= MONO_TYPE_SZARRAY
;
1823 result
->data
.klass
= eclass
;
1825 MonoArrayType
*at
= (MonoArrayType
*)mono_image_alloc0 (eclass
->image
, sizeof (MonoArrayType
));
1826 result
->type
= MONO_TYPE_ARRAY
;
1827 result
->data
.array
= at
;
1828 at
->eklass
= eclass
;
1831 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1832 } else if (is_sre_byref (klass
)) {
1833 MonoReflectionDerivedTypeHandle sre_byref
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1834 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_byref
, element_type
);
1835 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1836 goto_if_nok (error
, leave
);
1838 result
= &mono_class_from_mono_type_internal (base
)->this_arg
;
1839 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1840 } else if (is_sre_pointer (klass
)) {
1841 MonoReflectionDerivedTypeHandle sre_pointer
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1842 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_pointer
, element_type
);
1843 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1844 goto_if_nok (error
, leave
);
1846 result
= m_class_get_byval_arg (mono_class_create_ptr (base
));
1847 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1848 } else if (is_sre_generic_instance (klass
)) {
1849 result
= reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass
, ref
), error
);
1850 } else if (is_sre_gparam_builder (klass
)) {
1851 result
= reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam
, ref
), error
);
1852 } else if (is_sre_enum_builder (klass
)) {
1853 MonoReflectionEnumBuilderHandle ref_ebuilder
= MONO_HANDLE_CAST (MonoReflectionEnumBuilder
, ref
);
1855 MonoReflectionTypeHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_ebuilder
, tb
));
1856 result
= mono_reflection_type_handle_mono_type (ref_tb
, error
);
1857 } else if (is_sre_type_builder (klass
)) {
1858 MonoReflectionTypeBuilderHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref
);
1860 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1861 reflection_setup_internal_class (ref_tb
, error
);
1862 mono_error_assert_ok (error
);
1863 result
= MONO_HANDLE_GETVAL (ref
, type
);
1865 g_error ("Cannot handle corlib user type %s", mono_type_full_name (m_class_get_byval_arg (mono_handle_class (ref
))));
1868 HANDLE_FUNCTION_RETURN_VAL (result
);
1872 * LOCKING: Assumes the loader lock is held.
1874 static MonoMethodSignature
*
1875 parameters_to_signature (MonoImage
*image
, MonoArrayHandle parameters
, MonoArrayHandle required_modifiers
, MonoArrayHandle optional_modifiers
, MonoError
*error
) {
1876 MonoMethodSignature
*sig
;
1881 count
= MONO_HANDLE_IS_NULL (parameters
) ? 0 : mono_array_handle_length (parameters
);
1883 sig
= (MonoMethodSignature
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * count
);
1884 sig
->param_count
= count
;
1885 sig
->sentinelpos
= -1; /* FIXME */
1886 for (i
= 0; i
< count
; ++i
) {
1887 sig
->params
[i
] = mono_type_array_get_and_resolve_with_modifiers (parameters
, required_modifiers
, optional_modifiers
, i
, image
, error
);
1888 if (!is_ok (error
)) {
1889 image_g_free (image
, sig
);
1897 * LOCKING: Assumes the loader lock is held.
1899 static MonoMethodSignature
*
1900 ctor_builder_to_signature (MonoImage
*image
, MonoReflectionCtorBuilderHandle ctor
, MonoError
*error
) {
1901 MonoMethodSignature
*sig
;
1904 MonoArrayHandle params
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, parameters
);
1905 MonoArrayHandle required_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, param_modreq
);
1906 MonoArrayHandle optional_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, ctor
, param_modopt
);
1908 sig
= parameters_to_signature (image
, params
, required_modifiers
, optional_modifiers
, error
);
1909 return_val_if_nok (error
, NULL
);
1910 sig
->hasthis
= MONO_HANDLE_GETVAL (ctor
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1911 sig
->ret
= mono_get_void_type ();
1915 static MonoMethodSignature
*
1916 ctor_builder_to_signature_raw (MonoImage
*image
, MonoReflectionCtorBuilder
* ctor_raw
, MonoError
*error
) {
1917 HANDLE_FUNCTION_ENTER();
1918 MONO_HANDLE_DCL (MonoReflectionCtorBuilder
, ctor
);
1919 MonoMethodSignature
*sig
= ctor_builder_to_signature (image
, ctor
, error
);
1920 HANDLE_FUNCTION_RETURN_VAL (sig
);
1923 * LOCKING: Assumes the loader lock is held.
1925 static MonoMethodSignature
*
1926 method_builder_to_signature (MonoImage
*image
, MonoReflectionMethodBuilderHandle method
, MonoError
*error
) {
1927 MonoMethodSignature
*sig
;
1930 MonoArrayHandle params
= MONO_HANDLE_NEW_GET(MonoArray
, method
, parameters
);
1931 MonoArrayHandle required_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, method
, param_modreq
);
1932 MonoArrayHandle optional_modifiers
= MONO_HANDLE_NEW_GET(MonoArray
, method
, param_modopt
);
1934 sig
= parameters_to_signature (image
, params
, required_modifiers
, optional_modifiers
, error
);
1935 return_val_if_nok (error
, NULL
);
1936 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1937 MonoReflectionTypeHandle rtype
;
1938 rtype
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoObject
, method
, rtype
));
1939 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1940 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1941 if (!is_ok (error
)) {
1942 image_g_free (image
, sig
);
1946 sig
->ret
= mono_get_void_type ();
1948 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, method
, generic_params
);
1949 sig
->generic_param_count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
1953 static MonoMethodSignature
*
1954 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method
, MonoError
*error
)
1956 HANDLE_FUNCTION_ENTER ();
1957 MonoMethodSignature
*sig
= NULL
;
1961 sig
= parameters_to_signature (NULL
, MONO_HANDLE_NEW_GET (MonoArray
, method
, parameters
),
1962 MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
), MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
), error
);
1963 goto_if_nok (error
, leave
);
1964 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1965 MonoReflectionTypeHandle rtype
;
1966 rtype
= MONO_HANDLE_NEW_GET (MonoReflectionType
, method
, rtype
);
1967 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1968 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1969 if (!is_ok (error
)) {
1975 sig
->ret
= mono_get_void_type ();
1977 sig
->generic_param_count
= 0;
1979 HANDLE_FUNCTION_RETURN_VAL (sig
);
1983 get_prop_name_and_type (MonoObject
*prop
, char **name
, MonoType
**type
, MonoError
*error
)
1986 MonoClass
*klass
= mono_object_class (prop
);
1987 if (strcmp (klass
->name
, "PropertyBuilder") == 0) {
1988 MonoReflectionPropertyBuilder
*pb
= (MonoReflectionPropertyBuilder
*)prop
;
1989 *name
= mono_string_to_utf8_checked_internal (pb
->name
, error
);
1990 return_if_nok (error
);
1991 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)pb
->type
, error
);
1993 MonoReflectionProperty
*p
= (MonoReflectionProperty
*)prop
;
1994 *name
= g_strdup (p
->property
->name
);
1995 if (p
->property
->get
)
1996 *type
= mono_method_signature_internal (p
->property
->get
)->ret
;
1998 *type
= mono_method_signature_internal (p
->property
->set
)->params
[mono_method_signature_internal (p
->property
->set
)->param_count
- 1];
2003 get_field_name_and_type (MonoObject
*field
, char **name
, MonoType
**type
, MonoError
*error
)
2006 MonoClass
*klass
= mono_object_class (field
);
2007 if (strcmp (klass
->name
, "FieldBuilder") == 0) {
2008 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)field
;
2009 *name
= mono_string_to_utf8_checked_internal (fb
->name
, error
);
2010 return_if_nok (error
);
2011 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
2013 MonoReflectionField
*f
= (MonoReflectionField
*)field
;
2014 *name
= g_strdup (mono_field_get_name (f
->field
));
2015 *type
= f
->field
->type
;
2019 #else /* DISABLE_REFLECTION_EMIT */
2022 is_sre_type_builder (MonoClass
*klass
)
2028 is_sre_generic_instance (MonoClass
*klass
)
2034 mono_is_sre_ctor_builder (MonoClass
*klass
)
2040 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
2046 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
2051 #endif /* !DISABLE_REFLECTION_EMIT */
2055 is_sr_mono_field (MonoClass
*klass
)
2057 check_corlib_type_cached (klass
, "System.Reflection", "MonoField");
2061 mono_is_sr_mono_property (MonoClass
*klass
)
2063 check_corlib_type_cached (klass
, "System.Reflection", "MonoProperty");
2067 is_sr_mono_method (MonoClass
*klass
)
2069 check_corlib_type_cached (klass
, "System.Reflection", "MonoMethod");
2073 mono_is_sr_mono_cmethod (MonoClass
*klass
)
2075 check_corlib_type_cached (klass
, "System.Reflection", "MonoCMethod");
2079 mono_class_is_reflection_method_or_constructor (MonoClass
*klass
)
2081 return is_sr_mono_method (klass
) || mono_is_sr_mono_cmethod (klass
);
2085 mono_is_sre_type_builder (MonoClass
*klass
)
2087 return is_sre_type_builder (klass
);
2091 mono_is_sre_generic_instance (MonoClass
*klass
)
2093 return is_sre_generic_instance (klass
);
2099 * encode_cattr_value:
2100 * Encode a value in a custom attribute stream of bytes.
2101 * The value to encode is either supplied as an object in argument val
2102 * (valuetypes are boxed), or as a pointer to the data in the
2104 * @type represents the type of the value
2105 * @buffer is the start of the buffer
2106 * @p the current position in the buffer
2107 * @buflen contains the size of the buffer and is used to return the new buffer size
2108 * if this needs to be realloced.
2109 * @retbuffer and @retp return the start and the position of the buffer
2110 * @error set on error.
2113 encode_cattr_value (MonoAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, MonoObject
*arg
, gconstpointer void_argval
, MonoError
*error
)
2115 const char *argval
= (const char*)void_argval
;
2116 MonoTypeEnum simple_type
;
2119 if ((p
-buffer
) + 10 >= *buflen
) {
2122 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2123 p
= newbuf
+ (p
-buffer
);
2127 argval
= (const char*)mono_object_get_data (arg
);
2128 simple_type
= type
->type
;
2130 switch (simple_type
) {
2131 case MONO_TYPE_BOOLEAN
:
2136 case MONO_TYPE_CHAR
:
2139 swap_with_size (p
, argval
, 2, 1);
2145 swap_with_size (p
, argval
, 4, 1);
2149 swap_with_size (p
, argval
, 8, 1);
2154 swap_with_size (p
, argval
, 8, 1);
2157 case MONO_TYPE_VALUETYPE
:
2158 if (type
->data
.klass
->enumtype
) {
2159 simple_type
= mono_class_enum_basetype_internal (type
->data
.klass
)->type
;
2162 g_warning ("generic valutype %s not handled in custom attr value decoding", type
->data
.klass
->name
);
2165 case MONO_TYPE_STRING
: {
2172 str
= mono_string_to_utf8_checked_internal ((MonoString
*)arg
, error
);
2173 return_if_nok (error
);
2174 slen
= strlen (str
);
2175 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2179 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2180 p
= newbuf
+ (p
-buffer
);
2183 mono_metadata_encode_value (slen
, p
, &p
);
2184 memcpy (p
, str
, slen
);
2189 case MONO_TYPE_CLASS
: {
2198 arg_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)arg
, error
);
2199 return_if_nok (error
);
2201 str
= type_get_qualified_name (arg_type
, NULL
);
2202 slen
= strlen (str
);
2203 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2207 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2208 p
= newbuf
+ (p
-buffer
);
2211 mono_metadata_encode_value (slen
, p
, &p
);
2212 memcpy (p
, str
, slen
);
2217 case MONO_TYPE_SZARRAY
: {
2219 MonoClass
*eclass
, *arg_eclass
;
2222 *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff;
2225 len
= mono_array_length_internal ((MonoArray
*)arg
);
2227 *p
++ = (len
>> 8) & 0xff;
2228 *p
++ = (len
>> 16) & 0xff;
2229 *p
++ = (len
>> 24) & 0xff;
2231 *retbuffer
= buffer
;
2232 eclass
= type
->data
.klass
;
2233 arg_eclass
= mono_object_class (arg
)->element_class
;
2236 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2237 eclass
= mono_defaults
.object_class
;
2239 if (eclass
== mono_defaults
.object_class
&& arg_eclass
->valuetype
) {
2240 char *elptr
= mono_array_addr_internal ((MonoArray
*)arg
, char, 0);
2241 int elsize
= mono_class_array_element_size (arg_eclass
);
2242 for (i
= 0; i
< len
; ++i
) {
2243 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (arg_eclass
), NULL
, elptr
, error
);
2244 return_if_nok (error
);
2247 } else if (eclass
->valuetype
&& arg_eclass
->valuetype
) {
2248 char *elptr
= mono_array_addr_internal ((MonoArray
*)arg
, char, 0);
2249 int elsize
= mono_class_array_element_size (eclass
);
2250 for (i
= 0; i
< len
; ++i
) {
2251 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, m_class_get_byval_arg (eclass
), NULL
, elptr
, error
);
2252 return_if_nok (error
);
2256 for (i
= 0; i
< len
; ++i
) {
2257 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
);
2258 return_if_nok (error
);
2263 case MONO_TYPE_OBJECT
: {
2269 * The parameter type is 'object' but the type of the actual
2270 * argument is not. So we have to add type information to the blob
2271 * too. This is completely undocumented in the spec.
2275 *p
++ = MONO_TYPE_STRING
; // It's same hack as MS uses
2280 klass
= mono_object_class (arg
);
2282 if (mono_object_isinst_checked (arg
, mono_defaults
.systemtype_class
, error
)) {
2286 return_if_nok (error
);
2289 MonoType
*klass_byval_arg
= m_class_get_byval_arg (klass
);
2290 if (klass
->enumtype
) {
2292 } else if (klass
== mono_defaults
.string_class
) {
2293 simple_type
= MONO_TYPE_STRING
;
2296 } else if (klass
->rank
== 1) {
2298 if (m_class_get_byval_arg (m_class_get_element_class (klass
))->type
== MONO_TYPE_OBJECT
)
2299 /* See Partition II, Appendix B3 */
2302 *p
++ = m_class_get_byval_arg (m_class_get_element_class (klass
))->type
;
2303 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, klass_byval_arg
, arg
, NULL
, error
);
2304 return_if_nok (error
);
2306 } else if (klass_byval_arg
->type
>= MONO_TYPE_BOOLEAN
&& klass_byval_arg
->type
<= MONO_TYPE_R8
) {
2307 *p
++ = simple_type
= klass_byval_arg
->type
;
2310 g_error ("unhandled type in custom attr");
2312 str
= type_get_qualified_name (m_class_get_byval_arg (klass
), NULL
);
2313 slen
= strlen (str
);
2314 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2318 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2319 p
= newbuf
+ (p
-buffer
);
2322 mono_metadata_encode_value (slen
, p
, &p
);
2323 memcpy (p
, str
, slen
);
2326 simple_type
= mono_class_enum_basetype_internal (klass
)->type
;
2330 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type
);
2333 *retbuffer
= buffer
;
2337 encode_field_or_prop_type (MonoType
*type
, char *p
, char **retp
)
2339 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2340 char *str
= type_get_qualified_name (type
, NULL
);
2341 int slen
= strlen (str
);
2345 * This seems to be optional...
2348 mono_metadata_encode_value (slen
, p
, &p
);
2349 memcpy (p
, str
, slen
);
2352 } else if (type
->type
== MONO_TYPE_OBJECT
) {
2354 } else if (type
->type
== MONO_TYPE_CLASS
) {
2355 /* it should be a type: encode_cattr_value () has the check */
2358 mono_metadata_encode_value (type
->type
, p
, &p
);
2359 if (type
->type
== MONO_TYPE_SZARRAY
)
2360 /* See the examples in Partition VI, Annex B */
2361 encode_field_or_prop_type (m_class_get_byval_arg (type
->data
.klass
), p
, &p
);
2367 #ifndef DISABLE_REFLECTION_EMIT
2369 encode_named_val (MonoReflectionAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, char *name
, MonoObject
*value
, MonoError
*error
)
2375 /* Preallocate a large enough buffer */
2376 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2377 char *str
= type_get_qualified_name (type
, NULL
);
2380 } else if (type
->type
== MONO_TYPE_SZARRAY
&& type
->data
.klass
->enumtype
) {
2381 char *str
= type_get_qualified_name (m_class_get_byval_arg (type
->data
.klass
), NULL
);
2387 len
+= strlen (name
);
2389 if ((p
-buffer
) + 20 + len
>= *buflen
) {
2393 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2394 p
= newbuf
+ (p
-buffer
);
2398 encode_field_or_prop_type (type
, p
, &p
);
2400 len
= strlen (name
);
2401 mono_metadata_encode_value (len
, p
, &p
);
2402 memcpy (p
, name
, len
);
2404 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, buflen
, type
, value
, NULL
, error
);
2405 return_if_nok (error
);
2407 *retbuffer
= buffer
;
2411 * mono_reflection_get_custom_attrs_blob:
2412 * \param ctor custom attribute constructor
2413 * \param ctorArgs arguments o the constructor
2417 * \param fieldValues
2418 * Creates the blob of data that needs to be saved in the metadata and that represents
2419 * the custom attributed described by \p ctor, \p ctorArgs etc.
2420 * \returns a \c Byte array representing the blob of data.
2423 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
2426 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, error
);
2427 mono_error_cleanup (error
);
2432 * mono_reflection_get_custom_attrs_blob_checked:
2433 * \param ctor custom attribute constructor
2434 * \param ctorArgs arguments o the constructor
2438 * \param fieldValues
2439 * \param error set on error
2440 * Creates the blob of data that needs to be saved in the metadata and that represents
2441 * the custom attributed described by \p ctor, \p ctorArgs etc.
2442 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2445 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
, MonoError
*error
)
2447 MonoArray
*result
= NULL
;
2448 MonoMethodSignature
*sig
;
2455 if (strcmp (ctor
->vtable
->klass
->name
, "MonoCMethod")) {
2456 /* sig is freed later so allocate it in the heap */
2457 sig
= ctor_builder_to_signature_raw (NULL
, (MonoReflectionCtorBuilder
*)ctor
, error
); /* FIXME use handles */
2458 if (!is_ok (error
)) {
2463 sig
= mono_method_signature_internal (((MonoReflectionMethod
*)ctor
)->method
);
2466 g_assert (mono_array_length_internal (ctorArgs
) == sig
->param_count
);
2468 p
= buffer
= (char *)g_malloc (buflen
);
2469 /* write the prolog */
2472 for (i
= 0; i
< sig
->param_count
; ++i
) {
2473 arg
= mono_array_get_internal (ctorArgs
, MonoObject
*, i
);
2474 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, &buflen
, sig
->params
[i
], arg
, NULL
, error
);
2475 goto_if_nok (error
, leave
);
2479 i
+= mono_array_length_internal (properties
);
2481 i
+= mono_array_length_internal (fields
);
2483 *p
++ = (i
>> 8) & 0xff;
2486 for (i
= 0; i
< mono_array_length_internal (properties
); ++i
) {
2490 prop
= (MonoObject
*)mono_array_get_internal (properties
, gpointer
, i
);
2491 get_prop_name_and_type (prop
, &pname
, &ptype
, error
);
2492 goto_if_nok (error
, leave
);
2493 *p
++ = 0x54; /* PROPERTY signature */
2494 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ptype
, pname
, (MonoObject
*)mono_array_get_internal (propValues
, gpointer
, i
), error
);
2496 goto_if_nok (error
, leave
);
2502 for (i
= 0; i
< mono_array_length_internal (fields
); ++i
) {
2506 field
= (MonoObject
*)mono_array_get_internal (fields
, gpointer
, i
);
2507 get_field_name_and_type (field
, &fname
, &ftype
, error
);
2508 goto_if_nok (error
, leave
);
2509 *p
++ = 0x53; /* FIELD signature */
2510 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ftype
, fname
, (MonoObject
*)mono_array_get_internal (fieldValues
, gpointer
, i
), error
);
2512 goto_if_nok (error
, leave
);
2516 g_assert (p
- buffer
<= buflen
);
2517 buflen
= p
- buffer
;
2518 result
= mono_array_new_checked (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
2519 goto_if_nok (error
, leave
);
2520 p
= mono_array_addr_internal (result
, char, 0);
2521 memcpy (p
, buffer
, buflen
);
2524 if (strcmp (ctor
->vtable
->klass
->name
, "MonoCMethod"))
2530 reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
)
2534 mono_loader_lock ();
2536 MonoType
*parent_type
;
2537 MonoType
*child_type
;
2538 GHashTableIter iter
;
2540 g_hash_table_iter_init (&iter
, unparented
);
2542 while (g_hash_table_iter_next (&iter
, (gpointer
*) &child_type
, (gpointer
*) &parent_type
)) {
2543 MonoClass
*child_class
= mono_class_from_mono_type_internal (child_type
);
2544 if (parent_type
!= NULL
) {
2545 MonoClass
*parent_class
= mono_class_from_mono_type_internal (parent_type
);
2546 child_class
->parent
= NULL
;
2547 /* fool mono_class_setup_parent */
2548 child_class
->supertypes
= NULL
;
2549 mono_class_setup_parent (child_class
, parent_class
);
2550 } else if (strcmp (child_class
->name
, "Object") == 0 && strcmp (child_class
->name_space
, "System") == 0) {
2551 const char *old_n
= child_class
->name
;
2552 /* trick to get relative numbering right when compiling corlib */
2553 child_class
->name
= "BuildingObject";
2554 mono_class_setup_parent (child_class
, mono_defaults
.object_class
);
2555 child_class
->name
= old_n
;
2557 mono_class_setup_mono_type (child_class
);
2558 mono_class_setup_supertypes (child_class
);
2561 mono_loader_unlock ();
2562 return is_ok (error
);
2566 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2568 HANDLE_FUNCTION_ENTER ();
2571 mono_loader_lock ();
2573 gint32 entering_state
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_tb
), state
);
2574 if (entering_state
!= MonoTypeBuilderNew
) {
2575 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
));
2579 MONO_HANDLE_SETVAL (ref_tb
, state
, MonoTypeBuilderState
, MonoTypeBuilderEntered
);
2580 MonoReflectionModuleBuilderHandle module_ref
;
2581 module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2582 GHashTable
*unparented_classes
;
2583 unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
2585 // If this type is already setup, exit. We'll fix the parenting later
2587 type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2591 MonoReflectionModuleBuilderHandle ref_module
;
2592 ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2593 MonoDynamicImage
*dynamic_image
;
2594 dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
2596 MonoStringHandle ref_name
;
2597 ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, name
);
2598 MonoStringHandle ref_nspace
;
2599 ref_nspace
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, nspace
);
2602 table_idx
= MONO_HANDLE_GETVAL (ref_tb
, table_idx
);
2604 * The size calculation here warrants some explaining.
2605 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2606 * meaning we need to alloc enough space to morth a def into a gtd.
2609 klass
= (MonoClass
*)mono_image_alloc0 (&dynamic_image
->image
, MAX (sizeof (MonoClassDef
), sizeof (MonoClassGtd
)));
2610 klass
->class_kind
= MONO_CLASS_DEF
;
2612 klass
->image
= &dynamic_image
->image
;
2614 klass
->inited
= 1; /* we lie to the runtime */
2615 klass
->name
= mono_string_to_utf8_image (klass
->image
, ref_name
, error
);
2616 goto_if_nok (error
, leave
);
2617 klass
->name_space
= mono_string_to_utf8_image (klass
->image
, ref_nspace
, error
);
2618 goto_if_nok (error
, leave
);
2619 klass
->type_token
= MONO_TOKEN_TYPE_DEF
| table_idx
;
2620 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
2622 MONO_PROFILER_RAISE (class_loading
, (klass
));
2624 klass
->element_class
= klass
;
2626 g_assert (!mono_class_has_ref_info (klass
));
2627 mono_class_set_ref_info (klass
, MONO_HANDLE_CAST (MonoObject
, ref_tb
));
2629 MonoReflectionTypeHandle ref_nesting_type
;
2630 ref_nesting_type
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_tb
, nesting_type
);
2631 /* Put into cache so mono_class_get_checked () will find it.
2632 Skip nested types as those should not be available on the global scope. */
2633 if (MONO_HANDLE_IS_NULL (ref_nesting_type
))
2634 mono_image_add_to_name_cache (klass
->image
, klass
->name_space
, klass
->name
, table_idx
);
2637 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2638 by performing a mono_class_get which does the full resolution.
2640 Working around this semantics would require us to write a lot of code for no clear advantage.
2642 mono_image_append_class_to_reflection_info_set (klass
);
2644 mono_dynamic_image_register_token (dynamic_image
, MONO_TOKEN_TYPE_DEF
| table_idx
, MONO_HANDLE_CAST (MonoObject
, ref_tb
), MONO_DYN_IMAGE_TOK_NEW
);
2646 if ((!strcmp (klass
->name
, "ValueType") && !strcmp (klass
->name_space
, "System")) ||
2647 (!strcmp (klass
->name
, "Object") && !strcmp (klass
->name_space
, "System")) ||
2648 (!strcmp (klass
->name
, "Enum") && !strcmp (klass
->name_space
, "System"))) {
2649 klass
->instance_size
= MONO_ABI_SIZEOF (MonoObject
);
2650 klass
->size_inited
= 1;
2651 mono_class_setup_vtable_general (klass
, NULL
, 0, NULL
);
2654 mono_class_setup_mono_type (klass
);
2657 * FIXME: handle interfaces.
2659 MonoReflectionTypeHandle ref_tb_type
;
2660 ref_tb_type
= MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
);
2661 MONO_HANDLE_SETVAL (ref_tb_type
, type
, MonoType
*, m_class_get_byval_arg (klass
));
2662 MONO_HANDLE_SETVAL (ref_tb
, state
, gint32
, MonoTypeBuilderFinished
);
2664 reflection_init_generic_class (ref_tb
, error
);
2665 goto_if_nok (error
, leave
);
2667 // Do here so that the search inside of the parent can see the above type that's been set.
2668 MonoReflectionTypeHandle ref_parent
;
2669 ref_parent
= MONO_HANDLE_CAST (MonoReflectionType
, MONO_HANDLE_NEW_GET (MonoObject
, ref_tb
, parent
));
2670 MonoType
*parent_type
;
2672 if (!MONO_HANDLE_IS_NULL (ref_parent
)) {
2673 MonoClass
*parent_klass
= mono_handle_class (ref_parent
);
2674 gboolean recursive_init
= TRUE
;
2676 if (is_sre_type_builder (parent_klass
)) {
2677 MonoTypeBuilderState parent_state
= (MonoTypeBuilderState
)MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_parent
), state
);
2679 if (parent_state
!= MonoTypeBuilderNew
) {
2680 // Initialize types reachable from parent recursively
2681 // We'll fix the type hierarchy later
2682 recursive_init
= FALSE
;
2686 if (recursive_init
) {
2687 // If we haven't encountered a cycle, force the creation of ref_parent's type
2688 mono_reflection_type_handle_mono_type (ref_parent
, error
);
2689 goto_if_nok (error
, leave
);
2692 parent_type
= MONO_HANDLE_GETVAL (ref_parent
, type
);
2694 // If we failed to create the parent, fail the child
2699 // Push the child type and parent type to process later
2700 // Note: parent_type may be null.
2701 g_assert (!g_hash_table_lookup (unparented_classes
, m_class_get_byval_arg (klass
)));
2702 g_hash_table_insert (unparented_classes
, m_class_get_byval_arg (klass
), parent_type
);
2704 if (!MONO_HANDLE_IS_NULL (ref_nesting_type
)) {
2705 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_nesting_type
), error
))
2708 MonoType
*nesting_type
= mono_reflection_type_handle_mono_type (ref_nesting_type
, error
);
2709 goto_if_nok (error
, leave
);
2710 klass
->nested_in
= mono_class_from_mono_type_internal (nesting_type
);
2713 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2715 MONO_PROFILER_RAISE (class_loaded
, (klass
));
2718 mono_loader_unlock ();
2719 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2723 * reflection_init_generic_class:
2724 * @tb: a TypeBuilder object
2725 * @error: set on error
2727 * Creates the generic class after all generic parameters have been added.
2728 * On success returns TRUE, on failure returns FALSE and sets @error.
2730 * This assumes that reflection_setup_internal_class has already set up
2734 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2736 HANDLE_FUNCTION_ENTER ();
2740 MonoTypeBuilderState ref_state
= (MonoTypeBuilderState
)MONO_HANDLE_GETVAL (ref_tb
, state
);
2741 g_assert (ref_state
== MonoTypeBuilderFinished
);
2743 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2744 MonoClass
*klass
= mono_class_from_mono_type_internal (type
);
2746 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
2747 int count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
2752 if (mono_class_try_get_generic_container (klass
) != NULL
)
2753 goto leave
; /* already setup */
2755 MonoGenericContainer
*generic_container
;
2756 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2758 generic_container
->owner
.klass
= klass
;
2759 generic_container
->type_argc
= count
;
2760 generic_container
->type_params
= (MonoGenericParamFull
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericParamFull
) * count
);
2762 klass
->class_kind
= MONO_CLASS_GTD
;
2763 mono_class_set_generic_container (klass
, generic_container
);
2766 MonoReflectionGenericParamHandle ref_gparam
;
2767 ref_gparam
= MONO_HANDLE_NEW (MonoReflectionGenericParam
, NULL
);
2768 for (int i
= 0; i
< count
; i
++) {
2769 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
2770 MonoType
*param_type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), error
);
2771 goto_if_nok (error
, leave
);
2772 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) param_type
->data
.generic_param
;
2773 generic_container
->type_params
[i
] = *param
;
2774 /*Make sure we are a diferent type instance */
2775 generic_container
->type_params
[i
].owner
= generic_container
;
2776 generic_container
->type_params
[i
].info
.pklass
= NULL
;
2777 generic_container
->type_params
[i
].info
.flags
= MONO_HANDLE_GETVAL (ref_gparam
, attrs
);
2779 g_assert (generic_container
->type_params
[i
].owner
);
2782 generic_container
->context
.class_inst
= mono_get_shared_generic_inst (generic_container
);
2783 MonoGenericContext
* context
;
2784 context
= &generic_container
->context
;
2785 MonoType
*canonical_inst
;
2786 canonical_inst
= &((MonoClassGtd
*)klass
)->canonical_inst
;
2787 canonical_inst
->type
= MONO_TYPE_GENERICINST
;
2788 canonical_inst
->data
.generic_class
= mono_metadata_lookup_generic_class (klass
, context
->class_inst
, FALSE
);
2791 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2794 static MonoMarshalSpec
*
2795 mono_marshal_spec_from_builder (MonoImage
*image
, MonoAssembly
*assembly
,
2796 MonoReflectionMarshal
*minfo
, MonoError
*error
)
2798 MonoMarshalSpec
*res
;
2802 res
= image_g_new0 (image
, MonoMarshalSpec
, 1);
2803 res
->native
= (MonoMarshalNative
)minfo
->type
;
2805 switch (minfo
->type
) {
2806 case MONO_NATIVE_LPARRAY
:
2807 res
->data
.array_data
.elem_type
= (MonoMarshalNative
)minfo
->eltype
;
2808 if (minfo
->has_size
) {
2809 res
->data
.array_data
.param_num
= minfo
->param_num
;
2810 res
->data
.array_data
.num_elem
= minfo
->count
;
2811 res
->data
.array_data
.elem_mult
= minfo
->param_num
== -1 ? 0 : 1;
2814 res
->data
.array_data
.param_num
= -1;
2815 res
->data
.array_data
.num_elem
= -1;
2816 res
->data
.array_data
.elem_mult
= -1;
2820 case MONO_NATIVE_BYVALTSTR
:
2821 case MONO_NATIVE_BYVALARRAY
:
2822 res
->data
.array_data
.num_elem
= minfo
->count
;
2825 case MONO_NATIVE_CUSTOM
:
2826 if (minfo
->marshaltyperef
) {
2827 MonoType
*marshaltyperef
= mono_reflection_type_get_handle ((MonoReflectionType
*)minfo
->marshaltyperef
, error
);
2828 if (!is_ok (error
)) {
2829 image_g_free (image
, res
);
2832 res
->data
.custom_data
.custom_name
=
2833 type_get_fully_qualified_name (marshaltyperef
);
2835 if (minfo
->mcookie
) {
2836 res
->data
.custom_data
.cookie
= mono_string_to_utf8_checked_internal (minfo
->mcookie
, error
);
2837 if (!is_ok (error
)) {
2838 image_g_free (image
, res
);
2850 #endif /* !DISABLE_REFLECTION_EMIT */
2852 MonoReflectionMarshalAsAttributeHandle
2853 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain
*domain
, MonoClass
*klass
,
2854 MonoMarshalSpec
*spec
, MonoError
*error
)
2858 MonoReflectionMarshalAsAttributeHandle minfo
= MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, mono_object_new_handle (domain
, mono_class_get_marshal_as_attribute_class (), error
));
2859 goto_if_nok (error
, fail
);
2861 utype
= spec
->native
;
2862 MONO_HANDLE_SETVAL (minfo
, utype
, guint32
, utype
);
2865 case MONO_NATIVE_LPARRAY
:
2866 MONO_HANDLE_SETVAL (minfo
, array_subtype
, guint32
, spec
->data
.array_data
.elem_type
);
2867 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2868 if (spec
->data
.array_data
.param_num
!= -1)
2869 MONO_HANDLE_SETVAL (minfo
, size_param_index
, gint16
, spec
->data
.array_data
.param_num
);
2872 case MONO_NATIVE_BYVALTSTR
:
2873 case MONO_NATIVE_BYVALARRAY
:
2874 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2877 case MONO_NATIVE_CUSTOM
:
2878 if (spec
->data
.custom_data
.custom_name
) {
2879 MonoType
*mtype
= mono_reflection_type_from_name_checked (spec
->data
.custom_data
.custom_name
, klass
->image
, error
);
2880 goto_if_nok (error
, fail
);
2883 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, mtype
, error
);
2884 goto_if_nok (error
, fail
);
2886 MONO_HANDLE_SET (minfo
, marshal_type_ref
, rt
);
2889 MonoStringHandle custom_name
= mono_string_new_handle (domain
, spec
->data
.custom_data
.custom_name
, error
);
2890 goto_if_nok (error
, fail
);
2891 MONO_HANDLE_SET (minfo
, marshal_type
, custom_name
);
2893 if (spec
->data
.custom_data
.cookie
) {
2894 MonoStringHandle cookie
= mono_string_new_handle (domain
, spec
->data
.custom_data
.cookie
, error
);
2895 goto_if_nok (error
, fail
);
2896 MONO_HANDLE_SET (minfo
, marshal_cookie
, cookie
);
2906 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, NULL
);
2909 #ifndef DISABLE_REFLECTION_EMIT
2911 reflection_methodbuilder_to_mono_method (MonoClass
*klass
,
2912 ReflectionMethodBuilder
*rmb
,
2913 MonoMethodSignature
*sig
,
2917 MonoMethodWrapper
*wrapperm
;
2918 MonoMarshalSpec
**specs
= NULL
;
2919 MonoReflectionMethodAux
*method_aux
;
2926 * Methods created using a MethodBuilder should have their memory allocated
2927 * inside the image mempool, while dynamic methods should have their memory
2930 dynamic
= rmb
->refs
!= NULL
;
2931 image
= dynamic
? NULL
: klass
->image
;
2934 g_assert (!mono_class_is_ginst (klass
));
2936 mono_loader_lock ();
2938 if ((rmb
->attrs
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
2939 (rmb
->iattrs
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
2940 m
= (MonoMethod
*)image_g_new0 (image
, MonoMethodPInvoke
, 1);
2942 m
= (MonoMethod
*)image_g_new0 (image
, MonoDynamicMethod
, 1);
2944 wrapperm
= (MonoMethodWrapper
*)m
;
2946 m
->dynamic
= dynamic
;
2948 m
->flags
= rmb
->attrs
;
2949 m
->iflags
= rmb
->iattrs
;
2950 m
->name
= string_to_utf8_image_raw (image
, rmb
->name
, error
);
2951 goto_if_nok (error
, fail
);
2954 m
->sre_method
= TRUE
;
2955 m
->skip_visibility
= rmb
->skip_visibility
;
2957 m
->token
= MONO_TOKEN_METHOD_DEF
| (*rmb
->table_idx
);
2959 if (m
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) {
2960 if (klass
== mono_defaults
.string_class
&& !strcmp (m
->name
, ".ctor"))
2963 m
->signature
->pinvoke
= 1;
2964 } else if (m
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) {
2965 m
->signature
->pinvoke
= 1;
2967 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2969 method_aux
->dllentry
= rmb
->dllentry
? string_to_utf8_image_raw (image
, rmb
->dllentry
, error
) : image_strdup (image
, m
->name
);
2970 mono_error_assert_ok (error
);
2971 method_aux
->dll
= string_to_utf8_image_raw (image
, rmb
->dll
, error
);
2972 mono_error_assert_ok (error
);
2974 ((MonoMethodPInvoke
*)m
)->piflags
= (rmb
->native_cc
<< 8) | (rmb
->charset
? (rmb
->charset
- 1) * 2 : 0) | rmb
->extra_flags
;
2976 if (image_is_dynamic (klass
->image
))
2977 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
2981 } else if (!(m
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) &&
2982 !(m
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
)) {
2983 MonoMethodHeader
*header
;
2985 gint32 max_stack
, i
;
2986 gint32 num_locals
= 0;
2987 gint32 num_clauses
= 0;
2991 code
= mono_array_addr_internal (rmb
->ilgen
->code
, guint8
, 0);
2992 code_size
= rmb
->ilgen
->code_len
;
2993 max_stack
= rmb
->ilgen
->max_stack
;
2994 num_locals
= rmb
->ilgen
->locals
? mono_array_length_internal (rmb
->ilgen
->locals
) : 0;
2995 if (rmb
->ilgen
->ex_handlers
)
2996 num_clauses
= mono_reflection_method_count_clauses (rmb
->ilgen
);
2999 code
= mono_array_addr_internal (rmb
->code
, guint8
, 0);
3000 code_size
= mono_array_length_internal (rmb
->code
);
3001 /* we probably need to run a verifier on the code... */
3011 header
= (MonoMethodHeader
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_HEADER
+ num_locals
* sizeof (MonoType
*));
3012 header
->code_size
= code_size
;
3013 header
->code
= (const unsigned char *)image_g_malloc (image
, code_size
);
3014 memcpy ((char*)header
->code
, code
, code_size
);
3015 header
->max_stack
= max_stack
;
3016 header
->init_locals
= rmb
->init_locals
;
3017 header
->num_locals
= num_locals
;
3019 for (i
= 0; i
< num_locals
; ++i
) {
3020 MonoReflectionLocalBuilder
*lb
=
3021 mono_array_get_internal (rmb
->ilgen
->locals
, MonoReflectionLocalBuilder
*, i
);
3023 header
->locals
[i
] = image_g_new0 (image
, MonoType
, 1);
3024 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)lb
->type
, error
);
3025 mono_error_assert_ok (error
);
3026 memcpy (header
->locals
[i
], type
, mono_sizeof_type (type
));
3029 header
->num_clauses
= num_clauses
;
3031 header
->clauses
= method_encode_clauses (image
, (MonoDynamicImage
*)klass
->image
,
3032 rmb
->ilgen
, num_clauses
, error
);
3033 mono_error_assert_ok (error
);
3036 wrapperm
->header
= header
;
3037 MonoDynamicMethod
*dm
= (MonoDynamicMethod
*)wrapperm
;
3038 dm
->assembly
= klass
->image
->assembly
;
3041 if (rmb
->generic_params
) {
3042 int count
= mono_array_length_internal (rmb
->generic_params
);
3043 MonoGenericContainer
*container
;
3045 container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
3046 container
->is_method
= TRUE
;
3047 container
->is_anonymous
= FALSE
;
3048 container
->type_argc
= count
;
3049 container
->type_params
= image_g_new0 (image
, MonoGenericParamFull
, count
);
3050 container
->owner
.method
= m
;
3052 m
->is_generic
= TRUE
;
3053 mono_method_set_generic_container (m
, container
);
3055 for (i
= 0; i
< count
; i
++) {
3056 MonoReflectionGenericParam
*gp
=
3057 mono_array_get_internal (rmb
->generic_params
, MonoReflectionGenericParam
*, i
);
3058 MonoType
*gp_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gp
, error
);
3059 mono_error_assert_ok (error
);
3060 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) gp_type
->data
.generic_param
;
3061 container
->type_params
[i
] = *param
;
3062 container
->type_params
[i
].owner
= container
;
3064 gp
->type
.type
->data
.generic_param
= (MonoGenericParam
*)&container
->type_params
[i
];
3066 MonoClass
*gklass
= mono_class_from_mono_type_internal (gp_type
);
3067 gklass
->wastypebuilder
= TRUE
;
3071 * The method signature might have pointers to generic parameters that belong to other methods.
3072 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
3073 * generic parameters.
3075 for (i
= 0; i
< m
->signature
->param_count
; ++i
) {
3076 MonoType
*t
= m
->signature
->params
[i
];
3077 if (t
->type
== MONO_TYPE_MVAR
) {
3078 MonoGenericParam
*gparam
= t
->data
.generic_param
;
3079 if (gparam
->num
< count
) {
3080 m
->signature
->params
[i
] = mono_metadata_type_dup (image
, m
->signature
->params
[i
]);
3081 m
->signature
->params
[i
]->data
.generic_param
= mono_generic_container_get_param (container
, gparam
->num
);
3087 if (mono_class_is_gtd (klass
)) {
3088 container
->parent
= mono_class_get_generic_container (klass
);
3089 container
->context
.class_inst
= mono_class_get_generic_container (klass
)->context
.class_inst
;
3091 container
->context
.method_inst
= mono_get_shared_generic_inst (container
);
3095 MonoMethodWrapper
*mw
= (MonoMethodWrapper
*)m
;
3099 m
->wrapper_type
= MONO_WRAPPER_DYNAMIC_METHOD
;
3101 mw
->method_data
= data
= image_g_new (image
, gpointer
, rmb
->nrefs
+ 1);
3102 data
[0] = GUINT_TO_POINTER (rmb
->nrefs
);
3103 for (i
= 0; i
< rmb
->nrefs
; ++i
)
3104 data
[i
+ 1] = rmb
->refs
[i
];
3109 /* Parameter info */
3112 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3113 method_aux
->param_names
= image_g_new0 (image
, char *, mono_method_signature_internal (m
)->param_count
+ 1);
3114 for (i
= 0; i
<= m
->signature
->param_count
; ++i
) {
3115 MonoReflectionParamBuilder
*pb
;
3116 if ((pb
= mono_array_get_internal (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3117 if ((i
> 0) && (pb
->attrs
)) {
3118 /* Make a copy since it might point to a shared type structure */
3119 m
->signature
->params
[i
- 1] = mono_metadata_type_dup (klass
->image
, m
->signature
->params
[i
- 1]);
3120 m
->signature
->params
[i
- 1]->attrs
= pb
->attrs
;
3123 if (pb
->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
) {
3124 MonoDynamicImage
*assembly
;
3126 MonoTypeEnum def_type
;
3130 if (!method_aux
->param_defaults
) {
3131 method_aux
->param_defaults
= image_g_new0 (image
, guint8
*, m
->signature
->param_count
+ 1);
3132 method_aux
->param_default_types
= image_g_new0 (image
, guint32
, m
->signature
->param_count
+ 1);
3134 assembly
= (MonoDynamicImage
*)klass
->image
;
3135 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &def_type
);
3136 /* Copy the data from the blob since it might get realloc-ed */
3137 p
= assembly
->blob
.data
+ idx
;
3138 len
= mono_metadata_decode_blob_size (p
, &p2
);
3140 method_aux
->param_defaults
[i
] = (uint8_t *)image_g_malloc (image
, len
);
3141 method_aux
->param_default_types
[i
] = def_type
;
3142 memcpy ((gpointer
)method_aux
->param_defaults
[i
], p
, len
);
3146 method_aux
->param_names
[i
] = string_to_utf8_image_raw (image
, pb
->name
, error
);
3147 mono_error_assert_ok (error
);
3150 if (!method_aux
->param_cattr
)
3151 method_aux
->param_cattr
= image_g_new0 (image
, MonoCustomAttrInfo
*, m
->signature
->param_count
+ 1);
3152 method_aux
->param_cattr
[i
] = mono_custom_attrs_from_builders (image
, klass
->image
, pb
->cattrs
);
3158 /* Parameter marshalling */
3160 for (i
= 0; i
< mono_array_length_internal (rmb
->pinfo
); ++i
) {
3161 MonoReflectionParamBuilder
*pb
;
3162 if ((pb
= mono_array_get_internal (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3163 if (pb
->marshal_info
) {
3165 specs
= image_g_new0 (image
, MonoMarshalSpec
*, sig
->param_count
+ 1);
3166 specs
[pb
->position
] =
3167 mono_marshal_spec_from_builder (image
, klass
->image
->assembly
, pb
->marshal_info
, error
);
3168 goto_if_nok (error
, fail
);
3172 if (specs
!= NULL
) {
3174 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3175 method_aux
->param_marshall
= specs
;
3178 if (image_is_dynamic (klass
->image
) && method_aux
)
3179 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
3182 mono_loader_unlock ();
3183 if (!m
) // FIXME: This leaks if image is not NULL.
3184 image_g_free (image
, specs
);
3193 ctorbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionCtorBuilder
* mb
, MonoError
*error
)
3195 ReflectionMethodBuilder rmb
;
3196 MonoMethodSignature
*sig
;
3198 mono_loader_lock ();
3200 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb
, mb
, error
)) {
3201 mono_loader_unlock ();
3205 g_assert (klass
->image
!= NULL
);
3206 sig
= ctor_builder_to_signature_raw (klass
->image
, mb
, error
); /* FIXME use handles */
3207 mono_loader_unlock ();
3208 return_val_if_nok (error
, NULL
);
3210 mb
->mhandle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3211 return_val_if_nok (error
, NULL
);
3212 mono_save_custom_attrs (klass
->image
, mb
->mhandle
, mb
->cattrs
);
3214 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
) {
3215 /* ilgen is no longer needed */
3223 methodbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionMethodBuilderHandle ref_mb
, MonoError
*error
)
3225 ReflectionMethodBuilder rmb
;
3226 MonoMethodSignature
*sig
;
3230 mono_loader_lock ();
3232 MonoReflectionMethodBuilder
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME use handles */
3233 if (!mono_reflection_methodbuilder_from_method_builder (&rmb
, mb
, error
)) {
3234 mono_loader_unlock ();
3238 g_assert (klass
->image
!= NULL
);
3239 sig
= method_builder_to_signature (klass
->image
, ref_mb
, error
);
3240 mono_loader_unlock ();
3241 return_val_if_nok (error
, NULL
);
3243 MonoMethod
*method
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3244 return_val_if_nok (error
, NULL
);
3245 MONO_HANDLE_SETVAL (ref_mb
, mhandle
, MonoMethod
*, method
);
3246 mono_save_custom_attrs (klass
->image
, method
, mb
->cattrs
);
3248 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
)
3249 /* ilgen is no longer needed */
3255 methodbuilder_to_mono_method_raw (MonoClass
*klass
, MonoReflectionMethodBuilder
* mb_raw
, MonoError
*error
)
3257 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3259 MONO_HANDLE_DCL (MonoReflectionMethodBuilder
, mb
);
3260 MonoMethod
*result
= methodbuilder_to_mono_method (klass
, mb
, error
);
3261 HANDLE_FUNCTION_RETURN_VAL (result
);
3266 #ifndef DISABLE_REFLECTION_EMIT
3269 * fix_partial_generic_class:
3270 * @klass: a generic instantiation MonoClass
3271 * @error: set on error
3273 * Assumes that the generic container of @klass has its vtable
3274 * initialized, and updates the parent class, interfaces, methods and
3275 * fields of @klass by inflating the types using the generic context.
3277 * On success returns TRUE, on failure returns FALSE and sets @error.
3281 fix_partial_generic_class (MonoClass
*klass
, MonoError
*error
)
3283 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3288 if (klass
->wastypebuilder
)
3291 if (klass
->parent
!= gklass
->parent
) {
3292 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
);
3293 if (mono_error_ok (error
)) {
3294 MonoClass
*parent
= mono_class_from_mono_type_internal (parent_type
);
3295 mono_metadata_free_type (parent_type
);
3296 if (parent
!= klass
->parent
) {
3297 /*fool mono_class_setup_parent*/
3298 klass
->supertypes
= NULL
;
3299 mono_class_setup_parent (klass
, parent
);
3302 if (gklass
->wastypebuilder
)
3303 klass
->wastypebuilder
= TRUE
;
3308 if (!mono_class_get_generic_class (klass
)->need_sync
)
3311 int mcount
= mono_class_get_method_count (klass
);
3312 int gmcount
= mono_class_get_method_count (gklass
);
3313 if (mcount
!= gmcount
) {
3314 mono_class_set_method_count (klass
, gmcount
);
3315 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * (gmcount
+ 1));
3317 for (i
= 0; i
< gmcount
; i
++) {
3318 klass
->methods
[i
] = mono_class_inflate_generic_method_full_checked (
3319 gklass
->methods
[i
], klass
, mono_class_get_context (klass
), error
);
3320 mono_error_assert_ok (error
);
3324 if (klass
->interface_count
&& klass
->interface_count
!= gklass
->interface_count
) {
3325 klass
->interface_count
= gklass
->interface_count
;
3326 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * gklass
->interface_count
);
3327 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3329 MonoClass
**gklass_interfaces
= m_class_get_interfaces (gklass
);
3330 for (i
= 0; i
< gklass
->interface_count
; ++i
) {
3331 MonoType
*iface_type
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (gklass_interfaces
[i
]), mono_class_get_context (klass
), error
);
3332 return_val_if_nok (error
, FALSE
);
3334 klass
->interfaces
[i
] = mono_class_from_mono_type_internal (iface_type
);
3335 mono_metadata_free_type (iface_type
);
3337 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3340 klass
->interfaces_inited
= 1;
3343 int fcount
= mono_class_get_field_count (klass
);
3344 int gfcount
= mono_class_get_field_count (gklass
);
3345 if (fcount
!= gfcount
) {
3346 mono_class_set_field_count (klass
, gfcount
);
3347 klass
->fields
= image_g_new0 (klass
->image
, MonoClassField
, gfcount
);
3349 for (i
= 0; i
< gfcount
; i
++) {
3350 klass
->fields
[i
] = gklass
->fields
[i
];
3351 klass
->fields
[i
].parent
= klass
;
3352 klass
->fields
[i
].type
= mono_class_inflate_generic_type_checked (gklass
->fields
[i
].type
, mono_class_get_context (klass
), error
);
3353 return_val_if_nok (error
, FALSE
);
3357 /*We can only finish with this klass once it's parent has as well*/
3358 if (gklass
->wastypebuilder
)
3359 klass
->wastypebuilder
= TRUE
;
3364 * ensure_generic_class_runtime_vtable:
3365 * @klass a generic class
3366 * @error set on error
3368 * Ensures that the generic container of @klass has a vtable and
3369 * returns TRUE on success. On error returns FALSE and sets @error.
3372 ensure_generic_class_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3374 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3378 if (!ensure_runtime_vtable (gklass
, error
))
3381 return fix_partial_generic_class (klass
, error
);
3385 * ensure_runtime_vtable:
3387 * @error set on error
3389 * Ensures that @klass has a vtable and returns TRUE on success. On
3390 * error returns FALSE and sets @error.
3393 ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3395 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3400 if (!image_is_dynamic (klass
->image
) || (!tb
&& !mono_class_is_ginst (klass
)) || klass
->wastypebuilder
)
3403 if (!ensure_runtime_vtable (klass
->parent
, error
))
3407 num
= tb
->ctors
? mono_array_length_internal (tb
->ctors
): 0;
3408 num
+= tb
->num_methods
;
3409 mono_class_set_method_count (klass
, num
);
3410 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * num
);
3411 num
= tb
->ctors
? mono_array_length_internal (tb
->ctors
): 0;
3412 for (i
= 0; i
< num
; ++i
) {
3413 MonoMethod
*ctor
= ctorbuilder_to_mono_method (klass
, mono_array_get_internal (tb
->ctors
, MonoReflectionCtorBuilder
*, i
), error
);
3416 klass
->methods
[i
] = ctor
;
3418 num
= tb
->num_methods
;
3420 for (i
= 0; i
< num
; ++i
) {
3421 MonoMethod
*meth
= methodbuilder_to_mono_method_raw (klass
, mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
), error
); /* FIXME use handles */
3424 klass
->methods
[j
++] = meth
;
3427 if (tb
->interfaces
) {
3428 klass
->interface_count
= mono_array_length_internal (tb
->interfaces
);
3429 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * klass
->interface_count
);
3430 for (i
= 0; i
< klass
->interface_count
; ++i
) {
3431 MonoType
*iface
= mono_type_array_get_and_resolve_raw (tb
->interfaces
, i
, error
); /* FIXME use handles */
3432 return_val_if_nok (error
, FALSE
);
3433 klass
->interfaces
[i
] = mono_class_from_mono_type_internal (iface
);
3434 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3437 klass
->interfaces_inited
= 1;
3439 } else if (mono_class_is_ginst (klass
)){
3440 if (!ensure_generic_class_runtime_vtable (klass
, error
)) {
3441 mono_class_set_type_load_failure (klass
, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error
));
3446 if (mono_class_is_interface (klass
) && !mono_class_is_ginst (klass
)) {
3448 int mcount
= mono_class_get_method_count (klass
);
3449 for (i
= 0; i
< mcount
; ++i
) {
3450 MonoMethod
*im
= klass
->methods
[i
];
3451 if (!(im
->flags
& METHOD_ATTRIBUTE_STATIC
))
3452 im
->slot
= slot_num
++;
3455 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3456 mono_class_setup_interface_offsets (klass
);
3457 mono_class_setup_interface_id (klass
);
3461 * The generic vtable is needed even if image->run is not set since some
3462 * runtime code like ves_icall_Type_GetMethodsByName depends on
3463 * method->slot being defined.
3467 * tb->methods could not be freed since it is used for determining
3468 * overrides during dynamic vtable construction.
3475 mono_reflection_method_get_handle (MonoObject
*method
, MonoError
*error
)
3478 MonoClass
*klass
= mono_object_class (method
);
3479 if (is_sr_mono_method (klass
)) {
3480 MonoReflectionMethod
*sr_method
= (MonoReflectionMethod
*)method
;
3481 return sr_method
->method
;
3483 if (is_sre_method_builder (klass
)) {
3484 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)method
;
3487 if (mono_is_sre_method_on_tb_inst (klass
)) {
3488 MonoClass
*handle_class
;
3490 MonoMethod
*result
= (MonoMethod
*)mono_reflection_resolve_object (NULL
, method
, &handle_class
, NULL
, error
);
3491 return_val_if_nok (error
, NULL
);
3496 g_error ("Can't handle methods of type %s:%s", klass
->name_space
, klass
->name
);
3501 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
3503 MonoReflectionTypeBuilder
*tb
;
3505 MonoReflectionMethod
*m
;
3511 g_assert (image_is_dynamic (klass
->image
));
3513 if (!mono_class_has_ref_info (klass
))
3516 tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3517 g_assert (strcmp (mono_object_class (tb
)->name
, "TypeBuilder") == 0);
3521 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3522 MonoReflectionMethodBuilder
*mb
=
3523 mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3524 if (mb
->override_methods
)
3525 onum
+= mono_array_length_internal (mb
->override_methods
);
3530 *overrides
= g_new0 (MonoMethod
*, onum
* 2);
3533 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3534 MonoReflectionMethodBuilder
*mb
=
3535 mono_array_get_internal (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3536 if (mb
->override_methods
) {
3537 for (j
= 0; j
< mono_array_length_internal (mb
->override_methods
); ++j
) {
3538 m
= mono_array_get_internal (mb
->override_methods
, MonoReflectionMethod
*, j
);
3540 (*overrides
) [onum
* 2] = mono_reflection_method_get_handle ((MonoObject
*)m
, error
);
3541 return_if_nok (error
);
3542 (*overrides
) [onum
* 2 + 1] = mb
->mhandle
;
3544 g_assert (mb
->mhandle
);
3552 *num_overrides
= onum
;
3556 modulebuilder_get_next_table_index (MonoReflectionModuleBuilder
*mb
, gint32 table
, gint32 num_fields
, MonoError
*error
)
3560 if (mb
->table_indexes
== NULL
) {
3561 MonoArray
*arr
= mono_array_new_checked (mono_object_domain (&mb
->module
.obj
), mono_defaults
.int_class
, 64, error
);
3562 return_val_if_nok (error
, 0);
3563 for (int i
= 0; i
< 64; i
++) {
3564 mono_array_set_internal (arr
, int, i
, 1);
3566 MONO_OBJECT_SETREF_INTERNAL (mb
, table_indexes
, arr
);
3568 gint32 index
= mono_array_get_internal (mb
->table_indexes
, gint32
, table
);
3569 gint32 next_index
= index
+ num_fields
;
3570 mono_array_set_internal (mb
->table_indexes
, gint32
, table
, next_index
);
3574 /* This initializes the same data as mono_class_setup_fields () */
3576 typebuilder_setup_fields (MonoClass
*klass
, MonoError
*error
)
3578 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3579 MonoReflectionFieldBuilder
*fb
;
3580 MonoClassField
*field
;
3581 MonoFieldDefaultValue
*def_values
;
3582 MonoImage
*image
= klass
->image
;
3584 int i
, instance_size
, packing_size
= 0;
3589 if (klass
->parent
) {
3590 if (!klass
->parent
->size_inited
)
3591 mono_class_init (klass
->parent
);
3592 instance_size
= klass
->parent
->instance_size
;
3594 instance_size
= MONO_ABI_SIZEOF (MonoObject
);
3597 int fcount
= tb
->num_fields
;
3598 mono_class_set_field_count (klass
, fcount
);
3600 gint32 first_idx
= 0;
3601 if (tb
->num_fields
> 0) {
3602 first_idx
= modulebuilder_get_next_table_index (tb
->module
, MONO_TABLE_FIELD
, (gint32
)tb
->num_fields
, error
);
3603 return_if_nok (error
);
3605 mono_class_set_first_field_idx (klass
, first_idx
- 1); /* Why do we subtract 1? because mono_class_create_from_typedef does it, too. */
3607 if (tb
->class_size
) {
3608 packing_size
= tb
->packing_size
;
3609 instance_size
+= tb
->class_size
;
3612 klass
->fields
= image_g_new0 (image
, MonoClassField
, fcount
);
3613 def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, fcount
);
3614 mono_class_set_field_def_values (klass
, def_values
);
3616 This is, guess what, a hack.
3617 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3618 On the static path no field class is resolved, only types are built. This is the right thing to do
3620 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3622 klass
->size_inited
= 1;
3624 for (i
= 0; i
< fcount
; ++i
) {
3625 MonoArray
*rva_data
;
3626 fb
= (MonoReflectionFieldBuilder
*)mono_array_get_internal (tb
->fields
, gpointer
, i
);
3627 field
= &klass
->fields
[i
];
3628 field
->parent
= klass
;
3629 field
->name
= string_to_utf8_image_raw (image
, fb
->name
, error
); /* FIXME use handles */
3630 if (!mono_error_ok (error
))
3633 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3634 return_if_nok (error
);
3635 field
->type
= mono_metadata_type_dup (klass
->image
, type
);
3636 field
->type
->attrs
= fb
->attrs
;
3638 field
->type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3639 return_if_nok (error
);
3642 if (!klass
->enumtype
&& !mono_type_get_underlying_type (field
->type
)) {
3643 mono_class_set_type_load_failure (klass
, "Field '%s' is an enum type with a bad underlying type", field
->name
);
3647 if ((fb
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
) && (rva_data
= fb
->rva_data
)) {
3648 char *base
= mono_array_addr_internal (rva_data
, char, 0);
3649 size_t size
= mono_array_length_internal (rva_data
);
3650 char *data
= (char *)mono_image_alloc (klass
->image
, size
);
3651 memcpy (data
, base
, size
);
3652 def_values
[i
].data
= data
;
3654 if (fb
->offset
!= -1)
3655 field
->offset
= fb
->offset
;
3657 mono_save_custom_attrs (klass
->image
, field
, fb
->cattrs
);
3659 if (fb
->def_value
) {
3660 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3661 field
->type
->attrs
|= FIELD_ATTRIBUTE_HAS_DEFAULT
;
3662 idx
= mono_dynimage_encode_constant (assembly
, fb
->def_value
, &def_values
[i
].def_type
);
3663 /* Copy the data from the blob since it might get realloc-ed */
3664 p
= assembly
->blob
.data
+ idx
;
3665 len
= mono_metadata_decode_blob_size (p
, &p2
);
3667 def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3668 memcpy ((gpointer
)def_values
[i
].data
, p
, len
);
3671 MonoObjectHandle field_builder_handle
= MONO_HANDLE_CAST (MonoObject
, MONO_HANDLE_NEW (MonoReflectionFieldBuilder
, fb
));
3672 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
);
3675 if (!mono_class_has_failure (klass
))
3676 mono_class_layout_fields (klass
, instance_size
, packing_size
, tb
->class_size
, TRUE
);
3680 typebuilder_setup_properties (MonoClass
*klass
, MonoError
*error
)
3682 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3683 MonoReflectionPropertyBuilder
*pb
;
3684 MonoImage
*image
= klass
->image
;
3685 MonoProperty
*properties
;
3686 MonoClassPropertyInfo
*info
;
3691 info
= (MonoClassPropertyInfo
*)mono_class_get_property_info (klass
);
3693 info
= mono_class_alloc0 (klass
, sizeof (MonoClassPropertyInfo
));
3694 mono_class_set_property_info (klass
, info
);
3697 info
->count
= tb
->properties
? mono_array_length_internal (tb
->properties
) : 0;
3700 properties
= image_g_new0 (image
, MonoProperty
, info
->count
);
3701 info
->properties
= properties
;
3702 for (i
= 0; i
< info
->count
; ++i
) {
3703 pb
= mono_array_get_internal (tb
->properties
, MonoReflectionPropertyBuilder
*, i
);
3704 properties
[i
].parent
= klass
;
3705 properties
[i
].attrs
= pb
->attrs
;
3706 properties
[i
].name
= string_to_utf8_image_raw (image
, pb
->name
, error
); /* FIXME use handles */
3707 if (!mono_error_ok (error
))
3710 properties
[i
].get
= pb
->get_method
->mhandle
;
3712 properties
[i
].set
= pb
->set_method
->mhandle
;
3714 mono_save_custom_attrs (klass
->image
, &properties
[i
], pb
->cattrs
);
3715 if (pb
->def_value
) {
3718 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3719 if (!info
->def_values
)
3720 info
->def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, info
->count
);
3721 properties
[i
].attrs
|= PROPERTY_ATTRIBUTE_HAS_DEFAULT
;
3722 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &info
->def_values
[i
].def_type
);
3723 /* Copy the data from the blob since it might get realloc-ed */
3724 p
= assembly
->blob
.data
+ idx
;
3725 len
= mono_metadata_decode_blob_size (p
, &p2
);
3727 info
->def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3728 memcpy ((gpointer
)info
->def_values
[i
].data
, p
, len
);
3734 typebuilder_setup_events (MonoClass
*klass
, MonoError
*error
)
3736 MonoReflectionTypeBuilder
*tb
= mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3737 MonoReflectionEventBuilder
*eb
;
3738 MonoImage
*image
= klass
->image
;
3740 MonoClassEventInfo
*info
;
3745 info
= mono_class_alloc0 (klass
, sizeof (MonoClassEventInfo
));
3746 mono_class_set_event_info (klass
, info
);
3748 info
->count
= tb
->events
? mono_array_length_internal (tb
->events
) : 0;
3751 events
= image_g_new0 (image
, MonoEvent
, info
->count
);
3752 info
->events
= events
;
3753 for (i
= 0; i
< info
->count
; ++i
) {
3754 eb
= mono_array_get_internal (tb
->events
, MonoReflectionEventBuilder
*, i
);
3755 events
[i
].parent
= klass
;
3756 events
[i
].attrs
= eb
->attrs
;
3757 events
[i
].name
= string_to_utf8_image_raw (image
, eb
->name
, error
); /* FIXME use handles */
3758 if (!mono_error_ok (error
))
3761 events
[i
].add
= eb
->add_method
->mhandle
;
3762 if (eb
->remove_method
)
3763 events
[i
].remove
= eb
->remove_method
->mhandle
;
3764 if (eb
->raise_method
)
3765 events
[i
].raise
= eb
->raise_method
->mhandle
;
3767 #ifndef MONO_SMALL_CONFIG
3768 if (eb
->other_methods
) {
3770 events
[i
].other
= image_g_new0 (image
, MonoMethod
*, mono_array_length_internal (eb
->other_methods
) + 1);
3771 for (j
= 0; j
< mono_array_length_internal (eb
->other_methods
); ++j
) {
3772 MonoReflectionMethodBuilder
*mb
=
3773 mono_array_get_internal (eb
->other_methods
,
3774 MonoReflectionMethodBuilder
*, j
);
3775 events
[i
].other
[j
] = mb
->mhandle
;
3779 mono_save_custom_attrs (klass
->image
, &events
[i
], eb
->cattrs
);
3783 struct remove_instantiations_user_data
3790 remove_instantiations_of_and_ensure_contents (gpointer key
,
3794 struct remove_instantiations_user_data
*data
= (struct remove_instantiations_user_data
*)user_data
;
3795 MonoType
*type
= (MonoType
*)key
;
3796 MonoClass
*klass
= data
->klass
;
3797 gboolean already_failed
= !is_ok (data
->error
);
3798 ERROR_DECL_VALUE (lerror
);
3799 MonoError
*error
= already_failed
? &lerror
: data
->error
;
3801 if ((type
->type
== MONO_TYPE_GENERICINST
) && (type
->data
.generic_class
->container_class
== klass
)) {
3802 MonoClass
*inst_klass
= mono_class_from_mono_type_internal (type
);
3803 //Ensure it's safe to use it.
3804 if (!fix_partial_generic_class (inst_klass
, error
)) {
3805 mono_class_set_type_load_failure (inst_klass
, "Could not initialized generic type instance due to: %s", mono_error_get_message (error
));
3806 // Marked the class with failure, but since some other instantiation already failed,
3807 // just report that one, and swallow the error from this one.
3809 mono_error_cleanup (error
);
3817 * reflection_setup_internal_class:
3818 * @tb: a TypeBuilder object
3819 * @error: set on error
3821 * Creates a MonoClass that represents the TypeBuilder.
3822 * This is a trick that lets us simplify a lot of reflection code
3823 * (and will allow us to support Build and Run assemblies easier).
3825 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3828 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3830 MonoReflectionModuleBuilderHandle module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
3831 GHashTable
*unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
3833 if (unparented_classes
) {
3834 return reflection_setup_internal_class_internal (ref_tb
, error
);
3836 // If we're not being called recursively
3837 unparented_classes
= g_hash_table_new (NULL
, NULL
);
3838 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, unparented_classes
);
3840 gboolean ret_val
= reflection_setup_internal_class_internal (ref_tb
, error
);
3841 mono_error_assert_ok (error
);
3843 // Fix the relationship between the created classes and their parents
3844 reflection_setup_class_hierarchy (unparented_classes
, error
);
3845 mono_error_assert_ok (error
);
3847 g_hash_table_destroy (unparented_classes
);
3848 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, NULL
);
3854 MonoReflectionTypeHandle
3855 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3859 reflection_setup_internal_class (ref_tb
, error
);
3860 mono_error_assert_ok (error
);
3862 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_tb
);
3863 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
3864 MonoClass
*klass
= mono_class_from_mono_type_internal (type
);
3866 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, cattrs
);
3867 mono_save_custom_attrs (klass
->image
, klass
, MONO_HANDLE_RAW (cattrs
)); /* FIXME use handles */
3870 * we need to lock the domain because the lock will be taken inside
3871 * So, we need to keep the locking order correct.
3873 mono_loader_lock ();
3874 mono_domain_lock (domain
);
3875 if (klass
->wastypebuilder
) {
3876 mono_domain_unlock (domain
);
3877 mono_loader_unlock ();
3879 return mono_type_get_object_handle (domain
, m_class_get_byval_arg (klass
), error
);
3882 * Fields to set in klass:
3883 * the various flags: delegate/unicode/contextbound etc.
3885 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
3886 klass
->has_cctor
= 1;
3888 mono_class_setup_parent (klass
, klass
->parent
);
3889 /* fool mono_class_setup_supertypes */
3890 klass
->supertypes
= NULL
;
3891 mono_class_setup_supertypes (klass
);
3892 mono_class_setup_mono_type (klass
);
3894 /* enums are done right away */
3895 if (!klass
->enumtype
)
3896 if (!ensure_runtime_vtable (klass
, error
))
3899 MonoArrayHandle nested_types
;
3900 nested_types
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, subtypes
);
3901 if (!MONO_HANDLE_IS_NULL (nested_types
)) {
3902 GList
*nested
= NULL
;
3903 int num_nested
= mono_array_handle_length (nested_types
);
3904 MonoReflectionTypeHandle nested_tb
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
3905 for (int i
= 0; i
< num_nested
; ++i
) {
3906 MONO_HANDLE_ARRAY_GETREF (nested_tb
, nested_types
, i
);
3908 if (MONO_HANDLE_GETVAL (nested_tb
, type
) == NULL
) {
3909 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, nested_tb
), error
);
3910 mono_error_assert_ok (error
);
3913 MonoType
*subtype
= mono_reflection_type_handle_mono_type (nested_tb
, error
);
3914 goto_if_nok (error
, failure
);
3915 nested
= mono_g_list_prepend_image (klass
->image
, nested
, mono_class_from_mono_type_internal (subtype
));
3917 mono_class_set_nested_classes_property (klass
, nested
);
3920 klass
->nested_classes_inited
= TRUE
;
3922 typebuilder_setup_fields (klass
, error
);
3923 goto_if_nok (error
, failure
);
3924 typebuilder_setup_properties (klass
, error
);
3925 goto_if_nok (error
, failure
);
3927 typebuilder_setup_events (klass
, error
);
3928 goto_if_nok (error
, failure
);
3930 klass
->wastypebuilder
= TRUE
;
3932 MonoArrayHandle generic_params
;
3933 generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
3934 if (!MONO_HANDLE_IS_NULL (generic_params
)) {
3935 int num_params
= mono_array_handle_length (generic_params
);
3936 MonoReflectionTypeHandle ref_gparam
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
3937 for (int i
= 0; i
< num_params
; i
++) {
3938 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
3939 MonoType
*param_type
= mono_reflection_type_handle_mono_type (ref_gparam
, error
);
3940 goto_if_nok (error
, failure
);
3941 MonoClass
*gklass
= mono_class_from_mono_type_internal (param_type
);
3943 gklass
->wastypebuilder
= TRUE
;
3948 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3949 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3950 * we want to return normal System.MonoType objects, so clear these out from the cache.
3952 * Together with this we must ensure the contents of all instances to match the created type.
3954 if (domain
->type_hash
&& mono_class_is_gtd (klass
)) {
3955 struct remove_instantiations_user_data data
;
3958 mono_error_assert_ok (error
);
3959 mono_g_hash_table_foreach_remove (domain
->type_hash
, remove_instantiations_of_and_ensure_contents
, &data
);
3960 goto_if_nok (error
, failure
);
3963 mono_domain_unlock (domain
);
3964 mono_loader_unlock ();
3966 if (klass
->enumtype
&& !mono_class_is_valid_enum (klass
)) {
3967 mono_class_set_type_load_failure (klass
, "Not a valid enumeration");
3968 mono_error_set_type_load_class (error
, klass
, "Not a valid enumeration");
3969 goto failure_unlocked
;
3972 MonoReflectionTypeHandle res
;
3973 res
= mono_type_get_object_handle (domain
, m_class_get_byval_arg (klass
), error
);
3974 goto_if_nok (error
, failure_unlocked
);
3979 mono_class_set_type_load_failure (klass
, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error
));
3980 klass
->wastypebuilder
= TRUE
;
3981 mono_domain_unlock (domain
);
3982 mono_loader_unlock ();
3984 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
3990 } DynamicMethodReleaseData
;
3993 * The runtime automatically clean up those after finalization.
3995 static MonoReferenceQueue
*dynamic_method_queue
;
3998 free_dynamic_method (void *dynamic_method
)
4000 DynamicMethodReleaseData
*data
= (DynamicMethodReleaseData
*)dynamic_method
;
4001 MonoDomain
*domain
= data
->domain
;
4002 MonoMethod
*method
= data
->handle
;
4005 mono_domain_lock (domain
);
4006 dis_link
= (guint32
)(size_t)g_hash_table_lookup (domain
->method_to_dyn_method
, method
);
4007 g_hash_table_remove (domain
->method_to_dyn_method
, method
);
4008 mono_domain_unlock (domain
);
4009 g_assert (dis_link
);
4010 mono_gchandle_free_internal (dis_link
);
4012 mono_runtime_free_method (domain
, method
);
4017 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb
, MonoError
*error
)
4019 MonoReferenceQueue
*queue
;
4021 DynamicMethodReleaseData
*release_data
;
4022 ReflectionMethodBuilder rmb
;
4023 MonoMethodSignature
*sig
;
4031 if (mono_runtime_is_shutting_down ()) {
4032 mono_error_set_generic_error (error
, "System", "InvalidOperationException", "");
4036 if (!(queue
= dynamic_method_queue
)) {
4037 mono_loader_lock ();
4038 if (!(queue
= dynamic_method_queue
))
4039 queue
= dynamic_method_queue
= mono_gc_reference_queue_new_internal (free_dynamic_method
);
4040 mono_loader_unlock ();
4043 sig
= dynamic_method_to_signature (ref_mb
, error
);
4044 return_val_if_nok (error
, FALSE
);
4046 MonoReflectionDynamicMethod
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME convert reflection_create_dynamic_method to use handles */
4047 reflection_methodbuilder_from_dynamic_method (&rmb
, mb
);
4050 * Resolve references.
4053 * Every second entry in the refs array is reserved for storing handle_class,
4054 * which is needed by the ldtoken implementation in the JIT.
4056 rmb
.nrefs
= mb
->nrefs
;
4057 rmb
.refs
= g_new0 (gpointer
, mb
->nrefs
+ 1);
4058 for (i
= 0; i
< mb
->nrefs
; i
+= 2) {
4059 MonoClass
*handle_class
;
4061 MonoObject
*obj
= mono_array_get_internal (mb
->refs
, MonoObject
*, i
);
4063 if (strcmp (obj
->vtable
->klass
->name
, "DynamicMethod") == 0) {
4064 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4066 * The referenced DynamicMethod should already be created by the managed
4067 * code, except in the case of circular references. In that case, we store
4068 * method in the refs array, and fix it up later when the referenced
4069 * DynamicMethod is created.
4071 if (method
->mhandle
) {
4072 ref
= method
->mhandle
;
4074 /* FIXME: GC object stored in unmanaged memory */
4077 /* FIXME: GC object stored in unmanaged memory */
4078 method
->referenced_by
= g_slist_append (method
->referenced_by
, mb
);
4080 handle_class
= mono_defaults
.methodhandle_class
;
4082 MonoException
*ex
= NULL
;
4083 ref
= mono_reflection_resolve_object (mb
->module
->image
, obj
, &handle_class
, NULL
, error
);
4084 if (!is_ok (error
)) {
4089 ex
= mono_get_exception_type_load (NULL
, NULL
);
4090 else if (mono_security_core_clr_enabled ())
4091 ex
= mono_security_core_clr_ensure_dynamic_method_resolved_object (ref
, handle_class
);
4095 mono_error_set_exception_instance (error
, ex
);
4100 rmb
.refs
[i
] = ref
; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
4101 rmb
.refs
[i
+ 1] = handle_class
;
4104 MonoAssembly
*ass
= NULL
;
4106 MonoType
*owner_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)mb
->owner
, error
);
4107 if (!is_ok (error
)) {
4111 klass
= mono_class_from_mono_type_internal (owner_type
);
4112 ass
= klass
->image
->assembly
;
4114 klass
= mono_defaults
.object_class
;
4115 ass
= (mb
->module
&& mb
->module
->image
) ? mb
->module
->image
->assembly
: NULL
;
4118 mb
->mhandle
= handle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
4119 ((MonoDynamicMethod
*)handle
)->assembly
= ass
;
4121 return_val_if_nok (error
, FALSE
);
4123 release_data
= g_new (DynamicMethodReleaseData
, 1);
4124 release_data
->handle
= handle
;
4125 release_data
->domain
= mono_object_get_domain_internal ((MonoObject
*)mb
);
4126 if (!mono_gc_reference_queue_add_internal (queue
, (MonoObject
*)mb
, release_data
))
4127 g_free (release_data
);
4129 /* Fix up refs entries pointing at us */
4130 for (l
= mb
->referenced_by
; l
; l
= l
->next
) {
4131 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)l
->data
;
4132 MonoMethodWrapper
*wrapper
= (MonoMethodWrapper
*)method
->mhandle
;
4135 g_assert (method
->mhandle
);
4137 data
= (gpointer
*)wrapper
->method_data
;
4138 for (i
= 0; i
< GPOINTER_TO_UINT (data
[0]); i
+= 2) {
4139 if ((data
[i
+ 1] == mb
) && (data
[i
+ 1 + 1] == mono_defaults
.methodhandle_class
))
4140 data
[i
+ 1] = mb
->mhandle
;
4143 g_slist_free (mb
->referenced_by
);
4145 /* ilgen is no longer needed */
4148 domain
= mono_domain_get ();
4149 mono_domain_lock (domain
);
4150 if (!domain
->method_to_dyn_method
)
4151 domain
->method_to_dyn_method
= g_hash_table_new (NULL
, NULL
);
4152 g_hash_table_insert (domain
->method_to_dyn_method
, handle
, (gpointer
)(size_t)mono_gchandle_new_weakref_internal ((MonoObject
*)mb
, TRUE
));
4153 mono_domain_unlock (domain
);
4159 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4161 (void) reflection_create_dynamic_method (mb
, error
);
4164 #endif /* DISABLE_REFLECTION_EMIT */
4166 MonoMethodSignature
*
4167 mono_reflection_lookup_signature (MonoImage
*image
, MonoMethod
*method
, guint32 token
, MonoError
*error
)
4169 MonoMethodSignature
*sig
;
4170 g_assert (image_is_dynamic (image
));
4174 sig
= (MonoMethodSignature
*)g_hash_table_lookup (((MonoDynamicImage
*)image
)->vararg_aux_hash
, GUINT_TO_POINTER (token
));
4178 return mono_method_signature_checked (method
, error
);
4181 #ifndef DISABLE_REFLECTION_EMIT
4184 * ensure_complete_type:
4186 * Ensure that KLASS is completed if it is a dynamic type, or references
4190 ensure_complete_type (MonoClass
*klass
, MonoError
*error
)
4192 HANDLE_FUNCTION_ENTER ();
4196 if (image_is_dynamic (klass
->image
) && !klass
->wastypebuilder
&& mono_class_has_ref_info (klass
)) {
4197 MonoReflectionTypeBuilderHandle tb
= mono_class_get_ref_info (klass
);
4199 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4200 goto_if_nok (error
, exit
);
4202 // Asserting here could break a lot of code
4203 //g_assert (klass->wastypebuilder);
4206 if (mono_class_is_ginst (klass
)) {
4207 MonoGenericInst
*inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
4210 for (i
= 0; i
< inst
->type_argc
; ++i
) {
4211 ensure_complete_type (mono_class_from_mono_type_internal (inst
->type_argv
[i
]), error
);
4212 goto_if_nok (error
, exit
);
4217 HANDLE_FUNCTION_RETURN ();
4221 mono_reflection_resolve_object (MonoImage
*image
, MonoObject
*obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4223 HANDLE_FUNCTION_ENTER ();
4225 MonoClass
*oklass
= obj
->vtable
->klass
;
4226 gpointer result
= NULL
;
4230 if (strcmp (oklass
->name
, "String") == 0) {
4231 result
= mono_string_intern_checked ((MonoString
*)obj
, error
);
4232 goto_if_nok (error
, return_null
);
4233 *handle_class
= mono_defaults
.string_class
;
4235 } else if (strcmp (oklass
->name
, "RuntimeType") == 0) {
4236 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
4237 goto_if_nok (error
, return_null
);
4238 MonoClass
*mc
= mono_class_from_mono_type_internal (type
);
4239 if (!mono_class_init (mc
)) {
4240 mono_error_set_for_class_failure (error
, mc
);
4245 MonoType
*inflated
= mono_class_inflate_generic_type_checked (type
, context
, error
);
4246 goto_if_nok (error
, return_null
);
4248 result
= mono_class_from_mono_type_internal (inflated
);
4249 mono_metadata_free_type (inflated
);
4251 result
= mono_class_from_mono_type_internal (type
);
4253 *handle_class
= mono_defaults
.typehandle_class
;
4255 } else if (strcmp (oklass
->name
, "MonoMethod") == 0 ||
4256 strcmp (oklass
->name
, "MonoCMethod") == 0) {
4257 result
= ((MonoReflectionMethod
*)obj
)->method
;
4259 result
= mono_class_inflate_generic_method_checked ((MonoMethod
*)result
, context
, error
);
4260 mono_error_assert_ok (error
);
4262 *handle_class
= mono_defaults
.methodhandle_class
;
4264 } else if (strcmp (oklass
->name
, "MonoField") == 0) {
4265 MonoClassField
*field
= ((MonoReflectionField
*)obj
)->field
;
4267 ensure_complete_type (field
->parent
, error
);
4268 goto_if_nok (error
, return_null
);
4271 MonoType
*inflated
= mono_class_inflate_generic_type_checked (m_class_get_byval_arg (field
->parent
), context
, error
);
4272 goto_if_nok (error
, return_null
);
4275 klass
= mono_class_from_mono_type_internal (inflated
);
4276 MonoClassField
*inflated_field
;
4277 gpointer iter
= NULL
;
4278 mono_metadata_free_type (inflated
);
4279 while ((inflated_field
= mono_class_get_fields_internal (klass
, &iter
))) {
4280 if (!strcmp (field
->name
, inflated_field
->name
))
4283 g_assert (inflated_field
&& !strcmp (field
->name
, inflated_field
->name
));
4284 result
= inflated_field
;
4288 *handle_class
= mono_defaults
.fieldhandle_class
;
4290 } else if (strcmp (oklass
->name
, "TypeBuilder") == 0) {
4291 MonoReflectionTypeBuilderHandle tb
= MONO_HANDLE_NEW (MonoReflectionTypeBuilder
, (MonoReflectionTypeBuilder
*)obj
);
4292 MonoType
*type
= mono_reflection_type_get_handle (&MONO_HANDLE_RAW (tb
)->type
, error
);
4293 goto_if_nok (error
, return_null
);
4296 klass
= type
->data
.klass
;
4297 if (klass
->wastypebuilder
) {
4298 /* Already created */
4302 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4303 goto_if_nok (error
, return_null
);
4304 result
= type
->data
.klass
;
4307 *handle_class
= mono_defaults
.typehandle_class
;
4308 } else if (strcmp (oklass
->name
, "SignatureHelper") == 0) {
4309 MonoReflectionSigHelper
*helper
= (MonoReflectionSigHelper
*)obj
;
4310 MonoMethodSignature
*sig
;
4313 if (helper
->arguments
)
4314 nargs
= mono_array_length_internal (helper
->arguments
);
4318 sig
= mono_metadata_signature_alloc (image
, nargs
);
4319 sig
->explicit_this
= helper
->call_conv
& 64 ? 1 : 0;
4320 sig
->hasthis
= helper
->call_conv
& 32 ? 1 : 0;
4322 if (helper
->unmanaged_call_conv
) { /* unmanaged */
4323 sig
->call_convention
= helper
->unmanaged_call_conv
- 1;
4324 sig
->pinvoke
= TRUE
;
4325 } else if (helper
->call_conv
& 0x02) {
4326 sig
->call_convention
= MONO_CALL_VARARG
;
4328 sig
->call_convention
= MONO_CALL_DEFAULT
;
4331 sig
->param_count
= nargs
;
4332 /* TODO: Copy type ? */
4333 sig
->ret
= helper
->return_type
->type
;
4334 for (i
= 0; i
< nargs
; ++i
) {
4335 sig
->params
[i
] = mono_type_array_get_and_resolve_raw (helper
->arguments
, i
, error
); /* FIXME use handles */
4336 if (!is_ok (error
)) {
4337 image_g_free (image
, sig
);
4343 *handle_class
= NULL
;
4344 } else if (strcmp (oklass
->name
, "DynamicMethod") == 0) {
4345 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4346 /* Already created by the managed code */
4347 g_assert (method
->mhandle
);
4348 result
= method
->mhandle
;
4349 *handle_class
= mono_defaults
.methodhandle_class
;
4350 } else if (strcmp (oklass
->name
, "MonoArrayMethod") == 0) {
4351 MonoReflectionArrayMethod
*m
= (MonoReflectionArrayMethod
*)obj
;
4358 mtype
= mono_reflection_type_get_handle (m
->parent
, error
);
4359 goto_if_nok (error
, return_null
);
4360 klass
= mono_class_from_mono_type_internal (mtype
);
4362 /* Find the method */
4364 name
= mono_string_to_utf8_checked_internal (m
->name
, error
);
4365 goto_if_nok (error
, return_null
);
4367 while ((method
= mono_class_get_methods (klass
, &iter
))) {
4368 if (!strcmp (method
->name
, name
))
4375 // FIXME: Check parameters/return value etc. match
4378 *handle_class
= mono_defaults
.methodhandle_class
;
4379 } else if (is_sre_method_builder (oklass
) ||
4380 mono_is_sre_ctor_builder (oklass
) ||
4381 is_sre_field_builder (oklass
) ||
4382 is_sre_gparam_builder (oklass
) ||
4383 is_sre_generic_instance (oklass
) ||
4384 is_sre_array (oklass
) ||
4385 is_sre_byref (oklass
) ||
4386 is_sre_pointer (oklass
) ||
4387 !strcmp (oklass
->name
, "FieldOnTypeBuilderInst") ||
4388 !strcmp (oklass
->name
, "MethodOnTypeBuilderInst") ||
4389 !strcmp (oklass
->name
, "ConstructorOnTypeBuilderInst")) {
4390 static MonoMethod
*resolve_method
;
4391 if (!resolve_method
) {
4392 MonoMethod
*m
= mono_class_get_method_from_name_checked (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0, error
);
4393 mono_error_assert_ok (error
);
4395 mono_memory_barrier ();
4400 obj
= mono_runtime_invoke_checked (resolve_method
, NULL
, args
, error
);
4401 mono_error_assert_ok (error
);
4403 result
= mono_reflection_resolve_object (image
, obj
, handle_class
, context
, error
);
4406 g_print ("%s\n", obj
->vtable
->klass
->name
);
4407 g_assert_not_reached ();
4415 HANDLE_FUNCTION_RETURN_VAL (result
);
4419 mono_reflection_resolve_object_handle (MonoImage
*image
, MonoObjectHandle obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4421 return mono_reflection_resolve_object (image
, MONO_HANDLE_RAW (obj
), handle_class
, context
, error
);
4424 #else /* DISABLE_REFLECTION_EMIT */
4427 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4429 g_assert_not_reached ();
4434 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4436 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4440 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4442 g_assert_not_reached ();
4447 mono_image_insert_string (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4449 g_assert_not_reached ();
4454 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
4456 g_assert_not_reached ();
4461 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
4462 gboolean create_open_instance
, gboolean register_token
, MonoError
*error
)
4464 g_assert_not_reached ();
4469 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
4476 MonoReflectionTypeHandle
4477 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
)
4479 g_assert_not_reached ();
4480 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4484 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4490 mono_reflection_type_get_handle (MonoReflectionType
* ref
, MonoError
*error
)
4499 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
4502 if (MONO_HANDLE_IS_NULL (ref
))
4504 return MONO_HANDLE_GETVAL (ref
, type
);
4508 #endif /* DISABLE_REFLECTION_EMIT */
4511 mono_sre_generic_param_table_entry_free (GenericParamTableEntry
*entry
)
4513 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry
->gparam
);
4518 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, MonoBoolean create_open_instance
, MonoError
*error
)
4521 if (MONO_HANDLE_IS_NULL (obj
)) {
4522 mono_error_set_argument_null (error
, "obj", "");
4525 return mono_image_create_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), obj
, create_open_instance
, TRUE
, error
);
4529 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb
,
4530 MonoReflectionMethodHandle method
,
4531 MonoArrayHandle opt_param_types
,
4535 if (MONO_HANDLE_IS_NULL (method
)) {
4536 mono_error_set_argument_null (error
, "method", "");
4540 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), MONO_HANDLE_CAST (MonoObject
, method
), opt_param_types
, error
);
4544 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
4547 mono_image_create_pefile (mb
, file
, error
);
4548 mono_error_set_pending_exception (error
);
4552 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
4555 mono_image_build_metadata (mb
, error
);
4556 mono_error_set_pending_exception (error
);
4560 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, guint32 token
, MonoError
*error
)
4563 /* This function may be called by ModuleBuilder.FixupTokens to update
4564 * an existing token, so replace is okay here. */
4565 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), token
, obj
, MONO_DYN_IMAGE_TOK_REPLACE
);
4569 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb
, guint32 token
, MonoError
*error
)
4571 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
4572 return mono_dynamic_image_get_registered_token (dynamic_image
, token
, error
);
4575 #ifndef DISABLE_REFLECTION_EMIT
4577 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4580 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, error
);
4581 mono_error_set_pending_exception (error
);
4587 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4589 mono_reflection_dynimage_basic_init (assemblyb
);
4593 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb
, MonoError
*error
)
4595 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, assemblyb
, cattrs
);
4597 MonoReflectionAssemblyHandle assembly_handle
= MONO_HANDLE_CAST (MonoReflectionAssembly
, assemblyb
);
4598 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_handle
, assembly
);
4599 g_assert (assembly
);
4601 mono_save_custom_attrs (assembly
->image
, assembly
, MONO_HANDLE_RAW (cattrs
));
4605 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype
,
4606 MonoReflectionTypeHandle t
,
4610 MONO_HANDLE_SETVAL (enumtype
, type
, MonoType
*, MONO_HANDLE_GETVAL (t
, type
));
4614 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4617 mono_image_module_basic_init (moduleb
, error
);
4621 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4623 return mono_image_insert_string (module
, str
, error
);
4627 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb
, MonoReflectionTypeHandle ref_type
, MonoError
*error
)
4630 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
4631 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4634 image
->wrappers_type
= mono_class_from_mono_type_internal (type
);