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/debug-helpers.h"
21 #include "mono/metadata/dynamic-image-internals.h"
22 #include "mono/metadata/dynamic-stream-internals.h"
23 #include "mono/metadata/exception.h"
24 #include "mono/metadata/gc-internals.h"
25 #include "mono/metadata/mono-ptr-array.h"
26 #include "mono/metadata/object-internals.h"
27 #include "mono/metadata/profiler-private.h"
28 #include "mono/metadata/reflection-internals.h"
29 #include "mono/metadata/reflection-cache.h"
30 #include "mono/metadata/sre-internals.h"
31 #include "mono/metadata/custom-attrs-internals.h"
32 #include "mono/metadata/security-manager.h"
33 #include "mono/metadata/security-core-clr.h"
34 #include "mono/metadata/tabledefs.h"
35 #include "mono/metadata/tokentype.h"
36 #include "mono/utils/checked-build.h"
37 #include "mono/utils/mono-digest.h"
38 #include "mono/utils/w32api.h"
40 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute
, "System.Runtime.InteropServices", "MarshalAsAttribute");
41 static GENERATE_GET_CLASS_WITH_CACHE (module_builder
, "System.Reflection.Emit", "ModuleBuilder");
43 static char* string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s
, MonoError
*error
);
45 #ifndef DISABLE_REFLECTION_EMIT
46 static guint32
mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
);
47 static gboolean
ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
);
48 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
);
49 static gboolean
reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
50 static gboolean
reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
);
51 static gboolean
reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
);
54 static gpointer
register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
);
57 static char* type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
);
58 static MonoReflectionTypeHandle
mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
);
59 static gboolean
is_sre_array (MonoClass
*klass
);
60 static gboolean
is_sre_byref (MonoClass
*klass
);
61 static gboolean
is_sre_pointer (MonoClass
*klass
);
62 static gboolean
is_sre_generic_instance (MonoClass
*klass
);
63 static gboolean
is_sre_type_builder (MonoClass
*klass
);
64 static gboolean
is_sre_method_builder (MonoClass
*klass
);
65 static gboolean
is_sre_field_builder (MonoClass
*klass
);
66 static gboolean
is_sre_gparam_builder (MonoClass
*klass
);
67 static gboolean
is_sre_enum_builder (MonoClass
*klass
);
68 static gboolean
is_sr_mono_method (MonoClass
*klass
);
69 static gboolean
is_sr_mono_field (MonoClass
*klass
);
71 static guint32
mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
);
72 static guint32
mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
);
73 static guint32
mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
);
76 #ifndef DISABLE_REFLECTION_EMIT
77 static MonoType
* mono_type_array_get_and_resolve_raw (MonoArray
* array
, int idx
, MonoError
* error
);
80 static gboolean
mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module
, MonoError
*error
);
83 mono_reflection_emit_init (void)
85 mono_dynamic_images_init ();
89 string_to_utf8_image_raw (MonoImage
*image
, MonoString
*s_raw
, MonoError
*error
)
91 /* FIXME all callers to string_to_utf8_image_raw should use handles */
92 HANDLE_FUNCTION_ENTER ();
95 MONO_HANDLE_DCL (MonoString
, s
);
96 result
= mono_string_to_utf8_image (image
, s
, error
);
97 HANDLE_FUNCTION_RETURN_VAL (result
);
101 type_get_fully_qualified_name (MonoType
*type
)
103 MONO_REQ_GC_NEUTRAL_MODE
;
105 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
109 type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
)
111 MONO_REQ_GC_UNSAFE_MODE
;
116 klass
= mono_class_from_mono_type (type
);
118 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
119 ta
= klass
->image
->assembly
;
120 if (assembly_is_dynamic (ta
) || (ta
== ass
)) {
121 if (mono_class_is_ginst (klass
) || mono_class_is_gtd (klass
))
122 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
123 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_FULL_NAME
);
125 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
128 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
131 #ifndef DISABLE_REFLECTION_EMIT
135 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
139 image_g_malloc (MonoImage
*image
, guint size
)
141 MONO_REQ_GC_NEUTRAL_MODE
;
144 return mono_image_alloc (image
, size
);
146 return g_malloc (size
);
148 #endif /* !DISABLE_REFLECTION_EMIT */
153 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
157 mono_image_g_malloc0 (MonoImage
*image
, guint size
)
159 MONO_REQ_GC_NEUTRAL_MODE
;
162 return mono_image_alloc0 (image
, size
);
164 return g_malloc0 (size
);
169 * @image: a MonoImage
172 * If @image is NULL, free @ptr, otherwise do nothing.
175 image_g_free (MonoImage
*image
, gpointer ptr
)
181 #ifndef DISABLE_REFLECTION_EMIT
183 image_strdup (MonoImage
*image
, const char *s
)
185 MONO_REQ_GC_NEUTRAL_MODE
;
188 return mono_image_strdup (image
, s
);
194 #define image_g_new(image,struct_type, n_structs) \
195 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
197 #define image_g_new0(image,struct_type, n_structs) \
198 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
202 alloc_table (MonoDynamicTable
*table
, guint nrows
)
204 mono_dynimage_alloc_table (table
, nrows
);
208 string_heap_insert (MonoDynamicStream
*sh
, const char *str
)
210 return mono_dynstream_insert_string (sh
, str
);
214 mono_image_add_stream_data (MonoDynamicStream
*stream
, const char *data
, guint32 len
)
216 return mono_dynstream_add_data (stream
, data
, len
);
220 * Despite the name, we handle also TypeSpec (with the above helper).
223 mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
)
225 return mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, TRUE
);
229 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
230 * dest may be misaligned.
233 swap_with_size (char *dest
, const char* val
, int len
, int nelem
) {
234 MONO_REQ_GC_NEUTRAL_MODE
;
235 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
238 for (elem
= 0; elem
< nelem
; ++elem
) {
264 g_assert_not_reached ();
270 memcpy (dest
, val
, len
* nelem
);
275 mono_reflection_method_count_clauses (MonoReflectionILGen
*ilgen
)
277 MONO_REQ_GC_UNSAFE_MODE
;
279 guint32 num_clauses
= 0;
282 MonoILExceptionInfo
*ex_info
;
283 for (i
= 0; i
< mono_array_length (ilgen
->ex_handlers
); ++i
) {
284 ex_info
= (MonoILExceptionInfo
*)mono_array_addr (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
285 if (ex_info
->handlers
)
286 num_clauses
+= mono_array_length (ex_info
->handlers
);
294 #ifndef DISABLE_REFLECTION_EMIT
295 static MonoExceptionClause
*
296 method_encode_clauses (MonoImage
*image
, MonoDynamicImage
*assembly
, MonoReflectionILGen
*ilgen
, guint32 num_clauses
, MonoError
*error
)
298 MONO_REQ_GC_UNSAFE_MODE
;
302 MonoExceptionClause
*clauses
;
303 MonoExceptionClause
*clause
;
304 MonoILExceptionInfo
*ex_info
;
305 MonoILExceptionBlock
*ex_block
;
306 guint32 finally_start
;
307 int i
, j
, clause_index
;;
309 clauses
= image_g_new0 (image
, MonoExceptionClause
, num_clauses
);
312 for (i
= mono_array_length (ilgen
->ex_handlers
) - 1; i
>= 0; --i
) {
313 ex_info
= (MonoILExceptionInfo
*)mono_array_addr (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
314 finally_start
= ex_info
->start
+ ex_info
->len
;
315 if (!ex_info
->handlers
)
317 for (j
= 0; j
< mono_array_length (ex_info
->handlers
); ++j
) {
318 ex_block
= (MonoILExceptionBlock
*)mono_array_addr (ex_info
->handlers
, MonoILExceptionBlock
, j
);
319 clause
= &(clauses
[clause_index
]);
321 clause
->flags
= ex_block
->type
;
322 clause
->try_offset
= ex_info
->start
;
324 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FINALLY
)
325 clause
->try_len
= finally_start
- ex_info
->start
;
327 clause
->try_len
= ex_info
->len
;
328 clause
->handler_offset
= ex_block
->start
;
329 clause
->handler_len
= ex_block
->len
;
330 if (ex_block
->extype
) {
331 MonoType
*extype
= mono_reflection_type_get_handle ((MonoReflectionType
*)ex_block
->extype
, error
);
333 if (!is_ok (error
)) {
334 image_g_free (image
, clauses
);
337 clause
->data
.catch_class
= mono_class_from_mono_type (extype
);
339 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FILTER
)
340 clause
->data
.filter_offset
= ex_block
->filter_offset
;
342 clause
->data
.filter_offset
= 0;
344 finally_start
= ex_block
->start
+ ex_block
->len
;
352 #endif /* !DISABLE_REFLECTION_EMIT */
354 #ifndef DISABLE_REFLECTION_EMIT
356 * LOCKING: Acquires the loader lock.
359 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
361 MONO_REQ_GC_UNSAFE_MODE
;
363 MonoCustomAttrInfo
*ainfo
, *tmp
;
365 if (!cattrs
|| !mono_array_length (cattrs
))
368 ainfo
= mono_custom_attrs_from_builders (image
, image
, cattrs
);
371 tmp
= (MonoCustomAttrInfo
*)mono_image_property_lookup (image
, obj
, MONO_PROP_DYNAMIC_CATTR
);
373 mono_custom_attrs_free (tmp
);
374 mono_image_property_insert (image
, obj
, MONO_PROP_DYNAMIC_CATTR
, ainfo
);
375 mono_loader_unlock ();
379 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
381 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
387 mono_reflection_resolution_scope_from_image (MonoDynamicImage
*assembly
, MonoImage
*image
)
389 MONO_REQ_GC_UNSAFE_MODE
;
391 MonoDynamicTable
*table
;
394 guint32 cols
[MONO_ASSEMBLY_SIZE
];
398 if ((token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, image
))))
401 if (assembly_is_dynamic (image
->assembly
) && (image
->assembly
== assembly
->image
.assembly
)) {
402 table
= &assembly
->tables
[MONO_TABLE_MODULEREF
];
403 token
= table
->next_idx
++;
405 alloc_table (table
, table
->rows
);
406 values
= table
->values
+ token
* MONO_MODULEREF_SIZE
;
407 values
[MONO_MODULEREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->module_name
);
409 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
410 token
|= MONO_RESOLUTION_SCOPE_MODULEREF
;
411 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
416 if (assembly_is_dynamic (image
->assembly
))
418 memset (cols
, 0, sizeof (cols
));
420 /* image->assembly->image is the manifest module */
421 image
= image
->assembly
->image
;
422 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_ASSEMBLY
], 0, cols
, MONO_ASSEMBLY_SIZE
);
425 table
= &assembly
->tables
[MONO_TABLE_ASSEMBLYREF
];
426 token
= table
->next_idx
++;
428 alloc_table (table
, table
->rows
);
429 values
= table
->values
+ token
* MONO_ASSEMBLYREF_SIZE
;
430 values
[MONO_ASSEMBLYREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->assembly_name
);
431 values
[MONO_ASSEMBLYREF_MAJOR_VERSION
] = cols
[MONO_ASSEMBLY_MAJOR_VERSION
];
432 values
[MONO_ASSEMBLYREF_MINOR_VERSION
] = cols
[MONO_ASSEMBLY_MINOR_VERSION
];
433 values
[MONO_ASSEMBLYREF_BUILD_NUMBER
] = cols
[MONO_ASSEMBLY_BUILD_NUMBER
];
434 values
[MONO_ASSEMBLYREF_REV_NUMBER
] = cols
[MONO_ASSEMBLY_REV_NUMBER
];
435 values
[MONO_ASSEMBLYREF_FLAGS
] = 0;
436 values
[MONO_ASSEMBLYREF_CULTURE
] = 0;
437 values
[MONO_ASSEMBLYREF_HASH_VALUE
] = 0;
439 if (strcmp ("", image
->assembly
->aname
.culture
)) {
440 values
[MONO_ASSEMBLYREF_CULTURE
] = string_heap_insert (&assembly
->sheap
,
441 image
->assembly
->aname
.culture
);
444 if ((pubkey
= mono_image_get_public_key (image
, &publen
))) {
447 mono_digest_get_public_token (pubtoken
+ 1, (guchar
*)pubkey
, publen
);
448 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = mono_image_add_stream_data (&assembly
->blob
, (char*)pubtoken
, 9);
450 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = 0;
452 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
453 token
|= MONO_RESOLUTION_SCOPE_ASSEMBLYREF
;
454 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
458 #ifndef DISABLE_REFLECTION_EMIT
460 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
)
462 MONO_REQ_GC_UNSAFE_MODE
;
465 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
467 rmb
->ilgen
= mb
->ilgen
;
468 rmb
->rtype
= (MonoReflectionType
*)mb
->rtype
;
469 return_val_if_nok (error
, FALSE
);
470 rmb
->parameters
= mb
->parameters
;
471 rmb
->generic_params
= mb
->generic_params
;
472 rmb
->generic_container
= mb
->generic_container
;
473 rmb
->opt_types
= NULL
;
474 rmb
->pinfo
= mb
->pinfo
;
475 rmb
->attrs
= mb
->attrs
;
476 rmb
->iattrs
= mb
->iattrs
;
477 rmb
->call_conv
= mb
->call_conv
;
478 rmb
->code
= mb
->code
;
479 rmb
->type
= mb
->type
;
480 rmb
->name
= mb
->name
;
481 rmb
->table_idx
= &mb
->table_idx
;
482 rmb
->init_locals
= mb
->init_locals
;
483 rmb
->skip_visibility
= FALSE
;
484 rmb
->return_modreq
= mb
->return_modreq
;
485 rmb
->return_modopt
= mb
->return_modopt
;
486 rmb
->param_modreq
= mb
->param_modreq
;
487 rmb
->param_modopt
= mb
->param_modopt
;
488 rmb
->permissions
= mb
->permissions
;
489 rmb
->mhandle
= mb
->mhandle
;
494 rmb
->charset
= mb
->charset
;
495 rmb
->extra_flags
= mb
->extra_flags
;
496 rmb
->native_cc
= mb
->native_cc
;
497 rmb
->dllentry
= mb
->dllentry
;
505 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
507 MONO_REQ_GC_UNSAFE_MODE
;
509 const char *name
= mb
->attrs
& METHOD_ATTRIBUTE_STATIC
? ".cctor": ".ctor";
513 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
515 rmb
->ilgen
= mb
->ilgen
;
516 rmb
->rtype
= mono_type_get_object_checked (mono_domain_get (), &mono_defaults
.void_class
->byval_arg
, error
);
517 return_val_if_nok (error
, FALSE
);
518 rmb
->parameters
= mb
->parameters
;
519 rmb
->generic_params
= NULL
;
520 rmb
->generic_container
= NULL
;
521 rmb
->opt_types
= NULL
;
522 rmb
->pinfo
= mb
->pinfo
;
523 rmb
->attrs
= mb
->attrs
;
524 rmb
->iattrs
= mb
->iattrs
;
525 rmb
->call_conv
= mb
->call_conv
;
527 rmb
->type
= mb
->type
;
528 rmb
->name
= mono_string_new_checked (mono_domain_get (), name
, error
);
529 return_val_if_nok (error
, FALSE
);
530 rmb
->table_idx
= &mb
->table_idx
;
531 rmb
->init_locals
= mb
->init_locals
;
532 rmb
->skip_visibility
= FALSE
;
533 rmb
->return_modreq
= NULL
;
534 rmb
->return_modopt
= NULL
;
535 rmb
->param_modreq
= mb
->param_modreq
;
536 rmb
->param_modopt
= mb
->param_modopt
;
537 rmb
->permissions
= mb
->permissions
;
538 rmb
->mhandle
= mb
->mhandle
;
546 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
)
548 MONO_REQ_GC_UNSAFE_MODE
;
550 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
552 rmb
->ilgen
= mb
->ilgen
;
553 rmb
->rtype
= mb
->rtype
;
554 rmb
->parameters
= mb
->parameters
;
555 rmb
->generic_params
= NULL
;
556 rmb
->generic_container
= NULL
;
557 rmb
->opt_types
= NULL
;
559 rmb
->attrs
= mb
->attrs
;
561 rmb
->call_conv
= mb
->call_conv
;
563 rmb
->type
= (MonoObject
*) mb
->owner
;
564 rmb
->name
= mb
->name
;
565 rmb
->table_idx
= NULL
;
566 rmb
->init_locals
= mb
->init_locals
;
567 rmb
->skip_visibility
= mb
->skip_visibility
;
568 rmb
->return_modreq
= NULL
;
569 rmb
->return_modopt
= NULL
;
570 rmb
->param_modreq
= NULL
;
571 rmb
->param_modopt
= NULL
;
572 rmb
->permissions
= NULL
;
573 rmb
->mhandle
= mb
->mhandle
;
577 #else /* DISABLE_REFLECTION_EMIT */
579 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
) {
580 g_assert_not_reached ();
584 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
586 g_assert_not_reached ();
589 #endif /* DISABLE_REFLECTION_EMIT */
591 #ifndef DISABLE_REFLECTION_EMIT
593 mono_image_add_memberef_row (MonoDynamicImage
*assembly
, guint32 parent
, const char *name
, guint32 sig
)
595 MONO_REQ_GC_NEUTRAL_MODE
;
597 MonoDynamicTable
*table
;
599 guint32 token
, pclass
;
601 switch (parent
& MONO_TYPEDEFORREF_MASK
) {
602 case MONO_TYPEDEFORREF_TYPEREF
:
603 pclass
= MONO_MEMBERREF_PARENT_TYPEREF
;
605 case MONO_TYPEDEFORREF_TYPESPEC
:
606 pclass
= MONO_MEMBERREF_PARENT_TYPESPEC
;
608 case MONO_TYPEDEFORREF_TYPEDEF
:
609 pclass
= MONO_MEMBERREF_PARENT_TYPEDEF
;
612 g_warning ("unknown typeref or def token 0x%08x for %s", parent
, name
);
615 /* extract the index */
616 parent
>>= MONO_TYPEDEFORREF_BITS
;
618 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
620 if (assembly
->save
) {
621 alloc_table (table
, table
->rows
+ 1);
622 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
623 values
[MONO_MEMBERREF_CLASS
] = pclass
| (parent
<< MONO_MEMBERREF_PARENT_BITS
);
624 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
625 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
628 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
635 * Insert a memberef row into the metadata: the token that point to the memberref
636 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
637 * mono_image_get_fieldref_token()).
638 * The sig param is an index to an already built signature.
641 mono_image_get_memberref_token (MonoDynamicImage
*assembly
, MonoType
*type
, const char *name
, guint32 sig
)
643 MONO_REQ_GC_NEUTRAL_MODE
;
645 guint32 parent
= mono_image_typedef_or_ref (assembly
, type
);
646 return mono_image_add_memberef_row (assembly
, parent
, name
, sig
);
651 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
653 MONO_REQ_GC_NEUTRAL_MODE
;
656 MonoMethodSignature
*sig
;
658 create_typespec
= create_typespec
&& method
->is_generic
&& method
->klass
->image
!= &assembly
->image
;
660 if (create_typespec
) {
661 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1)));
666 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
667 if (token
&& !create_typespec
)
670 g_assert (!method
->is_inflated
);
673 * A methodref signature can't contain an unmanaged calling convention.
675 sig
= mono_metadata_signature_dup (mono_method_signature (method
));
676 if ((sig
->call_convention
!= MONO_CALL_DEFAULT
) && (sig
->call_convention
!= MONO_CALL_VARARG
))
677 sig
->call_convention
= MONO_CALL_DEFAULT
;
678 token
= mono_image_get_memberref_token (assembly
, &method
->klass
->byval_arg
,
679 method
->name
, mono_dynimage_encode_method_signature (assembly
, sig
));
681 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
684 if (create_typespec
) {
685 MonoDynamicTable
*table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
686 g_assert (mono_metadata_token_table (token
) == MONO_TABLE_MEMBERREF
);
687 token
= (mono_metadata_token_index (token
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
689 if (assembly
->save
) {
692 alloc_table (table
, table
->rows
+ 1);
693 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
694 values
[MONO_METHODSPEC_METHOD
] = token
;
695 values
[MONO_METHODSPEC_SIGNATURE
] = mono_dynimage_encode_generic_method_sig (assembly
, &mono_method_get_generic_container (method
)->context
);
698 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
700 /*methodspec and memberef tokens are diferent, */
701 g_hash_table_insert (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1), GUINT_TO_POINTER (token
));
708 mono_image_get_varargs_method_token (MonoDynamicImage
*assembly
, guint32 original
,
709 const gchar
*name
, guint32 sig
)
711 MonoDynamicTable
*table
;
715 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
717 if (assembly
->save
) {
718 alloc_table (table
, table
->rows
+ 1);
719 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
720 values
[MONO_MEMBERREF_CLASS
] = original
;
721 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
722 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
725 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
731 #else /* DISABLE_REFLECTION_EMIT */
734 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
736 g_assert_not_reached ();
742 is_field_on_inst (MonoClassField
*field
)
744 return mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->is_dynamic
;
748 is_field_on_gtd (MonoClassField
*field
)
750 return mono_class_is_gtd (field
->parent
);
753 #ifndef DISABLE_REFLECTION_EMIT
755 mono_image_get_fieldref_token (MonoDynamicImage
*assembly
, MonoClassField
*field
)
761 g_assert (field
->parent
);
763 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, field
));
767 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
) {
768 int index
= field
- field
->parent
->fields
;
769 type
= mono_field_get_type (&mono_class_get_generic_class (field
->parent
)->container_class
->fields
[index
]);
771 type
= mono_field_get_type (field
);
773 token
= mono_image_get_memberref_token (assembly
, &field
->parent
->byval_arg
,
774 mono_field_get_name (field
),
775 mono_dynimage_encode_fieldref_signature (assembly
, field
->parent
->image
, type
));
776 g_hash_table_insert (assembly
->handleref
, field
, GUINT_TO_POINTER(token
));
781 method_encode_methodspec (MonoDynamicImage
*assembly
, MonoMethod
*method
)
783 MonoDynamicTable
*table
;
785 guint32 token
, mtoken
= 0, sig
;
786 MonoMethodInflated
*imethod
;
787 MonoMethod
*declaring
;
789 table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
791 g_assert (method
->is_inflated
);
792 imethod
= (MonoMethodInflated
*) method
;
793 declaring
= imethod
->declaring
;
795 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature (declaring
));
796 mtoken
= mono_image_get_memberref_token (assembly
, &method
->klass
->byval_arg
, declaring
->name
, sig
);
798 if (!mono_method_signature (declaring
)->generic_param_count
)
801 switch (mono_metadata_token_table (mtoken
)) {
802 case MONO_TABLE_MEMBERREF
:
803 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
805 case MONO_TABLE_METHOD
:
806 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODDEF
;
809 g_assert_not_reached ();
812 sig
= mono_dynimage_encode_generic_method_sig (assembly
, mono_method_get_context (method
));
814 if (assembly
->save
) {
815 alloc_table (table
, table
->rows
+ 1);
816 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
817 values
[MONO_METHODSPEC_METHOD
] = mtoken
;
818 values
[MONO_METHODSPEC_SIGNATURE
] = sig
;
821 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
828 mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
)
830 MonoMethodInflated
*imethod
;
833 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
837 g_assert (method
->is_inflated
);
838 imethod
= (MonoMethodInflated
*) method
;
840 if (mono_method_signature (imethod
->declaring
)->generic_param_count
) {
841 token
= method_encode_methodspec (assembly
, method
);
843 guint32 sig
= mono_dynimage_encode_method_signature (
844 assembly
, mono_method_signature (imethod
->declaring
));
845 token
= mono_image_get_memberref_token (
846 assembly
, &method
->klass
->byval_arg
, method
->name
, sig
);
849 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
854 mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
)
856 MonoMethodInflated
*imethod
= (MonoMethodInflated
*) m
;
859 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature (imethod
->declaring
));
860 token
= mono_image_get_memberref_token (
861 assembly
, &m
->klass
->byval_arg
, m
->name
, sig
);
867 mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelperHandle helper
, MonoError
*error
)
870 MonoDynamicTable
*table
;
875 table
= &assembly
->tables
[MONO_TABLE_STANDALONESIG
];
876 idx
= table
->next_idx
++;
878 alloc_table (table
, table
->rows
);
879 values
= table
->values
+ idx
* MONO_STAND_ALONE_SIGNATURE_SIZE
;
881 values
[MONO_STAND_ALONE_SIGNATURE
] =
882 mono_dynimage_encode_reflection_sighelper (assembly
, helper
, error
);
883 return_val_if_nok (error
, 0);
889 reflection_cc_to_file (int call_conv
) {
890 switch (call_conv
& 0x3) {
892 case 1: return MONO_CALL_DEFAULT
;
893 case 2: return MONO_CALL_VARARG
;
895 g_assert_not_reached ();
899 #endif /* !DISABLE_REFLECTION_EMIT */
901 struct _ArrayMethod
{
903 MonoMethodSignature
*sig
;
909 mono_sre_array_method_free (ArrayMethod
*am
)
916 #ifndef DISABLE_REFLECTION_EMIT
918 mono_image_get_array_token (MonoDynamicImage
*assembly
, MonoReflectionArrayMethodHandle m
, MonoError
*error
)
920 MonoMethodSignature
*sig
= NULL
;
925 MonoArrayHandle parameters
= MONO_HANDLE_NEW_GET (MonoArray
, m
, parameters
);
926 guint32 nparams
= mono_array_handle_length (parameters
);
927 sig
= (MonoMethodSignature
*)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * nparams
);
929 sig
->sentinelpos
= -1;
930 sig
->call_convention
= reflection_cc_to_file (MONO_HANDLE_GETVAL (m
, call_conv
));
931 sig
->param_count
= nparams
;
932 MonoReflectionTypeHandle ret
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, ret
);
933 if (!MONO_HANDLE_IS_NULL (ret
)) {
934 sig
->ret
= mono_reflection_type_handle_mono_type (ret
, error
);
935 goto_if_nok (error
, fail
);
937 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
939 MonoReflectionTypeHandle parent
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, parent
);
940 MonoType
*mtype
= mono_reflection_type_handle_mono_type (parent
, error
);
941 goto_if_nok (error
, fail
);
943 for (int i
= 0; i
< nparams
; ++i
) {
944 sig
->params
[i
] = mono_type_array_get_and_resolve (parameters
, i
, error
);
945 goto_if_nok (error
, fail
);
948 MonoStringHandle mname
= MONO_HANDLE_NEW_GET (MonoString
, m
, name
);
949 name
= mono_string_handle_to_utf8 (mname
, error
);
950 goto_if_nok (error
, fail
);
952 ArrayMethod
*am
= NULL
;
953 for (GList
*tmp
= assembly
->array_methods
; tmp
; tmp
= tmp
->next
) {
954 am
= (ArrayMethod
*)tmp
->data
;
955 if (strcmp (name
, am
->name
) == 0 &&
956 mono_metadata_type_equal (am
->parent
, mtype
) &&
957 mono_metadata_signature_equal (am
->sig
, sig
)) {
960 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
964 am
= g_new0 (ArrayMethod
, 1);
968 am
->token
= mono_image_get_memberref_token (assembly
, am
->parent
, name
,
969 mono_dynimage_encode_method_signature (assembly
, sig
));
970 assembly
->array_methods
= g_list_prepend (assembly
->array_methods
, am
);
971 MONO_HANDLE_SETVAL (m
, table_idx
, guint32
, am
->token
& 0xffffff);
981 #ifndef DISABLE_REFLECTION_EMIT
984 * mono_image_insert_string:
985 * @module: module builder object
988 * Insert @str into the user string stream of @module.
991 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module
, MonoStringHandle str
, MonoError
*error
)
993 HANDLE_FUNCTION_ENTER ();
999 MonoDynamicImage
*assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1001 if (!mono_image_module_basic_init (ref_module
, error
))
1004 assembly
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1006 g_assert (assembly
!= NULL
);
1008 if (assembly
->save
) {
1009 int32_t length
= mono_string_length (MONO_HANDLE_RAW (str
));
1010 mono_metadata_encode_value (1 | (length
* 2), b
, &b
);
1011 idx
= mono_image_add_stream_data (&assembly
->us
, buf
, b
-buf
);
1013 uint32_t gchandle
= mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject
, str
), TRUE
);
1014 const char *p
= (const char*)mono_string_chars (MONO_HANDLE_RAW (str
));
1015 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1017 char *swapped
= g_malloc (2 * length
);
1019 swap_with_size (swapped
, p
, 2, length
);
1020 mono_image_add_stream_data (&assembly
->us
, swapped
, length
* 2);
1024 mono_image_add_stream_data (&assembly
->us
, p
, length
* 2);
1026 mono_gchandle_free (gchandle
);
1027 mono_image_add_stream_data (&assembly
->us
, "", 1);
1029 idx
= assembly
->us
.index
++;
1032 token
= MONO_TOKEN_STRING
| idx
;
1033 mono_dynamic_image_register_token (assembly
, token
, MONO_HANDLE_CAST (MonoObject
, str
), MONO_DYN_IMAGE_TOK_NEW
);
1036 HANDLE_FUNCTION_RETURN_VAL (token
);
1040 create_method_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1042 guint32 sig_token
, parent
;
1045 int nargs
= mono_array_handle_length (opt_param_types
);
1046 MonoMethodSignature
*old
= mono_method_signature (method
);
1047 MonoMethodSignature
*sig
= mono_metadata_signature_alloc ( &assembly
->image
, old
->param_count
+ nargs
);
1049 sig
->hasthis
= old
->hasthis
;
1050 sig
->explicit_this
= old
->explicit_this
;
1051 sig
->call_convention
= old
->call_convention
;
1052 sig
->generic_param_count
= old
->generic_param_count
;
1053 sig
->param_count
= old
->param_count
+ nargs
;
1054 sig
->sentinelpos
= old
->param_count
;
1055 sig
->ret
= old
->ret
;
1057 for (int i
= 0; i
< old
->param_count
; i
++)
1058 sig
->params
[i
] = old
->params
[i
];
1060 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1061 for (int i
= 0; i
< nargs
; i
++) {
1062 MONO_HANDLE_ARRAY_GETREF (rt
, opt_param_types
, i
);
1063 sig
->params
[old
->param_count
+ i
] = mono_reflection_type_handle_mono_type (rt
, error
);
1064 goto_if_nok (error
, fail
);
1067 parent
= mono_image_typedef_or_ref (assembly
, &method
->klass
->byval_arg
);
1068 g_assert ((parent
& MONO_TYPEDEFORREF_MASK
) == MONO_MEMBERREF_PARENT_TYPEREF
);
1069 parent
>>= MONO_TYPEDEFORREF_BITS
;
1071 parent
<<= MONO_MEMBERREF_PARENT_BITS
;
1072 parent
|= MONO_MEMBERREF_PARENT_TYPEREF
;
1074 sig_token
= mono_dynimage_encode_method_signature (assembly
, sig
);
1075 guint32 token
= mono_image_get_varargs_method_token (assembly
, parent
, method
->name
, sig_token
);
1076 g_hash_table_insert (assembly
->vararg_aux_hash
, GUINT_TO_POINTER (token
), sig
);
1083 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
1089 MonoClass
*klass
= mono_handle_class (obj
);
1090 if (strcmp (klass
->name
, "MonoMethod") == 0 || strcmp (klass
->name
, "MonoCMethod") == 0) {
1091 MonoReflectionMethodHandle ref_method
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1092 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
1093 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types
) && (mono_method_signature (method
)->sentinelpos
>= 0));
1094 token
= create_method_token (assembly
, method
, opt_param_types
, error
);
1095 goto_if_nok (error
, fail
);
1096 } else if (strcmp (klass
->name
, "MethodBuilder") == 0) {
1097 g_assert_not_reached ();
1099 g_error ("requested method token for %s\n", klass
->name
);
1102 mono_dynamic_image_register_token (assembly
, token
, obj
, MONO_DYN_IMAGE_TOK_NEW
);
1105 g_assert (!mono_error_ok (error
));
1110 * mono_image_create_token:
1111 * @assembly: a dynamic assembly
1113 * @register_token: Whenever to register the token in the assembly->tokens hash.
1115 * Get a token to insert in the IL code stream for the given MemberInfo.
1116 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1117 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1121 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
1122 gboolean create_open_instance
, gboolean register_token
,
1125 HANDLE_FUNCTION_ENTER ();
1130 MonoClass
*klass
= mono_handle_class (obj
);
1131 MonoObjectHandle register_obj
= MONO_HANDLE_NEW (MonoObject
, NULL
);
1132 MONO_HANDLE_ASSIGN (register_obj
, obj
);
1134 /* Check for user defined reflection objects */
1135 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1136 if (klass
->image
!= mono_defaults
.corlib
|| (strcmp (klass
->name
, "TypeDelegator") == 0)) {
1137 mono_error_set_not_supported (error
, "User defined subclasses of System.Type are not yet supported");
1141 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1142 int how_collide
= MONO_DYN_IMAGE_TOK_SAME_OK
;
1144 if (strcmp (klass
->name
, "RuntimeType") == 0) {
1145 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, obj
), error
);
1146 goto_if_nok (error
, leave
);
1147 MonoClass
*mc
= mono_class_from_mono_type (type
);
1148 token
= mono_metadata_token_from_dor (
1149 mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, !mono_class_is_gtd (mc
) || create_open_instance
));
1150 /* If it's a RuntimeType now, we could have registered a
1151 * TypeBuilder for it before, so replacing is okay. */
1152 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1153 } else if (strcmp (klass
->name
, "MonoCMethod") == 0 ||
1154 strcmp (klass
->name
, "MonoMethod") == 0) {
1155 MonoReflectionMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionMethod
, obj
);
1156 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
1157 if (method
->is_inflated
) {
1158 if (create_open_instance
) {
1159 guint32 methodspec_token
= mono_image_get_methodspec_token (assembly
, method
);
1160 MonoReflectionMethodHandle canonical_obj
=
1161 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1162 goto_if_nok (error
, leave
);
1163 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1164 token
= methodspec_token
;
1166 token
= mono_image_get_inflated_method_token (assembly
, method
);
1167 } else if ((method
->klass
->image
== &assembly
->image
) &&
1168 !mono_class_is_ginst (method
->klass
) &&
1169 !mono_class_is_gtd (method
->klass
)) {
1170 static guint32 method_table_idx
= 0xffffff;
1171 if (method
->klass
->wastypebuilder
) {
1172 /* we use the same token as the one that was assigned
1173 * to the Methodbuilder.
1174 * FIXME: do the equivalent for Fields.
1176 token
= method
->token
;
1177 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1180 * Each token should have a unique index, but the indexes are
1181 * assigned by managed code, so we don't know about them. An
1182 * easy solution is to count backwards...
1184 method_table_idx
--;
1185 token
= MONO_TOKEN_METHOD_DEF
| method_table_idx
;
1186 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1189 guint32 methodref_token
= mono_image_get_methodref_token (assembly
, method
, create_open_instance
);
1190 /* We need to register a 'canonical' object. The same
1191 * MonoMethod could have been reflected via different
1192 * classes so the MonoReflectionMethod:reftype could be
1193 * different, and the object lookup in
1194 * dynamic_image_register_token would assert assert. So
1195 * we pick the MonoReflectionMethod object that has the
1196 * reflected type as NULL (ie, take the declaring type
1198 MonoReflectionMethodHandle canonical_obj
=
1199 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj
), method
, NULL
, error
);
1200 goto_if_nok (error
, leave
);
1201 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1202 token
= methodref_token
;
1204 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1205 } else if (strcmp (klass
->name
, "MonoField") == 0) {
1206 MonoReflectionFieldHandle f
= MONO_HANDLE_CAST (MonoReflectionField
, obj
);
1207 MonoClassField
*field
= MONO_HANDLE_GETVAL (f
, field
);
1208 if ((field
->parent
->image
== &assembly
->image
) &&
1209 !is_field_on_gtd (field
) &&
1210 !is_field_on_inst (field
)) {
1211 static guint32 field_table_idx
= 0xffffff;
1213 token
= MONO_TOKEN_FIELD_DEF
| field_table_idx
;
1214 g_assert (!mono_class_is_gtd (field
->parent
));
1215 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1217 guint32 fieldref_token
= mono_image_get_fieldref_token (assembly
, field
);
1218 /* Same as methodref: get a canonical object to
1219 * register with the token. */
1220 MonoReflectionFieldHandle canonical_obj
=
1221 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj
), field
->parent
, field
, error
);
1222 goto_if_nok (error
, leave
);
1223 MONO_HANDLE_ASSIGN (register_obj
, canonical_obj
);
1224 token
= fieldref_token
;
1226 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1227 } else if (strcmp (klass
->name
, "MonoArrayMethod") == 0) {
1228 MonoReflectionArrayMethodHandle m
= MONO_HANDLE_CAST (MonoReflectionArrayMethod
, obj
);
1229 /* mono_image_get_array_token caches tokens by signature */
1230 guint32 array_token
= mono_image_get_array_token (assembly
, m
, error
);
1231 goto_if_nok (error
, leave
);
1232 token
= array_token
;
1233 /* ModuleBuilder:GetArrayMethod() always returns a fresh
1234 * MonoArrayMethod instance even given the same method name and
1235 * signature. But they're all interchangeable, so it's okay to
1238 how_collide
= MONO_DYN_IMAGE_TOK_REPLACE
;
1239 } else if (strcmp (klass
->name
, "SignatureHelper") == 0) {
1240 MonoReflectionSigHelperHandle s
= MONO_HANDLE_CAST (MonoReflectionSigHelper
, obj
);
1241 /* always returns a fresh token */
1242 guint32 sig_token
= MONO_TOKEN_SIGNATURE
| mono_image_get_sighelper_token (assembly
, s
, error
);
1243 goto_if_nok (error
, leave
);
1245 how_collide
= MONO_DYN_IMAGE_TOK_NEW
;
1247 g_error ("requested token for %s\n", klass
->name
);
1251 mono_dynamic_image_register_token (assembly
, token
, register_obj
, how_collide
);
1254 HANDLE_FUNCTION_RETURN_VAL (token
);
1260 #ifndef DISABLE_REFLECTION_EMIT
1263 assemblybuilderaccess_can_refonlyload (guint32 access
)
1265 return (access
& 0x4) != 0;
1269 assemblybuilderaccess_can_run (guint32 access
)
1271 return (access
& MonoAssemblyBuilderAccess_Run
) != 0;
1275 assemblybuilderaccess_can_save (guint32 access
)
1277 return (access
& MonoAssemblyBuilderAccess_Save
) != 0;
1282 * mono_reflection_dynimage_basic_init:
1283 * @assembly: an assembly builder object
1285 * Create the MonoImage that represents the assembly builder and setup some
1286 * of the helper hash table and the basic metadata streams.
1289 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
1292 MonoDynamicAssembly
*assembly
;
1293 MonoDynamicImage
*image
;
1294 MonoDomain
*domain
= mono_object_domain (assemblyb
);
1296 if (assemblyb
->dynamic_assembly
)
1299 assembly
= assemblyb
->dynamic_assembly
= g_new0 (MonoDynamicAssembly
, 1);
1301 MONO_PROFILER_RAISE (assembly_loading
, (&assembly
->assembly
));
1303 assembly
->assembly
.ref_count
= 1;
1304 assembly
->assembly
.dynamic
= TRUE
;
1305 assembly
->assembly
.corlib_internal
= assemblyb
->corlib_internal
;
1306 assemblyb
->assembly
.assembly
= (MonoAssembly
*)assembly
;
1307 assembly
->assembly
.basedir
= mono_string_to_utf8_checked (assemblyb
->dir
, &error
);
1308 if (mono_error_set_pending_exception (&error
))
1310 if (assemblyb
->culture
) {
1311 assembly
->assembly
.aname
.culture
= mono_string_to_utf8_checked (assemblyb
->culture
, &error
);
1312 if (mono_error_set_pending_exception (&error
))
1315 assembly
->assembly
.aname
.culture
= g_strdup ("");
1317 if (assemblyb
->version
) {
1318 char *vstr
= mono_string_to_utf8_checked (assemblyb
->version
, &error
);
1319 if (mono_error_set_pending_exception (&error
))
1321 char **version
= g_strsplit (vstr
, ".", 4);
1322 char **parts
= version
;
1323 assembly
->assembly
.aname
.major
= atoi (*parts
++);
1324 assembly
->assembly
.aname
.minor
= atoi (*parts
++);
1325 assembly
->assembly
.aname
.build
= *parts
!= NULL
? atoi (*parts
++) : 0;
1326 assembly
->assembly
.aname
.revision
= *parts
!= NULL
? atoi (*parts
) : 0;
1328 g_strfreev (version
);
1331 assembly
->assembly
.aname
.major
= 0;
1332 assembly
->assembly
.aname
.minor
= 0;
1333 assembly
->assembly
.aname
.build
= 0;
1334 assembly
->assembly
.aname
.revision
= 0;
1337 assembly
->assembly
.ref_only
= assemblybuilderaccess_can_refonlyload (assemblyb
->access
);
1338 assembly
->run
= assemblybuilderaccess_can_run (assemblyb
->access
);
1339 assembly
->save
= assemblybuilderaccess_can_save (assemblyb
->access
);
1340 assembly
->domain
= domain
;
1342 char *assembly_name
= mono_string_to_utf8_checked (assemblyb
->name
, &error
);
1343 if (mono_error_set_pending_exception (&error
))
1345 image
= mono_dynamic_image_create (assembly
, assembly_name
, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1346 image
->initial_image
= TRUE
;
1347 assembly
->assembly
.aname
.name
= image
->image
.name
;
1348 assembly
->assembly
.image
= &image
->image
;
1349 if (assemblyb
->pktoken
&& assemblyb
->pktoken
->max_length
) {
1350 /* -1 to correct for the trailing NULL byte */
1351 if (assemblyb
->pktoken
->max_length
!= MONO_PUBLIC_KEY_TOKEN_LENGTH
- 1) {
1352 g_error ("Public key token length invalid for assembly %s: %i", assembly
->assembly
.aname
.name
, assemblyb
->pktoken
->max_length
);
1354 memcpy (&assembly
->assembly
.aname
.public_key_token
, mono_array_addr (assemblyb
->pktoken
, guint8
, 0), assemblyb
->pktoken
->max_length
);
1357 mono_domain_assemblies_lock (domain
);
1358 domain
->domain_assemblies
= g_slist_append (domain
->domain_assemblies
, assembly
);
1359 mono_domain_assemblies_unlock (domain
);
1361 register_assembly (mono_object_domain (assemblyb
), &assemblyb
->assembly
, &assembly
->assembly
);
1363 MONO_PROFILER_RAISE (assembly_loaded
, (&assembly
->assembly
));
1365 mono_assembly_invoke_load_hook ((MonoAssembly
*)assembly
);
1368 #endif /* !DISABLE_REFLECTION_EMIT */
1370 #ifndef DISABLE_REFLECTION_EMIT
1372 register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
)
1374 return CACHE_OBJECT (MonoReflectionAssembly
*, assembly
, &res
->object
, NULL
);
1377 static MonoReflectionModuleBuilderHandle
1378 register_module (MonoDomain
*domain
, MonoReflectionModuleBuilderHandle res
, MonoDynamicImage
*module
)
1380 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilderHandle
, module
, MONO_HANDLE_CAST (MonoObject
, res
), NULL
);
1384 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1387 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (moduleb
);
1388 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
1389 MonoReflectionAssemblyBuilderHandle ab
= MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder
, NULL
);
1390 MONO_HANDLE_GET (ab
, moduleb
, assemblyb
);
1393 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1394 * we don't know which module it belongs to, since that is only
1395 * determined at assembly save time.
1397 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1398 MonoStringHandle abname
= MONO_HANDLE_NEW_GET (MonoString
, ab
, name
);
1399 char *name
= mono_string_handle_to_utf8 (abname
, error
);
1400 return_val_if_nok (error
, FALSE
);
1401 MonoStringHandle modfqname
= MONO_HANDLE_NEW_GET (MonoString
, MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), fqname
);
1402 char *fqname
= mono_string_handle_to_utf8 (modfqname
, error
);
1403 if (!is_ok (error
)) {
1407 MonoDynamicAssembly
*dynamic_assembly
= MONO_HANDLE_GETVAL (ab
, dynamic_assembly
);
1408 image
= mono_dynamic_image_create (dynamic_assembly
, name
, fqname
);
1410 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule
, moduleb
), image
, MonoImage
*, &image
->image
);
1411 MONO_HANDLE_SETVAL (moduleb
, dynamic_image
, MonoDynamicImage
*, image
);
1412 register_module (domain
, moduleb
, image
);
1414 /* register the module with the assembly */
1415 MonoImage
*ass
= dynamic_assembly
->assembly
.image
;
1416 int module_count
= ass
->module_count
;
1417 MonoImage
**new_modules
= g_new0 (MonoImage
*, module_count
+ 1);
1420 memcpy (new_modules
, ass
->modules
, module_count
* sizeof (MonoImage
*));
1421 new_modules
[module_count
] = &image
->image
;
1422 mono_image_addref (&image
->image
);
1424 g_free (ass
->modules
);
1425 ass
->modules
= new_modules
;
1426 ass
->module_count
++;
1432 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
1435 return image_module_basic_init (moduleb
, error
);
1441 is_corlib_type (MonoClass
*klass
)
1443 return klass
->image
== mono_defaults
.corlib
;
1446 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1447 static MonoClass *cached_class; \
1449 return cached_class == _class; \
1450 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1451 cached_class = _class; \
1459 mono_type_array_get_and_resolve (MonoArrayHandle array
, int idx
, MonoError
*error
)
1461 HANDLE_FUNCTION_ENTER();
1463 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1464 MONO_HANDLE_ARRAY_GETREF (t
, array
, idx
);
1465 MonoType
*result
= mono_reflection_type_handle_mono_type (t
, error
);
1466 HANDLE_FUNCTION_RETURN_VAL (result
);
1470 #ifndef DISABLE_REFLECTION_EMIT
1472 is_sre_array (MonoClass
*klass
)
1474 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ArrayType");
1478 is_sre_byref (MonoClass
*klass
)
1480 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ByRefType");
1484 is_sre_pointer (MonoClass
*klass
)
1486 check_corlib_type_cached (klass
, "System.Reflection.Emit", "PointerType");
1490 is_sre_generic_instance (MonoClass
*klass
)
1492 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilderInstantiation");
1496 is_sre_type_builder (MonoClass
*klass
)
1498 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilder");
1502 is_sre_method_builder (MonoClass
*klass
)
1504 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodBuilder");
1508 mono_is_sre_ctor_builder (MonoClass
*klass
)
1510 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorBuilder");
1514 is_sre_field_builder (MonoClass
*klass
)
1516 check_corlib_type_cached (klass
, "System.Reflection.Emit", "FieldBuilder");
1520 is_sre_gparam_builder (MonoClass
*klass
)
1522 check_corlib_type_cached (klass
, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1526 is_sre_enum_builder (MonoClass
*klass
)
1528 check_corlib_type_cached (klass
, "System.Reflection.Emit", "EnumBuilder");
1532 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1534 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1538 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1540 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1543 static MonoReflectionTypeHandle
1544 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t
, MonoError
*error
)
1546 static MonoMethod
*method_get_underlying_system_type
= NULL
;
1547 HANDLE_FUNCTION_ENTER ();
1551 if (!method_get_underlying_system_type
)
1552 method_get_underlying_system_type
= mono_class_get_method_from_name (mono_defaults
.systemtype_class
, "get_UnderlyingSystemType", 0);
1554 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1556 MonoMethod
*usertype_method
= mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject
, t
), method_get_underlying_system_type
, error
);
1557 goto_if_nok (error
, leave
);
1559 MONO_HANDLE_ASSIGN (rt
, MONO_HANDLE_NEW (MonoReflectionType
, mono_runtime_invoke_checked (usertype_method
, MONO_HANDLE_RAW (t
), NULL
, error
)));
1562 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType
, rt
);
1566 mono_reflection_type_get_handle (MonoReflectionType
* ref_raw
, MonoError
*error
)
1568 HANDLE_FUNCTION_ENTER ();
1570 MONO_HANDLE_DCL (MonoReflectionType
, ref
);
1571 MonoType
*result
= mono_reflection_type_handle_mono_type (ref
, error
);
1572 HANDLE_FUNCTION_RETURN_VAL (result
);
1576 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass
, MonoError
*error
)
1578 HANDLE_FUNCTION_ENTER ();
1579 MonoType
*result
= NULL
;
1580 MonoType
**types
= NULL
;
1582 MonoArrayHandle typeargs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_gclass
, type_arguments
);
1583 int count
= mono_array_handle_length (typeargs
);
1584 types
= g_new0 (MonoType
*, count
);
1585 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1586 for (int i
= 0; i
< count
; ++i
) {
1587 MONO_HANDLE_ARRAY_GETREF (t
, typeargs
, i
);
1588 types
[i
] = mono_reflection_type_handle_mono_type (t
, error
);
1589 if (!types
[i
] || !is_ok (error
)) {
1593 /* Need to resolve the generic_type in order for it to create its generic context. */
1594 MonoReflectionTypeHandle ref_gtd
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_gclass
, generic_type
);
1595 MonoType
*gtd
= mono_reflection_type_handle_mono_type (ref_gtd
, error
);
1596 goto_if_nok (error
, leave
);
1597 MonoClass
*gtd_klass
= mono_class_from_mono_type (gtd
);
1598 if (is_sre_type_builder (mono_handle_class (ref_gtd
))) {
1599 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_gtd
), error
);
1600 goto_if_nok (error
, leave
);
1602 g_assert (count
== 0 || mono_class_is_gtd (gtd_klass
));
1603 result
= mono_reflection_bind_generic_parameters (ref_gtd
, count
, types
, error
);
1604 goto_if_nok (error
, leave
);
1606 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gclass
), type
, MonoType
*, result
);
1609 HANDLE_FUNCTION_RETURN_VAL (result
);
1613 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam
, MonoError
*error
)
1615 HANDLE_FUNCTION_ENTER ();
1617 MonoType
*result
= NULL
;
1620 MonoReflectionTypeBuilderHandle ref_tbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder
, ref_gparam
, tbuilder
);
1621 MonoReflectionModuleBuilderHandle ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tbuilder
, module
);
1622 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
1623 MonoImage
*image
= &dynamic_image
->image
;
1625 MonoGenericParamFull
*param
= mono_image_new0 (image
, MonoGenericParamFull
, 1);
1627 MonoStringHandle ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_gparam
, name
);
1628 param
->info
.name
= mono_string_to_utf8_image (image
, ref_name
, error
);
1629 mono_error_assert_ok (error
);
1630 param
->param
.num
= MONO_HANDLE_GETVAL (ref_gparam
, index
);
1632 MonoReflectionMethodBuilderHandle ref_mbuilder
= MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder
, ref_gparam
, mbuilder
);
1633 if (!MONO_HANDLE_IS_NULL (ref_mbuilder
)) {
1634 MonoGenericContainer
*generic_container
= MONO_HANDLE_GETVAL (ref_mbuilder
, generic_container
);
1635 if (!generic_container
) {
1636 generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (image
, sizeof (MonoGenericContainer
));
1637 generic_container
->is_method
= TRUE
;
1639 * Cannot set owner.method, since the MonoMethod is not created yet.
1640 * Set the image field instead, so type_in_image () works.
1642 generic_container
->is_anonymous
= TRUE
;
1643 generic_container
->owner
.image
= image
;
1644 MONO_HANDLE_SETVAL (ref_mbuilder
, generic_container
, MonoGenericContainer
*, generic_container
);
1646 param
->param
.owner
= generic_container
;
1648 MonoType
*type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_tbuilder
), error
);
1649 goto_if_nok (error
, leave
);
1650 MonoClass
*owner
= mono_class_from_mono_type (type
);
1651 g_assert (mono_class_is_gtd (owner
));
1652 param
->param
.owner
= mono_class_get_generic_container (owner
);
1655 MonoClass
*pklass
= mono_class_from_generic_parameter_internal ((MonoGenericParam
*) param
);
1657 result
= &pklass
->byval_arg
;
1659 mono_class_set_ref_info (pklass
, MONO_HANDLE_CAST (MonoObject
, ref_gparam
));
1660 mono_image_append_class_to_reflection_info_set (pklass
);
1662 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), type
, MonoType
*, result
);
1665 HANDLE_FUNCTION_RETURN_VAL (result
);
1669 mono_type_array_get_and_resolve_raw (MonoArray
* array_raw
, int idx
, MonoError
*error
)
1671 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1673 MONO_HANDLE_DCL (MonoArray
, array
);
1674 MonoType
*result
= mono_type_array_get_and_resolve (array
, idx
, error
);
1675 HANDLE_FUNCTION_RETURN_VAL (result
);
1679 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
1681 HANDLE_FUNCTION_ENTER ();
1684 MonoType
* result
= NULL
;
1687 if (MONO_HANDLE_IS_NULL (ref
))
1689 MonoType
*t
= MONO_HANDLE_GETVAL (ref
, type
);
1695 if (mono_reflection_is_usertype (ref
)) {
1696 MONO_HANDLE_ASSIGN (ref
, mono_reflection_type_get_underlying_system_type (ref
, error
));
1697 if (!is_ok (error
) || MONO_HANDLE_IS_NULL (ref
) || mono_reflection_is_usertype (ref
))
1699 t
= MONO_HANDLE_GETVAL (ref
, type
);
1706 MonoClass
*klass
= mono_handle_class (ref
);
1708 if (is_sre_array (klass
)) {
1709 MonoReflectionArrayTypeHandle sre_array
= MONO_HANDLE_CAST (MonoReflectionArrayType
, ref
);
1710 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_array
, element_type
);
1711 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1712 goto_if_nok (error
, leave
);
1714 gint32 rank
= MONO_HANDLE_GETVAL (sre_array
, rank
);
1715 MonoClass
*eclass
= mono_class_from_mono_type (base
);
1716 result
= mono_image_new0 (eclass
->image
, MonoType
, 1);
1718 result
->type
= MONO_TYPE_SZARRAY
;
1719 result
->data
.klass
= eclass
;
1721 MonoArrayType
*at
= (MonoArrayType
*)mono_image_alloc0 (eclass
->image
, sizeof (MonoArrayType
));
1722 result
->type
= MONO_TYPE_ARRAY
;
1723 result
->data
.array
= at
;
1724 at
->eklass
= eclass
;
1727 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1728 } else if (is_sre_byref (klass
)) {
1729 MonoReflectionDerivedTypeHandle sre_byref
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1730 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_byref
, element_type
);
1731 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1732 goto_if_nok (error
, leave
);
1734 result
= &mono_class_from_mono_type (base
)->this_arg
;
1735 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1736 } else if (is_sre_pointer (klass
)) {
1737 MonoReflectionDerivedTypeHandle sre_pointer
= MONO_HANDLE_CAST (MonoReflectionDerivedType
, ref
);
1738 MonoReflectionTypeHandle ref_element
= MONO_HANDLE_NEW_GET (MonoReflectionType
, sre_pointer
, element_type
);
1739 MonoType
*base
= mono_reflection_type_handle_mono_type (ref_element
, error
);
1740 goto_if_nok (error
, leave
);
1742 result
= &mono_ptr_class_get (base
)->byval_arg
;
1743 MONO_HANDLE_SETVAL (ref
, type
, MonoType
*, result
);
1744 } else if (is_sre_generic_instance (klass
)) {
1745 result
= reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass
, ref
), error
);
1746 } else if (is_sre_gparam_builder (klass
)) {
1747 result
= reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam
, ref
), error
);
1748 } else if (is_sre_enum_builder (klass
)) {
1749 MonoReflectionEnumBuilderHandle ref_ebuilder
= MONO_HANDLE_CAST (MonoReflectionEnumBuilder
, ref
);
1751 MonoReflectionTypeHandle ref_tb
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_ebuilder
, tb
);
1752 result
= mono_reflection_type_handle_mono_type (ref_tb
, error
);
1753 } else if (is_sre_type_builder (klass
)) {
1754 MonoReflectionTypeBuilderHandle ref_tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref
);
1756 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1757 reflection_setup_internal_class (ref_tb
, error
);
1758 mono_error_assert_ok (error
);
1759 result
= MONO_HANDLE_GETVAL (ref
, type
);
1761 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref
)->byval_arg
));
1764 HANDLE_FUNCTION_RETURN_VAL (result
);
1768 * LOCKING: Assumes the loader lock is held.
1770 static MonoMethodSignature
*
1771 parameters_to_signature (MonoImage
*image
, MonoArrayHandle parameters
, MonoError
*error
) {
1772 MonoMethodSignature
*sig
;
1777 count
= MONO_HANDLE_IS_NULL (parameters
) ? 0 : mono_array_handle_length (parameters
);
1779 sig
= (MonoMethodSignature
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * count
);
1780 sig
->param_count
= count
;
1781 sig
->sentinelpos
= -1; /* FIXME */
1782 for (i
= 0; i
< count
; ++i
) {
1783 sig
->params
[i
] = mono_type_array_get_and_resolve (parameters
, i
, error
);
1784 if (!is_ok (error
)) {
1785 image_g_free (image
, sig
);
1793 * LOCKING: Assumes the loader lock is held.
1795 static MonoMethodSignature
*
1796 ctor_builder_to_signature (MonoImage
*image
, MonoReflectionCtorBuilderHandle ctor
, MonoError
*error
) {
1797 MonoMethodSignature
*sig
;
1801 sig
= parameters_to_signature (image
, MONO_HANDLE_NEW_GET (MonoArray
, ctor
, parameters
), error
);
1802 return_val_if_nok (error
, NULL
);
1803 sig
->hasthis
= MONO_HANDLE_GETVAL (ctor
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1804 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1808 static MonoMethodSignature
*
1809 ctor_builder_to_signature_raw (MonoImage
*image
, MonoReflectionCtorBuilder
* ctor_raw
, MonoError
*error
) {
1810 HANDLE_FUNCTION_ENTER();
1811 MONO_HANDLE_DCL (MonoReflectionCtorBuilder
, ctor
);
1812 MonoMethodSignature
*sig
= ctor_builder_to_signature (image
, ctor
, error
);
1813 HANDLE_FUNCTION_RETURN_VAL (sig
);
1816 * LOCKING: Assumes the loader lock is held.
1818 static MonoMethodSignature
*
1819 method_builder_to_signature (MonoImage
*image
, MonoReflectionMethodBuilderHandle method
, MonoError
*error
) {
1820 MonoMethodSignature
*sig
;
1824 sig
= parameters_to_signature (image
, MONO_HANDLE_NEW_GET(MonoArray
, method
, parameters
), error
);
1825 return_val_if_nok (error
, NULL
);
1826 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1827 MonoReflectionTypeHandle rtype
= MONO_HANDLE_NEW_GET (MonoReflectionType
, method
, rtype
);
1828 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1829 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1830 if (!is_ok (error
)) {
1831 image_g_free (image
, sig
);
1835 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1837 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, method
, generic_params
);
1838 sig
->generic_param_count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
1842 static MonoMethodSignature
*
1843 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method
, MonoError
*error
) {
1844 HANDLE_FUNCTION_ENTER ();
1845 MonoMethodSignature
*sig
= NULL
;
1849 sig
= parameters_to_signature (NULL
, MONO_HANDLE_NEW_GET (MonoArray
, method
, parameters
), error
);
1850 goto_if_nok (error
, leave
);
1851 sig
->hasthis
= MONO_HANDLE_GETVAL (method
, attrs
) & METHOD_ATTRIBUTE_STATIC
? 0: 1;
1852 MonoReflectionTypeHandle rtype
= MONO_HANDLE_NEW_GET (MonoReflectionType
, method
, rtype
);
1853 if (!MONO_HANDLE_IS_NULL (rtype
)) {
1854 sig
->ret
= mono_reflection_type_handle_mono_type (rtype
, error
);
1855 if (!is_ok (error
)) {
1861 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1863 sig
->generic_param_count
= 0;
1865 HANDLE_FUNCTION_RETURN_VAL (sig
);
1869 get_prop_name_and_type (MonoObject
*prop
, char **name
, MonoType
**type
, MonoError
*error
)
1872 MonoClass
*klass
= mono_object_class (prop
);
1873 if (strcmp (klass
->name
, "PropertyBuilder") == 0) {
1874 MonoReflectionPropertyBuilder
*pb
= (MonoReflectionPropertyBuilder
*)prop
;
1875 *name
= mono_string_to_utf8_checked (pb
->name
, error
);
1876 return_if_nok (error
);
1877 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)pb
->type
, error
);
1879 MonoReflectionProperty
*p
= (MonoReflectionProperty
*)prop
;
1880 *name
= g_strdup (p
->property
->name
);
1881 if (p
->property
->get
)
1882 *type
= mono_method_signature (p
->property
->get
)->ret
;
1884 *type
= mono_method_signature (p
->property
->set
)->params
[mono_method_signature (p
->property
->set
)->param_count
- 1];
1889 get_field_name_and_type (MonoObject
*field
, char **name
, MonoType
**type
, MonoError
*error
)
1892 MonoClass
*klass
= mono_object_class (field
);
1893 if (strcmp (klass
->name
, "FieldBuilder") == 0) {
1894 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)field
;
1895 *name
= mono_string_to_utf8_checked (fb
->name
, error
);
1896 return_if_nok (error
);
1897 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
1899 MonoReflectionField
*f
= (MonoReflectionField
*)field
;
1900 *name
= g_strdup (mono_field_get_name (f
->field
));
1901 *type
= f
->field
->type
;
1905 #else /* DISABLE_REFLECTION_EMIT */
1908 is_sre_type_builder (MonoClass
*klass
)
1914 is_sre_generic_instance (MonoClass
*klass
)
1920 mono_is_sre_ctor_builder (MonoClass
*klass
)
1926 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1932 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1937 #endif /* !DISABLE_REFLECTION_EMIT */
1941 is_sr_mono_field (MonoClass
*klass
)
1943 check_corlib_type_cached (klass
, "System.Reflection", "MonoField");
1947 mono_is_sr_mono_property (MonoClass
*klass
)
1949 check_corlib_type_cached (klass
, "System.Reflection", "MonoProperty");
1953 is_sr_mono_method (MonoClass
*klass
)
1955 check_corlib_type_cached (klass
, "System.Reflection", "MonoMethod");
1959 mono_is_sr_mono_cmethod (MonoClass
*klass
)
1961 check_corlib_type_cached (klass
, "System.Reflection", "MonoCMethod");
1965 mono_class_is_reflection_method_or_constructor (MonoClass
*klass
)
1967 return is_sr_mono_method (klass
) || mono_is_sr_mono_cmethod (klass
);
1971 mono_is_sre_type_builder (MonoClass
*klass
)
1973 return is_sre_type_builder (klass
);
1977 mono_is_sre_generic_instance (MonoClass
*klass
)
1979 return is_sre_generic_instance (klass
);
1985 * encode_cattr_value:
1986 * Encode a value in a custom attribute stream of bytes.
1987 * The value to encode is either supplied as an object in argument val
1988 * (valuetypes are boxed), or as a pointer to the data in the
1990 * @type represents the type of the value
1991 * @buffer is the start of the buffer
1992 * @p the current position in the buffer
1993 * @buflen contains the size of the buffer and is used to return the new buffer size
1994 * if this needs to be realloced.
1995 * @retbuffer and @retp return the start and the position of the buffer
1996 * @error set on error.
1999 encode_cattr_value (MonoAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, MonoObject
*arg
, char *argval
, MonoError
*error
)
2001 MonoTypeEnum simple_type
;
2004 if ((p
-buffer
) + 10 >= *buflen
) {
2007 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2008 p
= newbuf
+ (p
-buffer
);
2012 argval
= ((char*)arg
+ sizeof (MonoObject
));
2013 simple_type
= type
->type
;
2015 switch (simple_type
) {
2016 case MONO_TYPE_BOOLEAN
:
2021 case MONO_TYPE_CHAR
:
2024 swap_with_size (p
, argval
, 2, 1);
2030 swap_with_size (p
, argval
, 4, 1);
2034 swap_with_size (p
, argval
, 8, 1);
2039 swap_with_size (p
, argval
, 8, 1);
2042 case MONO_TYPE_VALUETYPE
:
2043 if (type
->data
.klass
->enumtype
) {
2044 simple_type
= mono_class_enum_basetype (type
->data
.klass
)->type
;
2047 g_warning ("generic valutype %s not handled in custom attr value decoding", type
->data
.klass
->name
);
2050 case MONO_TYPE_STRING
: {
2057 str
= mono_string_to_utf8_checked ((MonoString
*)arg
, error
);
2058 return_if_nok (error
);
2059 slen
= strlen (str
);
2060 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2064 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2065 p
= newbuf
+ (p
-buffer
);
2068 mono_metadata_encode_value (slen
, p
, &p
);
2069 memcpy (p
, str
, slen
);
2074 case MONO_TYPE_CLASS
: {
2083 arg_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)arg
, error
);
2084 return_if_nok (error
);
2086 str
= type_get_qualified_name (arg_type
, NULL
);
2087 slen
= strlen (str
);
2088 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2092 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2093 p
= newbuf
+ (p
-buffer
);
2096 mono_metadata_encode_value (slen
, p
, &p
);
2097 memcpy (p
, str
, slen
);
2102 case MONO_TYPE_SZARRAY
: {
2104 MonoClass
*eclass
, *arg_eclass
;
2107 *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff;
2110 len
= mono_array_length ((MonoArray
*)arg
);
2112 *p
++ = (len
>> 8) & 0xff;
2113 *p
++ = (len
>> 16) & 0xff;
2114 *p
++ = (len
>> 24) & 0xff;
2116 *retbuffer
= buffer
;
2117 eclass
= type
->data
.klass
;
2118 arg_eclass
= mono_object_class (arg
)->element_class
;
2121 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2122 eclass
= mono_defaults
.object_class
;
2124 if (eclass
== mono_defaults
.object_class
&& arg_eclass
->valuetype
) {
2125 char *elptr
= mono_array_addr ((MonoArray
*)arg
, char, 0);
2126 int elsize
= mono_class_array_element_size (arg_eclass
);
2127 for (i
= 0; i
< len
; ++i
) {
2128 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &arg_eclass
->byval_arg
, NULL
, elptr
, error
);
2129 return_if_nok (error
);
2132 } else if (eclass
->valuetype
&& arg_eclass
->valuetype
) {
2133 char *elptr
= mono_array_addr ((MonoArray
*)arg
, char, 0);
2134 int elsize
= mono_class_array_element_size (eclass
);
2135 for (i
= 0; i
< len
; ++i
) {
2136 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &eclass
->byval_arg
, NULL
, elptr
, error
);
2137 return_if_nok (error
);
2141 for (i
= 0; i
< len
; ++i
) {
2142 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &eclass
->byval_arg
, mono_array_get ((MonoArray
*)arg
, MonoObject
*, i
), NULL
, error
);
2143 return_if_nok (error
);
2148 case MONO_TYPE_OBJECT
: {
2154 * The parameter type is 'object' but the type of the actual
2155 * argument is not. So we have to add type information to the blob
2156 * too. This is completely undocumented in the spec.
2160 *p
++ = MONO_TYPE_STRING
; // It's same hack as MS uses
2165 klass
= mono_object_class (arg
);
2167 if (mono_object_isinst_checked (arg
, mono_defaults
.systemtype_class
, error
)) {
2171 return_if_nok (error
);
2174 if (klass
->enumtype
) {
2176 } else if (klass
== mono_defaults
.string_class
) {
2177 simple_type
= MONO_TYPE_STRING
;
2180 } else if (klass
->rank
== 1) {
2182 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_OBJECT
)
2183 /* See Partition II, Appendix B3 */
2186 *p
++ = klass
->element_class
->byval_arg
.type
;
2187 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &klass
->byval_arg
, arg
, NULL
, error
);
2188 return_if_nok (error
);
2190 } else if (klass
->byval_arg
.type
>= MONO_TYPE_BOOLEAN
&& klass
->byval_arg
.type
<= MONO_TYPE_R8
) {
2191 *p
++ = simple_type
= klass
->byval_arg
.type
;
2194 g_error ("unhandled type in custom attr");
2196 str
= type_get_qualified_name (mono_class_get_type(klass
), NULL
);
2197 slen
= strlen (str
);
2198 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2202 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2203 p
= newbuf
+ (p
-buffer
);
2206 mono_metadata_encode_value (slen
, p
, &p
);
2207 memcpy (p
, str
, slen
);
2210 simple_type
= mono_class_enum_basetype (klass
)->type
;
2214 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type
);
2217 *retbuffer
= buffer
;
2221 encode_field_or_prop_type (MonoType
*type
, char *p
, char **retp
)
2223 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2224 char *str
= type_get_qualified_name (type
, NULL
);
2225 int slen
= strlen (str
);
2229 * This seems to be optional...
2232 mono_metadata_encode_value (slen
, p
, &p
);
2233 memcpy (p
, str
, slen
);
2236 } else if (type
->type
== MONO_TYPE_OBJECT
) {
2238 } else if (type
->type
== MONO_TYPE_CLASS
) {
2239 /* it should be a type: encode_cattr_value () has the check */
2242 mono_metadata_encode_value (type
->type
, p
, &p
);
2243 if (type
->type
== MONO_TYPE_SZARRAY
)
2244 /* See the examples in Partition VI, Annex B */
2245 encode_field_or_prop_type (&type
->data
.klass
->byval_arg
, p
, &p
);
2251 #ifndef DISABLE_REFLECTION_EMIT
2253 encode_named_val (MonoReflectionAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, char *name
, MonoObject
*value
, MonoError
*error
)
2259 /* Preallocate a large enough buffer */
2260 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2261 char *str
= type_get_qualified_name (type
, NULL
);
2264 } else if (type
->type
== MONO_TYPE_SZARRAY
&& type
->data
.klass
->enumtype
) {
2265 char *str
= type_get_qualified_name (&type
->data
.klass
->byval_arg
, NULL
);
2271 len
+= strlen (name
);
2273 if ((p
-buffer
) + 20 + len
>= *buflen
) {
2277 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2278 p
= newbuf
+ (p
-buffer
);
2282 encode_field_or_prop_type (type
, p
, &p
);
2284 len
= strlen (name
);
2285 mono_metadata_encode_value (len
, p
, &p
);
2286 memcpy (p
, name
, len
);
2288 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, buflen
, type
, value
, NULL
, error
);
2289 return_if_nok (error
);
2291 *retbuffer
= buffer
;
2295 * mono_reflection_get_custom_attrs_blob:
2296 * \param ctor custom attribute constructor
2297 * \param ctorArgs arguments o the constructor
2301 * \param fieldValues
2302 * Creates the blob of data that needs to be saved in the metadata and that represents
2303 * the custom attributed described by \p ctor, \p ctorArgs etc.
2304 * \returns a \c Byte array representing the blob of data.
2307 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
2310 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, &error
);
2311 mono_error_cleanup (&error
);
2316 * mono_reflection_get_custom_attrs_blob_checked:
2317 * \param ctor custom attribute constructor
2318 * \param ctorArgs arguments o the constructor
2322 * \param fieldValues
2323 * \param error set on error
2324 * Creates the blob of data that needs to be saved in the metadata and that represents
2325 * the custom attributed described by \p ctor, \p ctorArgs etc.
2326 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2329 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
, MonoError
*error
)
2331 MonoArray
*result
= NULL
;
2332 MonoMethodSignature
*sig
;
2339 if (strcmp (ctor
->vtable
->klass
->name
, "MonoCMethod")) {
2340 /* sig is freed later so allocate it in the heap */
2341 sig
= ctor_builder_to_signature_raw (NULL
, (MonoReflectionCtorBuilder
*)ctor
, error
); /* FIXME use handles */
2342 if (!is_ok (error
)) {
2347 sig
= mono_method_signature (((MonoReflectionMethod
*)ctor
)->method
);
2350 g_assert (mono_array_length (ctorArgs
) == sig
->param_count
);
2352 p
= buffer
= (char *)g_malloc (buflen
);
2353 /* write the prolog */
2356 for (i
= 0; i
< sig
->param_count
; ++i
) {
2357 arg
= mono_array_get (ctorArgs
, MonoObject
*, i
);
2358 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, &buflen
, sig
->params
[i
], arg
, NULL
, error
);
2359 goto_if_nok (error
, leave
);
2363 i
+= mono_array_length (properties
);
2365 i
+= mono_array_length (fields
);
2367 *p
++ = (i
>> 8) & 0xff;
2370 for (i
= 0; i
< mono_array_length (properties
); ++i
) {
2374 prop
= (MonoObject
*)mono_array_get (properties
, gpointer
, i
);
2375 get_prop_name_and_type (prop
, &pname
, &ptype
, error
);
2376 goto_if_nok (error
, leave
);
2377 *p
++ = 0x54; /* PROPERTY signature */
2378 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ptype
, pname
, (MonoObject
*)mono_array_get (propValues
, gpointer
, i
), error
);
2380 goto_if_nok (error
, leave
);
2386 for (i
= 0; i
< mono_array_length (fields
); ++i
) {
2390 field
= (MonoObject
*)mono_array_get (fields
, gpointer
, i
);
2391 get_field_name_and_type (field
, &fname
, &ftype
, error
);
2392 goto_if_nok (error
, leave
);
2393 *p
++ = 0x53; /* FIELD signature */
2394 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ftype
, fname
, (MonoObject
*)mono_array_get (fieldValues
, gpointer
, i
), error
);
2396 goto_if_nok (error
, leave
);
2400 g_assert (p
- buffer
<= buflen
);
2401 buflen
= p
- buffer
;
2402 result
= mono_array_new_checked (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
2403 goto_if_nok (error
, leave
);
2404 p
= mono_array_addr (result
, char, 0);
2405 memcpy (p
, buffer
, buflen
);
2408 if (strcmp (ctor
->vtable
->klass
->name
, "MonoCMethod"))
2414 reflection_setup_class_hierarchy (GHashTable
*unparented
, MonoError
*error
)
2418 mono_loader_lock ();
2420 MonoType
*parent_type
;
2421 MonoType
*child_type
;
2422 GHashTableIter iter
;
2424 g_hash_table_iter_init (&iter
, unparented
);
2426 while (g_hash_table_iter_next (&iter
, (gpointer
*) &child_type
, (gpointer
*) &parent_type
)) {
2427 MonoClass
*child_class
= mono_class_from_mono_type (child_type
);
2428 if (parent_type
!= NULL
) {
2429 MonoClass
*parent_class
= mono_class_from_mono_type (parent_type
);
2430 child_class
->parent
= NULL
;
2431 /* fool mono_class_setup_parent */
2432 child_class
->supertypes
= NULL
;
2433 mono_class_setup_parent (child_class
, parent_class
);
2434 } else if (strcmp (child_class
->name
, "Object") == 0 && strcmp (child_class
->name_space
, "System") == 0) {
2435 const char *old_n
= child_class
->name
;
2436 /* trick to get relative numbering right when compiling corlib */
2437 child_class
->name
= "BuildingObject";
2438 mono_class_setup_parent (child_class
, mono_defaults
.object_class
);
2439 child_class
->name
= old_n
;
2441 mono_class_setup_mono_type (child_class
);
2442 mono_class_setup_supertypes (child_class
);
2445 mono_loader_unlock ();
2446 return is_ok (error
);
2450 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2452 HANDLE_FUNCTION_ENTER ();
2455 mono_loader_lock ();
2457 gint32 entering_state
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_tb
), state
);
2458 if (entering_state
!= MonoTypeBuilderNew
) {
2459 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
));
2463 MONO_HANDLE_SETVAL (ref_tb
, state
, MonoTypeBuilderState
, MonoTypeBuilderEntered
);
2464 MonoReflectionModuleBuilderHandle module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2465 GHashTable
*unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
2467 // If this type is already setup, exit. We'll fix the parenting later
2468 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2472 MonoReflectionModuleBuilderHandle ref_module
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
2473 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (ref_module
, dynamic_image
);
2475 MonoStringHandle ref_name
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, name
);
2476 MonoStringHandle ref_nspace
= MONO_HANDLE_NEW_GET (MonoString
, ref_tb
, nspace
);
2478 guint32 table_idx
= MONO_HANDLE_GETVAL (ref_tb
, table_idx
);
2480 * The size calculation here warrants some explaining.
2481 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2482 * meaning we need to alloc enough space to morth a def into a gtd.
2484 MonoClass
*klass
= (MonoClass
*)mono_image_alloc0 (&dynamic_image
->image
, MAX (sizeof (MonoClassDef
), sizeof (MonoClassGtd
)));
2485 klass
->class_kind
= MONO_CLASS_DEF
;
2487 klass
->image
= &dynamic_image
->image
;
2489 klass
->inited
= 1; /* we lie to the runtime */
2490 klass
->name
= mono_string_to_utf8_image (klass
->image
, ref_name
, error
);
2491 goto_if_nok (error
, leave
);
2492 klass
->name_space
= mono_string_to_utf8_image (klass
->image
, ref_nspace
, error
);
2493 goto_if_nok (error
, leave
);
2494 klass
->type_token
= MONO_TOKEN_TYPE_DEF
| table_idx
;
2495 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
2497 MONO_PROFILER_RAISE (class_loading
, (klass
));
2499 klass
->element_class
= klass
;
2501 g_assert (!mono_class_has_ref_info (klass
));
2502 mono_class_set_ref_info (klass
, MONO_HANDLE_CAST (MonoObject
, ref_tb
));
2504 MonoReflectionTypeHandle ref_nesting_type
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_tb
, nesting_type
);
2505 /* Put into cache so mono_class_get_checked () will find it.
2506 Skip nested types as those should not be available on the global scope. */
2507 if (MONO_HANDLE_IS_NULL (ref_nesting_type
))
2508 mono_image_add_to_name_cache (klass
->image
, klass
->name_space
, klass
->name
, table_idx
);
2511 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2512 by performing a mono_class_get which does the full resolution.
2514 Working around this semantics would require us to write a lot of code for no clear advantage.
2516 mono_image_append_class_to_reflection_info_set (klass
);
2518 mono_dynamic_image_register_token (dynamic_image
, MONO_TOKEN_TYPE_DEF
| table_idx
, MONO_HANDLE_CAST (MonoObject
, ref_tb
), MONO_DYN_IMAGE_TOK_NEW
);
2520 if ((!strcmp (klass
->name
, "ValueType") && !strcmp (klass
->name_space
, "System")) ||
2521 (!strcmp (klass
->name
, "Object") && !strcmp (klass
->name_space
, "System")) ||
2522 (!strcmp (klass
->name
, "Enum") && !strcmp (klass
->name_space
, "System"))) {
2523 klass
->instance_size
= sizeof (MonoObject
);
2524 klass
->size_inited
= 1;
2525 mono_class_setup_vtable_general (klass
, NULL
, 0, NULL
);
2528 mono_class_setup_mono_type (klass
);
2531 * FIXME: handle interfaces.
2533 MonoReflectionTypeHandle ref_tb_type
= MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
);
2534 MONO_HANDLE_SETVAL (ref_tb_type
, type
, MonoType
*, &klass
->byval_arg
);
2535 MONO_HANDLE_SETVAL (ref_tb
, state
, gint32
, MonoTypeBuilderFinished
);
2537 reflection_init_generic_class (ref_tb
, error
);
2538 goto_if_nok (error
, leave
);
2540 // Do here so that the search inside of the parent can see the above type that's been set.
2541 MonoReflectionTypeHandle ref_parent
= MONO_HANDLE_NEW_GET (MonoReflectionType
, ref_tb
, parent
);
2542 MonoType
*parent_type
= NULL
;
2543 if (!MONO_HANDLE_IS_NULL (ref_parent
)) {
2544 MonoClass
*parent_klass
= mono_handle_class (ref_parent
);
2545 gboolean recursive_init
= TRUE
;
2547 if (is_sre_type_builder (parent_klass
)) {
2548 MonoTypeBuilderState parent_state
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_parent
), state
);
2550 if (parent_state
!= MonoTypeBuilderNew
) {
2551 // Initialize types reachable from parent recursively
2552 // We'll fix the type hierarchy later
2553 recursive_init
= FALSE
;
2557 if (recursive_init
) {
2558 // If we haven't encountered a cycle, force the creation of ref_parent's type
2559 mono_reflection_type_handle_mono_type (ref_parent
, error
);
2560 goto_if_nok (error
, leave
);
2563 parent_type
= MONO_HANDLE_GETVAL (ref_parent
, type
);
2565 // If we failed to create the parent, fail the child
2570 // Push the child type and parent type to process later
2571 // Note: parent_type may be null.
2572 g_assert (!g_hash_table_lookup (unparented_classes
, &klass
->byval_arg
));
2573 g_hash_table_insert (unparented_classes
, &klass
->byval_arg
, parent_type
);
2575 if (!MONO_HANDLE_IS_NULL (ref_nesting_type
)) {
2576 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_nesting_type
), error
))
2579 MonoType
*nesting_type
= mono_reflection_type_handle_mono_type (ref_nesting_type
, error
);
2580 goto_if_nok (error
, leave
);
2581 klass
->nested_in
= mono_class_from_mono_type (nesting_type
);
2584 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2586 MONO_PROFILER_RAISE (class_loaded
, (klass
));
2589 mono_loader_unlock ();
2590 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2594 * reflection_init_generic_class:
2595 * @tb: a TypeBuilder object
2596 * @error: set on error
2598 * Creates the generic class after all generic parameters have been added.
2599 * On success returns TRUE, on failure returns FALSE and sets @error.
2601 * This assumes that reflection_setup_internal_class has already set up
2605 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
2607 HANDLE_FUNCTION_ENTER ();
2611 MonoTypeBuilderState ref_state
= MONO_HANDLE_GETVAL (ref_tb
, state
);
2612 g_assert (ref_state
== MonoTypeBuilderFinished
);
2614 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
2615 MonoClass
*klass
= mono_class_from_mono_type (type
);
2617 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
2618 int count
= MONO_HANDLE_IS_NULL (generic_params
) ? 0 : mono_array_handle_length (generic_params
);
2623 if (mono_class_try_get_generic_container (klass
) != NULL
)
2624 goto leave
; /* already setup */
2626 MonoGenericContainer
*generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2628 generic_container
->owner
.klass
= klass
;
2629 generic_container
->type_argc
= count
;
2630 generic_container
->type_params
= (MonoGenericParamFull
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericParamFull
) * count
);
2632 klass
->class_kind
= MONO_CLASS_GTD
;
2633 mono_class_set_generic_container (klass
, generic_container
);
2636 MonoReflectionGenericParamHandle ref_gparam
= MONO_HANDLE_NEW (MonoReflectionGenericParam
, NULL
);
2637 for (int i
= 0; i
< count
; i
++) {
2638 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
2639 MonoType
*param_type
= mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType
, ref_gparam
), error
);
2640 goto_if_nok (error
, leave
);
2641 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) param_type
->data
.generic_param
;
2642 generic_container
->type_params
[i
] = *param
;
2643 /*Make sure we are a diferent type instance */
2644 generic_container
->type_params
[i
].param
.owner
= generic_container
;
2645 generic_container
->type_params
[i
].info
.pklass
= NULL
;
2646 generic_container
->type_params
[i
].info
.flags
= MONO_HANDLE_GETVAL (ref_gparam
, attrs
);
2648 g_assert (generic_container
->type_params
[i
].param
.owner
);
2651 generic_container
->context
.class_inst
= mono_get_shared_generic_inst (generic_container
);
2652 MonoGenericContext
* context
= &generic_container
->context
;
2653 MonoType
*canonical_inst
= &((MonoClassGtd
*)klass
)->canonical_inst
;
2654 canonical_inst
->type
= MONO_TYPE_GENERICINST
;
2655 canonical_inst
->data
.generic_class
= mono_metadata_lookup_generic_class (klass
, context
->class_inst
, FALSE
);
2658 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2661 static MonoMarshalSpec
*
2662 mono_marshal_spec_from_builder (MonoImage
*image
, MonoAssembly
*assembly
,
2663 MonoReflectionMarshal
*minfo
, MonoError
*error
)
2665 MonoMarshalSpec
*res
;
2669 res
= image_g_new0 (image
, MonoMarshalSpec
, 1);
2670 res
->native
= (MonoMarshalNative
)minfo
->type
;
2672 switch (minfo
->type
) {
2673 case MONO_NATIVE_LPARRAY
:
2674 res
->data
.array_data
.elem_type
= (MonoMarshalNative
)minfo
->eltype
;
2675 if (minfo
->has_size
) {
2676 res
->data
.array_data
.param_num
= minfo
->param_num
;
2677 res
->data
.array_data
.num_elem
= minfo
->count
;
2678 res
->data
.array_data
.elem_mult
= minfo
->param_num
== -1 ? 0 : 1;
2681 res
->data
.array_data
.param_num
= -1;
2682 res
->data
.array_data
.num_elem
= -1;
2683 res
->data
.array_data
.elem_mult
= -1;
2687 case MONO_NATIVE_BYVALTSTR
:
2688 case MONO_NATIVE_BYVALARRAY
:
2689 res
->data
.array_data
.num_elem
= minfo
->count
;
2692 case MONO_NATIVE_CUSTOM
:
2693 if (minfo
->marshaltyperef
) {
2694 MonoType
*marshaltyperef
= mono_reflection_type_get_handle ((MonoReflectionType
*)minfo
->marshaltyperef
, error
);
2695 if (!is_ok (error
)) {
2696 image_g_free (image
, res
);
2699 res
->data
.custom_data
.custom_name
=
2700 type_get_fully_qualified_name (marshaltyperef
);
2702 if (minfo
->mcookie
) {
2703 res
->data
.custom_data
.cookie
= mono_string_to_utf8_checked (minfo
->mcookie
, error
);
2704 if (!is_ok (error
)) {
2705 image_g_free (image
, res
);
2717 #endif /* !DISABLE_REFLECTION_EMIT */
2719 MonoReflectionMarshalAsAttributeHandle
2720 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain
*domain
, MonoClass
*klass
,
2721 MonoMarshalSpec
*spec
, MonoError
*error
)
2725 MonoReflectionMarshalAsAttributeHandle minfo
= MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, mono_object_new_checked (domain
, mono_class_get_marshal_as_attribute_class (), error
));
2726 goto_if_nok (error
, fail
);
2727 guint32 utype
= spec
->native
;
2728 MONO_HANDLE_SETVAL (minfo
, utype
, guint32
, utype
);
2731 case MONO_NATIVE_LPARRAY
:
2732 MONO_HANDLE_SETVAL (minfo
, array_subtype
, guint32
, spec
->data
.array_data
.elem_type
);
2733 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2734 if (spec
->data
.array_data
.param_num
!= -1)
2735 MONO_HANDLE_SETVAL (minfo
, size_param_index
, gint16
, spec
->data
.array_data
.param_num
);
2738 case MONO_NATIVE_BYVALTSTR
:
2739 case MONO_NATIVE_BYVALARRAY
:
2740 MONO_HANDLE_SETVAL (minfo
, size_const
, gint32
, spec
->data
.array_data
.num_elem
);
2743 case MONO_NATIVE_CUSTOM
:
2744 if (spec
->data
.custom_data
.custom_name
) {
2745 MonoType
*mtype
= mono_reflection_type_from_name_checked (spec
->data
.custom_data
.custom_name
, klass
->image
, error
);
2746 goto_if_nok (error
, fail
);
2749 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, mtype
, error
);
2750 goto_if_nok (error
, fail
);
2752 MONO_HANDLE_SET (minfo
, marshal_type_ref
, rt
);
2755 MonoStringHandle custom_name
= mono_string_new_handle (domain
, spec
->data
.custom_data
.custom_name
, error
);
2756 goto_if_nok (error
, fail
);
2757 MONO_HANDLE_SET (minfo
, marshal_type
, custom_name
);
2759 if (spec
->data
.custom_data
.cookie
) {
2760 MonoStringHandle cookie
= mono_string_new_handle (domain
, spec
->data
.custom_data
.cookie
, error
);
2761 goto_if_nok (error
, fail
);
2762 MONO_HANDLE_SET (minfo
, marshal_cookie
, cookie
);
2772 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, NULL
);
2775 #ifndef DISABLE_REFLECTION_EMIT
2777 reflection_methodbuilder_to_mono_method (MonoClass
*klass
,
2778 ReflectionMethodBuilder
*rmb
,
2779 MonoMethodSignature
*sig
,
2783 MonoMethodWrapper
*wrapperm
;
2784 MonoMarshalSpec
**specs
= NULL
;
2785 MonoReflectionMethodAux
*method_aux
;
2792 * Methods created using a MethodBuilder should have their memory allocated
2793 * inside the image mempool, while dynamic methods should have their memory
2796 dynamic
= rmb
->refs
!= NULL
;
2797 image
= dynamic
? NULL
: klass
->image
;
2800 g_assert (!mono_class_is_ginst (klass
));
2802 mono_loader_lock ();
2804 if ((rmb
->attrs
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
2805 (rmb
->iattrs
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
2806 m
= (MonoMethod
*)image_g_new0 (image
, MonoMethodPInvoke
, 1);
2808 m
= (MonoMethod
*)image_g_new0 (image
, MonoDynamicMethod
, 1);
2810 wrapperm
= (MonoMethodWrapper
*)m
;
2812 m
->dynamic
= dynamic
;
2814 m
->flags
= rmb
->attrs
;
2815 m
->iflags
= rmb
->iattrs
;
2816 m
->name
= string_to_utf8_image_raw (image
, rmb
->name
, error
);
2817 goto_if_nok (error
, fail
);
2820 m
->sre_method
= TRUE
;
2821 m
->skip_visibility
= rmb
->skip_visibility
;
2823 m
->token
= MONO_TOKEN_METHOD_DEF
| (*rmb
->table_idx
);
2825 if (m
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) {
2826 if (klass
== mono_defaults
.string_class
&& !strcmp (m
->name
, ".ctor"))
2829 m
->signature
->pinvoke
= 1;
2830 } else if (m
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) {
2831 m
->signature
->pinvoke
= 1;
2833 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2835 method_aux
->dllentry
= rmb
->dllentry
? string_to_utf8_image_raw (image
, rmb
->dllentry
, error
) : image_strdup (image
, m
->name
);
2836 mono_error_assert_ok (error
);
2837 method_aux
->dll
= string_to_utf8_image_raw (image
, rmb
->dll
, error
);
2838 mono_error_assert_ok (error
);
2840 ((MonoMethodPInvoke
*)m
)->piflags
= (rmb
->native_cc
<< 8) | (rmb
->charset
? (rmb
->charset
- 1) * 2 : 0) | rmb
->extra_flags
;
2842 if (image_is_dynamic (klass
->image
))
2843 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
2847 } else if (!(m
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) &&
2848 !(m
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
)) {
2849 MonoMethodHeader
*header
;
2851 gint32 max_stack
, i
;
2852 gint32 num_locals
= 0;
2853 gint32 num_clauses
= 0;
2857 code
= mono_array_addr (rmb
->ilgen
->code
, guint8
, 0);
2858 code_size
= rmb
->ilgen
->code_len
;
2859 max_stack
= rmb
->ilgen
->max_stack
;
2860 num_locals
= rmb
->ilgen
->locals
? mono_array_length (rmb
->ilgen
->locals
) : 0;
2861 if (rmb
->ilgen
->ex_handlers
)
2862 num_clauses
= mono_reflection_method_count_clauses (rmb
->ilgen
);
2865 code
= mono_array_addr (rmb
->code
, guint8
, 0);
2866 code_size
= mono_array_length (rmb
->code
);
2867 /* we probably need to run a verifier on the code... */
2877 header
= (MonoMethodHeader
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_HEADER
+ num_locals
* sizeof (MonoType
*));
2878 header
->code_size
= code_size
;
2879 header
->code
= (const unsigned char *)image_g_malloc (image
, code_size
);
2880 memcpy ((char*)header
->code
, code
, code_size
);
2881 header
->max_stack
= max_stack
;
2882 header
->init_locals
= rmb
->init_locals
;
2883 header
->num_locals
= num_locals
;
2885 for (i
= 0; i
< num_locals
; ++i
) {
2886 MonoReflectionLocalBuilder
*lb
=
2887 mono_array_get (rmb
->ilgen
->locals
, MonoReflectionLocalBuilder
*, i
);
2889 header
->locals
[i
] = image_g_new0 (image
, MonoType
, 1);
2890 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)lb
->type
, error
);
2891 mono_error_assert_ok (error
);
2892 memcpy (header
->locals
[i
], type
, MONO_SIZEOF_TYPE
);
2895 header
->num_clauses
= num_clauses
;
2897 header
->clauses
= method_encode_clauses (image
, (MonoDynamicImage
*)klass
->image
,
2898 rmb
->ilgen
, num_clauses
, error
);
2899 mono_error_assert_ok (error
);
2902 wrapperm
->header
= header
;
2903 MonoDynamicMethod
*dm
= (MonoDynamicMethod
*)wrapperm
;
2904 dm
->assembly
= klass
->image
->assembly
;
2907 if (rmb
->generic_params
) {
2908 int count
= mono_array_length (rmb
->generic_params
);
2909 MonoGenericContainer
*container
;
2911 container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2912 container
->is_method
= TRUE
;
2913 container
->is_anonymous
= FALSE
;
2914 container
->type_argc
= count
;
2915 container
->type_params
= image_g_new0 (image
, MonoGenericParamFull
, count
);
2916 container
->owner
.method
= m
;
2918 m
->is_generic
= TRUE
;
2919 mono_method_set_generic_container (m
, container
);
2921 for (i
= 0; i
< count
; i
++) {
2922 MonoReflectionGenericParam
*gp
=
2923 mono_array_get (rmb
->generic_params
, MonoReflectionGenericParam
*, i
);
2924 MonoType
*gp_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gp
, error
);
2925 mono_error_assert_ok (error
);
2926 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) gp_type
->data
.generic_param
;
2927 container
->type_params
[i
] = *param
;
2928 container
->type_params
[i
].param
.owner
= container
;
2930 gp
->type
.type
->data
.generic_param
= (MonoGenericParam
*)&container
->type_params
[i
];
2932 MonoClass
*gklass
= mono_class_from_mono_type (gp_type
);
2933 gklass
->wastypebuilder
= TRUE
;
2937 * The method signature might have pointers to generic parameters that belong to other methods.
2938 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2939 * generic parameters.
2941 for (i
= 0; i
< m
->signature
->param_count
; ++i
) {
2942 MonoType
*t
= m
->signature
->params
[i
];
2943 if (t
->type
== MONO_TYPE_MVAR
) {
2944 MonoGenericParam
*gparam
= t
->data
.generic_param
;
2945 if (gparam
->num
< count
) {
2946 m
->signature
->params
[i
] = mono_metadata_type_dup (image
, m
->signature
->params
[i
]);
2947 m
->signature
->params
[i
]->data
.generic_param
= mono_generic_container_get_param (container
, gparam
->num
);
2953 if (mono_class_is_gtd (klass
)) {
2954 container
->parent
= mono_class_get_generic_container (klass
);
2955 container
->context
.class_inst
= mono_class_get_generic_container (klass
)->context
.class_inst
;
2957 container
->context
.method_inst
= mono_get_shared_generic_inst (container
);
2961 MonoMethodWrapper
*mw
= (MonoMethodWrapper
*)m
;
2965 m
->wrapper_type
= MONO_WRAPPER_DYNAMIC_METHOD
;
2967 mw
->method_data
= data
= image_g_new (image
, gpointer
, rmb
->nrefs
+ 1);
2968 data
[0] = GUINT_TO_POINTER (rmb
->nrefs
);
2969 for (i
= 0; i
< rmb
->nrefs
; ++i
)
2970 data
[i
+ 1] = rmb
->refs
[i
];
2975 /* Parameter info */
2978 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2979 method_aux
->param_names
= image_g_new0 (image
, char *, mono_method_signature (m
)->param_count
+ 1);
2980 for (i
= 0; i
<= m
->signature
->param_count
; ++i
) {
2981 MonoReflectionParamBuilder
*pb
;
2982 if ((pb
= mono_array_get (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
2983 if ((i
> 0) && (pb
->attrs
)) {
2984 /* Make a copy since it might point to a shared type structure */
2985 m
->signature
->params
[i
- 1] = mono_metadata_type_dup (klass
->image
, m
->signature
->params
[i
- 1]);
2986 m
->signature
->params
[i
- 1]->attrs
= pb
->attrs
;
2989 if (pb
->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
) {
2990 MonoDynamicImage
*assembly
;
2992 MonoTypeEnum def_type
;
2996 if (!method_aux
->param_defaults
) {
2997 method_aux
->param_defaults
= image_g_new0 (image
, guint8
*, m
->signature
->param_count
+ 1);
2998 method_aux
->param_default_types
= image_g_new0 (image
, guint32
, m
->signature
->param_count
+ 1);
3000 assembly
= (MonoDynamicImage
*)klass
->image
;
3001 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &def_type
);
3002 /* Copy the data from the blob since it might get realloc-ed */
3003 p
= assembly
->blob
.data
+ idx
;
3004 len
= mono_metadata_decode_blob_size (p
, &p2
);
3006 method_aux
->param_defaults
[i
] = (uint8_t *)image_g_malloc (image
, len
);
3007 method_aux
->param_default_types
[i
] = def_type
;
3008 memcpy ((gpointer
)method_aux
->param_defaults
[i
], p
, len
);
3012 method_aux
->param_names
[i
] = string_to_utf8_image_raw (image
, pb
->name
, error
);
3013 mono_error_assert_ok (error
);
3016 if (!method_aux
->param_cattr
)
3017 method_aux
->param_cattr
= image_g_new0 (image
, MonoCustomAttrInfo
*, m
->signature
->param_count
+ 1);
3018 method_aux
->param_cattr
[i
] = mono_custom_attrs_from_builders (image
, klass
->image
, pb
->cattrs
);
3024 /* Parameter marshalling */
3026 for (i
= 0; i
< mono_array_length (rmb
->pinfo
); ++i
) {
3027 MonoReflectionParamBuilder
*pb
;
3028 if ((pb
= mono_array_get (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
3029 if (pb
->marshal_info
) {
3031 specs
= image_g_new0 (image
, MonoMarshalSpec
*, sig
->param_count
+ 1);
3032 specs
[pb
->position
] =
3033 mono_marshal_spec_from_builder (image
, klass
->image
->assembly
, pb
->marshal_info
, error
);
3034 goto_if_nok (error
, fail
);
3038 if (specs
!= NULL
) {
3040 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
3041 method_aux
->param_marshall
= specs
;
3044 if (image_is_dynamic (klass
->image
) && method_aux
)
3045 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
3048 mono_loader_unlock ();
3049 if (!m
) // FIXME: This leaks if image is not NULL.
3050 image_g_free (image
, specs
);
3059 ctorbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionCtorBuilder
* mb
, MonoError
*error
)
3061 ReflectionMethodBuilder rmb
;
3062 MonoMethodSignature
*sig
;
3064 mono_loader_lock ();
3066 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb
, mb
, error
))
3069 g_assert (klass
->image
!= NULL
);
3070 sig
= ctor_builder_to_signature_raw (klass
->image
, mb
, error
); /* FIXME use handles */
3071 mono_loader_unlock ();
3072 return_val_if_nok (error
, NULL
);
3074 mb
->mhandle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3075 return_val_if_nok (error
, NULL
);
3076 mono_save_custom_attrs (klass
->image
, mb
->mhandle
, mb
->cattrs
);
3078 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
) {
3079 /* ilgen is no longer needed */
3087 methodbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionMethodBuilderHandle ref_mb
, MonoError
*error
)
3089 ReflectionMethodBuilder rmb
;
3090 MonoMethodSignature
*sig
;
3094 mono_loader_lock ();
3096 MonoReflectionMethodBuilder
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME use handles */
3097 if (!mono_reflection_methodbuilder_from_method_builder (&rmb
, mb
, error
))
3100 g_assert (klass
->image
!= NULL
);
3101 sig
= method_builder_to_signature (klass
->image
, ref_mb
, error
);
3102 mono_loader_unlock ();
3103 return_val_if_nok (error
, NULL
);
3105 MonoMethod
*method
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3106 return_val_if_nok (error
, NULL
);
3107 MONO_HANDLE_SETVAL (ref_mb
, mhandle
, MonoMethod
*, method
);
3108 mono_save_custom_attrs (klass
->image
, method
, mb
->cattrs
);
3110 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
)
3111 /* ilgen is no longer needed */
3117 methodbuilder_to_mono_method_raw (MonoClass
*klass
, MonoReflectionMethodBuilder
* mb_raw
, MonoError
*error
)
3119 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3121 MONO_HANDLE_DCL (MonoReflectionMethodBuilder
, mb
);
3122 MonoMethod
*result
= methodbuilder_to_mono_method (klass
, mb
, error
);
3123 HANDLE_FUNCTION_RETURN_VAL (result
);
3128 #ifndef DISABLE_REFLECTION_EMIT
3131 * fix_partial_generic_class:
3132 * @klass: a generic instantiation MonoClass
3133 * @error: set on error
3135 * Assumes that the generic container of @klass has its vtable
3136 * initialized, and updates the parent class, interfaces, methods and
3137 * fields of @klass by inflating the types using the generic context.
3139 * On success returns TRUE, on failure returns FALSE and sets @error.
3143 fix_partial_generic_class (MonoClass
*klass
, MonoError
*error
)
3145 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3150 if (klass
->wastypebuilder
)
3153 if (klass
->parent
!= gklass
->parent
) {
3154 MonoType
*parent_type
= mono_class_inflate_generic_type_checked (&gklass
->parent
->byval_arg
, &mono_class_get_generic_class (klass
)->context
, error
);
3155 if (mono_error_ok (error
)) {
3156 MonoClass
*parent
= mono_class_from_mono_type (parent_type
);
3157 mono_metadata_free_type (parent_type
);
3158 if (parent
!= klass
->parent
) {
3159 /*fool mono_class_setup_parent*/
3160 klass
->supertypes
= NULL
;
3161 mono_class_setup_parent (klass
, parent
);
3164 if (gklass
->wastypebuilder
)
3165 klass
->wastypebuilder
= TRUE
;
3170 if (!mono_class_get_generic_class (klass
)->need_sync
)
3173 int mcount
= mono_class_get_method_count (klass
);
3174 int gmcount
= mono_class_get_method_count (gklass
);
3175 if (mcount
!= gmcount
) {
3176 mono_class_set_method_count (klass
, gmcount
);
3177 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * (gmcount
+ 1));
3179 for (i
= 0; i
< gmcount
; i
++) {
3180 klass
->methods
[i
] = mono_class_inflate_generic_method_full_checked (
3181 gklass
->methods
[i
], klass
, mono_class_get_context (klass
), error
);
3182 mono_error_assert_ok (error
);
3186 if (klass
->interface_count
&& klass
->interface_count
!= gklass
->interface_count
) {
3187 klass
->interface_count
= gklass
->interface_count
;
3188 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * gklass
->interface_count
);
3189 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3191 for (i
= 0; i
< gklass
->interface_count
; ++i
) {
3192 MonoType
*iface_type
= mono_class_inflate_generic_type_checked (&gklass
->interfaces
[i
]->byval_arg
, mono_class_get_context (klass
), error
);
3193 return_val_if_nok (error
, FALSE
);
3195 klass
->interfaces
[i
] = mono_class_from_mono_type (iface_type
);
3196 mono_metadata_free_type (iface_type
);
3198 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3201 klass
->interfaces_inited
= 1;
3204 int fcount
= mono_class_get_field_count (klass
);
3205 int gfcount
= mono_class_get_field_count (gklass
);
3206 if (fcount
!= gfcount
) {
3207 mono_class_set_field_count (klass
, gfcount
);
3208 klass
->fields
= image_g_new0 (klass
->image
, MonoClassField
, gfcount
);
3210 for (i
= 0; i
< gfcount
; i
++) {
3211 klass
->fields
[i
] = gklass
->fields
[i
];
3212 klass
->fields
[i
].parent
= klass
;
3213 klass
->fields
[i
].type
= mono_class_inflate_generic_type_checked (gklass
->fields
[i
].type
, mono_class_get_context (klass
), error
);
3214 return_val_if_nok (error
, FALSE
);
3218 /*We can only finish with this klass once it's parent has as well*/
3219 if (gklass
->wastypebuilder
)
3220 klass
->wastypebuilder
= TRUE
;
3225 * ensure_generic_class_runtime_vtable:
3226 * @klass a generic class
3227 * @error set on error
3229 * Ensures that the generic container of @klass has a vtable and
3230 * returns TRUE on success. On error returns FALSE and sets @error.
3233 ensure_generic_class_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3235 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3239 if (!ensure_runtime_vtable (gklass
, error
))
3242 return fix_partial_generic_class (klass
, error
);
3246 * ensure_runtime_vtable:
3248 * @error set on error
3250 * Ensures that @klass has a vtable and returns TRUE on success. On
3251 * error returns FALSE and sets @error.
3254 ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3256 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3261 if (!image_is_dynamic (klass
->image
) || (!tb
&& !mono_class_is_ginst (klass
)) || klass
->wastypebuilder
)
3264 if (!ensure_runtime_vtable (klass
->parent
, error
))
3268 num
= tb
->ctors
? mono_array_length (tb
->ctors
): 0;
3269 num
+= tb
->num_methods
;
3270 mono_class_set_method_count (klass
, num
);
3271 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * num
);
3272 num
= tb
->ctors
? mono_array_length (tb
->ctors
): 0;
3273 for (i
= 0; i
< num
; ++i
) {
3274 MonoMethod
*ctor
= ctorbuilder_to_mono_method (klass
, mono_array_get (tb
->ctors
, MonoReflectionCtorBuilder
*, i
), error
);
3277 klass
->methods
[i
] = ctor
;
3279 num
= tb
->num_methods
;
3281 for (i
= 0; i
< num
; ++i
) {
3282 MonoMethod
*meth
= methodbuilder_to_mono_method_raw (klass
, mono_array_get (tb
->methods
, MonoReflectionMethodBuilder
*, i
), error
); /* FIXME use handles */
3285 klass
->methods
[j
++] = meth
;
3288 if (tb
->interfaces
) {
3289 klass
->interface_count
= mono_array_length (tb
->interfaces
);
3290 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * klass
->interface_count
);
3291 for (i
= 0; i
< klass
->interface_count
; ++i
) {
3292 MonoType
*iface
= mono_type_array_get_and_resolve_raw (tb
->interfaces
, i
, error
); /* FIXME use handles */
3293 return_val_if_nok (error
, FALSE
);
3294 klass
->interfaces
[i
] = mono_class_from_mono_type (iface
);
3295 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3298 klass
->interfaces_inited
= 1;
3300 } else if (mono_class_is_ginst (klass
)){
3301 if (!ensure_generic_class_runtime_vtable (klass
, error
)) {
3302 mono_class_set_type_load_failure (klass
, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error
));
3307 if (mono_class_is_interface (klass
) && !mono_class_is_ginst (klass
)) {
3309 int mcount
= mono_class_get_method_count (klass
);
3310 for (i
= 0; i
< mcount
; ++i
) {
3311 MonoMethod
*im
= klass
->methods
[i
];
3312 if (!(im
->flags
& METHOD_ATTRIBUTE_STATIC
))
3313 im
->slot
= slot_num
++;
3316 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3317 mono_class_setup_interface_offsets (klass
);
3318 mono_class_setup_interface_id (klass
);
3322 * The generic vtable is needed even if image->run is not set since some
3323 * runtime code like ves_icall_Type_GetMethodsByName depends on
3324 * method->slot being defined.
3328 * tb->methods could not be freed since it is used for determining
3329 * overrides during dynamic vtable construction.
3336 mono_reflection_method_get_handle (MonoObject
*method
, MonoError
*error
)
3339 MonoClass
*klass
= mono_object_class (method
);
3340 if (is_sr_mono_method (klass
)) {
3341 MonoReflectionMethod
*sr_method
= (MonoReflectionMethod
*)method
;
3342 return sr_method
->method
;
3344 if (is_sre_method_builder (klass
)) {
3345 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)method
;
3348 if (mono_is_sre_method_on_tb_inst (klass
)) {
3349 MonoClass
*handle_class
;
3351 MonoMethod
*result
= mono_reflection_resolve_object (NULL
, method
, &handle_class
, NULL
, error
);
3352 return_val_if_nok (error
, NULL
);
3357 g_error ("Can't handle methods of type %s:%s", klass
->name_space
, klass
->name
);
3362 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
3364 MonoReflectionTypeBuilder
*tb
;
3366 MonoReflectionMethod
*m
;
3372 g_assert (image_is_dynamic (klass
->image
));
3374 if (!mono_class_has_ref_info (klass
))
3377 tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3378 g_assert (strcmp (mono_object_class (tb
)->name
, "TypeBuilder") == 0);
3382 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3383 MonoReflectionMethodBuilder
*mb
=
3384 mono_array_get (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3385 if (mb
->override_methods
)
3386 onum
+= mono_array_length (mb
->override_methods
);
3391 *overrides
= g_new0 (MonoMethod
*, onum
* 2);
3394 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3395 MonoReflectionMethodBuilder
*mb
=
3396 mono_array_get (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3397 if (mb
->override_methods
) {
3398 for (j
= 0; j
< mono_array_length (mb
->override_methods
); ++j
) {
3399 m
= mono_array_get (mb
->override_methods
, MonoReflectionMethod
*, j
);
3401 (*overrides
) [onum
* 2] = mono_reflection_method_get_handle ((MonoObject
*)m
, error
);
3402 return_if_nok (error
);
3403 (*overrides
) [onum
* 2 + 1] = mb
->mhandle
;
3405 g_assert (mb
->mhandle
);
3413 *num_overrides
= onum
;
3416 /* This initializes the same data as mono_class_setup_fields () */
3418 typebuilder_setup_fields (MonoClass
*klass
, MonoError
*error
)
3420 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3421 MonoReflectionFieldBuilder
*fb
;
3422 MonoClassField
*field
;
3423 MonoFieldDefaultValue
*def_values
;
3424 MonoImage
*image
= klass
->image
;
3426 int i
, instance_size
, packing_size
= 0;
3429 if (klass
->parent
) {
3430 if (!klass
->parent
->size_inited
)
3431 mono_class_init (klass
->parent
);
3432 instance_size
= klass
->parent
->instance_size
;
3434 instance_size
= sizeof (MonoObject
);
3437 int fcount
= tb
->num_fields
;
3438 mono_class_set_field_count (klass
, fcount
);
3442 if (tb
->class_size
) {
3443 packing_size
= tb
->packing_size
;
3444 instance_size
+= tb
->class_size
;
3447 klass
->fields
= image_g_new0 (image
, MonoClassField
, fcount
);
3448 def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, fcount
);
3449 mono_class_set_field_def_values (klass
, def_values
);
3451 This is, guess what, a hack.
3452 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3453 On the static path no field class is resolved, only types are built. This is the right thing to do
3455 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3457 klass
->size_inited
= 1;
3459 for (i
= 0; i
< fcount
; ++i
) {
3460 MonoArray
*rva_data
;
3461 fb
= (MonoReflectionFieldBuilder
*)mono_array_get (tb
->fields
, gpointer
, i
);
3462 field
= &klass
->fields
[i
];
3463 field
->parent
= klass
;
3464 field
->name
= string_to_utf8_image_raw (image
, fb
->name
, error
); /* FIXME use handles */
3465 if (!mono_error_ok (error
))
3468 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3469 return_if_nok (error
);
3470 field
->type
= mono_metadata_type_dup (klass
->image
, type
);
3471 field
->type
->attrs
= fb
->attrs
;
3473 field
->type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3474 return_if_nok (error
);
3477 if (!klass
->enumtype
&& !mono_type_get_underlying_type (field
->type
)) {
3478 mono_class_set_type_load_failure (klass
, "Field '%s' is an enum type with a bad underlying type", field
->name
);
3482 if ((fb
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
) && (rva_data
= fb
->rva_data
)) {
3483 char *base
= mono_array_addr (rva_data
, char, 0);
3484 size_t size
= mono_array_length (rva_data
);
3485 char *data
= (char *)mono_image_alloc (klass
->image
, size
);
3486 memcpy (data
, base
, size
);
3487 def_values
[i
].data
= data
;
3489 if (fb
->offset
!= -1)
3490 field
->offset
= fb
->offset
;
3492 mono_save_custom_attrs (klass
->image
, field
, fb
->cattrs
);
3494 if (fb
->def_value
) {
3495 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3496 field
->type
->attrs
|= FIELD_ATTRIBUTE_HAS_DEFAULT
;
3497 idx
= mono_dynimage_encode_constant (assembly
, fb
->def_value
, &def_values
[i
].def_type
);
3498 /* Copy the data from the blob since it might get realloc-ed */
3499 p
= assembly
->blob
.data
+ idx
;
3500 len
= mono_metadata_decode_blob_size (p
, &p2
);
3502 def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3503 memcpy ((gpointer
)def_values
[i
].data
, p
, len
);
3507 if (!mono_class_has_failure (klass
))
3508 mono_class_layout_fields (klass
, instance_size
, packing_size
, tb
->class_size
, TRUE
);
3512 typebuilder_setup_properties (MonoClass
*klass
, MonoError
*error
)
3514 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3515 MonoReflectionPropertyBuilder
*pb
;
3516 MonoImage
*image
= klass
->image
;
3517 MonoProperty
*properties
;
3518 MonoClassPropertyInfo
*info
;
3523 info
= mono_class_get_property_info (klass
);
3525 info
= mono_class_alloc0 (klass
, sizeof (MonoClassPropertyInfo
));
3526 mono_class_set_property_info (klass
, info
);
3529 info
->count
= tb
->properties
? mono_array_length (tb
->properties
) : 0;
3532 properties
= image_g_new0 (image
, MonoProperty
, info
->count
);
3533 info
->properties
= properties
;
3534 for (i
= 0; i
< info
->count
; ++i
) {
3535 pb
= mono_array_get (tb
->properties
, MonoReflectionPropertyBuilder
*, i
);
3536 properties
[i
].parent
= klass
;
3537 properties
[i
].attrs
= pb
->attrs
;
3538 properties
[i
].name
= string_to_utf8_image_raw (image
, pb
->name
, error
); /* FIXME use handles */
3539 if (!mono_error_ok (error
))
3542 properties
[i
].get
= pb
->get_method
->mhandle
;
3544 properties
[i
].set
= pb
->set_method
->mhandle
;
3546 mono_save_custom_attrs (klass
->image
, &properties
[i
], pb
->cattrs
);
3547 if (pb
->def_value
) {
3550 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3551 if (!info
->def_values
)
3552 info
->def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, info
->count
);
3553 properties
[i
].attrs
|= PROPERTY_ATTRIBUTE_HAS_DEFAULT
;
3554 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &info
->def_values
[i
].def_type
);
3555 /* Copy the data from the blob since it might get realloc-ed */
3556 p
= assembly
->blob
.data
+ idx
;
3557 len
= mono_metadata_decode_blob_size (p
, &p2
);
3559 info
->def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3560 memcpy ((gpointer
)info
->def_values
[i
].data
, p
, len
);
3566 typebuilder_setup_events (MonoClass
*klass
, MonoError
*error
)
3568 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
3569 MonoReflectionEventBuilder
*eb
;
3570 MonoImage
*image
= klass
->image
;
3572 MonoClassEventInfo
*info
;
3577 info
= mono_class_alloc0 (klass
, sizeof (MonoClassEventInfo
));
3578 mono_class_set_event_info (klass
, info
);
3580 info
->count
= tb
->events
? mono_array_length (tb
->events
) : 0;
3583 events
= image_g_new0 (image
, MonoEvent
, info
->count
);
3584 info
->events
= events
;
3585 for (i
= 0; i
< info
->count
; ++i
) {
3586 eb
= mono_array_get (tb
->events
, MonoReflectionEventBuilder
*, i
);
3587 events
[i
].parent
= klass
;
3588 events
[i
].attrs
= eb
->attrs
;
3589 events
[i
].name
= string_to_utf8_image_raw (image
, eb
->name
, error
); /* FIXME use handles */
3590 if (!mono_error_ok (error
))
3593 events
[i
].add
= eb
->add_method
->mhandle
;
3594 if (eb
->remove_method
)
3595 events
[i
].remove
= eb
->remove_method
->mhandle
;
3596 if (eb
->raise_method
)
3597 events
[i
].raise
= eb
->raise_method
->mhandle
;
3599 #ifndef MONO_SMALL_CONFIG
3600 if (eb
->other_methods
) {
3602 events
[i
].other
= image_g_new0 (image
, MonoMethod
*, mono_array_length (eb
->other_methods
) + 1);
3603 for (j
= 0; j
< mono_array_length (eb
->other_methods
); ++j
) {
3604 MonoReflectionMethodBuilder
*mb
=
3605 mono_array_get (eb
->other_methods
,
3606 MonoReflectionMethodBuilder
*, j
);
3607 events
[i
].other
[j
] = mb
->mhandle
;
3611 mono_save_custom_attrs (klass
->image
, &events
[i
], eb
->cattrs
);
3615 struct remove_instantiations_user_data
3622 remove_instantiations_of_and_ensure_contents (gpointer key
,
3626 struct remove_instantiations_user_data
*data
= (struct remove_instantiations_user_data
*)user_data
;
3627 MonoType
*type
= (MonoType
*)key
;
3628 MonoClass
*klass
= data
->klass
;
3629 gboolean already_failed
= !is_ok (data
->error
);
3631 MonoError
*error
= already_failed
? &lerror
: data
->error
;
3633 if ((type
->type
== MONO_TYPE_GENERICINST
) && (type
->data
.generic_class
->container_class
== klass
)) {
3634 MonoClass
*inst_klass
= mono_class_from_mono_type (type
);
3635 //Ensure it's safe to use it.
3636 if (!fix_partial_generic_class (inst_klass
, error
)) {
3637 mono_class_set_type_load_failure (inst_klass
, "Could not initialized generic type instance due to: %s", mono_error_get_message (error
));
3638 // Marked the class with failure, but since some other instantiation already failed,
3639 // just report that one, and swallow the error from this one.
3641 mono_error_cleanup (error
);
3649 * reflection_setup_internal_class:
3650 * @tb: a TypeBuilder object
3651 * @error: set on error
3653 * Creates a MonoClass that represents the TypeBuilder.
3654 * This is a trick that lets us simplify a lot of reflection code
3655 * (and will allow us to support Build and Run assemblies easier).
3657 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3660 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3662 MonoReflectionModuleBuilderHandle module_ref
= MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder
, ref_tb
, module
);
3663 GHashTable
*unparented_classes
= MONO_HANDLE_GETVAL(module_ref
, unparented_classes
);
3665 if (unparented_classes
) {
3666 return reflection_setup_internal_class_internal (ref_tb
, error
);
3668 // If we're not being called recursively
3669 unparented_classes
= g_hash_table_new (NULL
, NULL
);
3670 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, unparented_classes
);
3672 gboolean ret_val
= reflection_setup_internal_class_internal (ref_tb
, error
);
3673 mono_error_assert_ok (error
);
3675 // Fix the relationship between the created classes and their parents
3676 reflection_setup_class_hierarchy (unparented_classes
, error
);
3677 mono_error_assert_ok (error
);
3679 g_hash_table_destroy (unparented_classes
);
3680 MONO_HANDLE_SETVAL (module_ref
, unparented_classes
, GHashTable
*, NULL
);
3687 MonoReflectionTypeHandle
3688 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb
, MonoError
*error
)
3692 reflection_setup_internal_class (ref_tb
, error
);
3693 mono_error_assert_ok (error
);
3695 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_tb
);
3696 MonoType
*type
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType
, ref_tb
), type
);
3697 MonoClass
*klass
= mono_class_from_mono_type (type
);
3699 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, cattrs
);
3700 mono_save_custom_attrs (klass
->image
, klass
, MONO_HANDLE_RAW (cattrs
)); /* FIXME use handles */
3703 * we need to lock the domain because the lock will be taken inside
3704 * So, we need to keep the locking order correct.
3706 mono_loader_lock ();
3707 mono_domain_lock (domain
);
3708 if (klass
->wastypebuilder
) {
3709 mono_domain_unlock (domain
);
3710 mono_loader_unlock ();
3712 return mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
3715 * Fields to set in klass:
3716 * the various flags: delegate/unicode/contextbound etc.
3718 mono_class_set_flags (klass
, MONO_HANDLE_GETVAL (ref_tb
, attrs
));
3719 klass
->has_cctor
= 1;
3721 mono_class_setup_parent (klass
, klass
->parent
);
3722 /* fool mono_class_setup_supertypes */
3723 klass
->supertypes
= NULL
;
3724 mono_class_setup_supertypes (klass
);
3725 mono_class_setup_mono_type (klass
);
3727 /* enums are done right away */
3728 if (!klass
->enumtype
)
3729 if (!ensure_runtime_vtable (klass
, error
))
3732 MonoArrayHandle nested_types
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, subtypes
);
3733 if (!MONO_HANDLE_IS_NULL (nested_types
)) {
3734 GList
*nested
= NULL
;
3735 int num_nested
= mono_array_handle_length (nested_types
);
3736 MonoReflectionTypeHandle nested_tb
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
3737 for (int i
= 0; i
< num_nested
; ++i
) {
3738 MONO_HANDLE_ARRAY_GETREF (nested_tb
, nested_types
, i
);
3740 if (MONO_HANDLE_GETVAL (nested_tb
, type
) == NULL
) {
3741 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, nested_tb
), error
);
3742 mono_error_assert_ok (error
);
3745 MonoType
*subtype
= mono_reflection_type_handle_mono_type (nested_tb
, error
);
3746 goto_if_nok (error
, failure
);
3747 nested
= g_list_prepend_image (klass
->image
, nested
, mono_class_from_mono_type (subtype
));
3749 mono_class_set_nested_classes_property (klass
, nested
);
3752 klass
->nested_classes_inited
= TRUE
;
3754 typebuilder_setup_fields (klass
, error
);
3755 goto_if_nok (error
, failure
);
3756 typebuilder_setup_properties (klass
, error
);
3757 goto_if_nok (error
, failure
);
3759 typebuilder_setup_events (klass
, error
);
3760 goto_if_nok (error
, failure
);
3762 klass
->wastypebuilder
= TRUE
;
3764 MonoArrayHandle generic_params
= MONO_HANDLE_NEW_GET (MonoArray
, ref_tb
, generic_params
);
3765 if (!MONO_HANDLE_IS_NULL (generic_params
)) {
3766 int num_params
= mono_array_handle_length (generic_params
);
3767 MonoReflectionTypeHandle ref_gparam
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
3768 for (int i
= 0; i
< num_params
; i
++) {
3769 MONO_HANDLE_ARRAY_GETREF (ref_gparam
, generic_params
, i
);
3770 MonoType
*param_type
= mono_reflection_type_handle_mono_type (ref_gparam
, error
);
3771 goto_if_nok (error
, failure
);
3772 MonoClass
*gklass
= mono_class_from_mono_type (param_type
);
3774 gklass
->wastypebuilder
= TRUE
;
3779 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3780 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3781 * we want to return normal System.MonoType objects, so clear these out from the cache.
3783 * Together with this we must ensure the contents of all instances to match the created type.
3785 if (domain
->type_hash
&& mono_class_is_gtd (klass
)) {
3786 struct remove_instantiations_user_data data
;
3789 mono_error_assert_ok (error
);
3790 mono_g_hash_table_foreach_remove (domain
->type_hash
, remove_instantiations_of_and_ensure_contents
, &data
);
3791 goto_if_nok (error
, failure
);
3794 mono_domain_unlock (domain
);
3795 mono_loader_unlock ();
3797 if (klass
->enumtype
&& !mono_class_is_valid_enum (klass
)) {
3798 mono_class_set_type_load_failure (klass
, "Not a valid enumeration");
3799 mono_error_set_type_load_class (error
, klass
, "Not a valid enumeration");
3800 goto failure_unlocked
;
3803 MonoReflectionTypeHandle res
= mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
3804 goto_if_nok (error
, failure_unlocked
);
3809 mono_class_set_type_load_failure (klass
, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error
));
3810 klass
->wastypebuilder
= TRUE
;
3811 mono_domain_unlock (domain
);
3812 mono_loader_unlock ();
3820 } DynamicMethodReleaseData
;
3823 * The runtime automatically clean up those after finalization.
3825 static MonoReferenceQueue
*dynamic_method_queue
;
3828 free_dynamic_method (void *dynamic_method
)
3830 DynamicMethodReleaseData
*data
= (DynamicMethodReleaseData
*)dynamic_method
;
3831 MonoDomain
*domain
= data
->domain
;
3832 MonoMethod
*method
= data
->handle
;
3835 mono_domain_lock (domain
);
3836 dis_link
= (guint32
)(size_t)g_hash_table_lookup (domain
->method_to_dyn_method
, method
);
3837 g_hash_table_remove (domain
->method_to_dyn_method
, method
);
3838 mono_domain_unlock (domain
);
3839 g_assert (dis_link
);
3840 mono_gchandle_free (dis_link
);
3842 mono_runtime_free_method (domain
, method
);
3847 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb
, MonoError
*error
)
3849 MonoReferenceQueue
*queue
;
3851 DynamicMethodReleaseData
*release_data
;
3852 ReflectionMethodBuilder rmb
;
3853 MonoMethodSignature
*sig
;
3861 if (mono_runtime_is_shutting_down ()) {
3862 mono_error_set_generic_error (error
, "System", "InvalidOperationException", "");
3866 if (!(queue
= dynamic_method_queue
)) {
3867 mono_loader_lock ();
3868 if (!(queue
= dynamic_method_queue
))
3869 queue
= dynamic_method_queue
= mono_gc_reference_queue_new (free_dynamic_method
);
3870 mono_loader_unlock ();
3873 sig
= dynamic_method_to_signature (ref_mb
, error
);
3874 return_val_if_nok (error
, FALSE
);
3876 MonoReflectionDynamicMethod
*mb
= MONO_HANDLE_RAW (ref_mb
); /* FIXME convert reflection_create_dynamic_method to use handles */
3877 reflection_methodbuilder_from_dynamic_method (&rmb
, mb
);
3880 * Resolve references.
3883 * Every second entry in the refs array is reserved for storing handle_class,
3884 * which is needed by the ldtoken implementation in the JIT.
3886 rmb
.nrefs
= mb
->nrefs
;
3887 rmb
.refs
= g_new0 (gpointer
, mb
->nrefs
+ 1);
3888 for (i
= 0; i
< mb
->nrefs
; i
+= 2) {
3889 MonoClass
*handle_class
;
3891 MonoObject
*obj
= mono_array_get (mb
->refs
, MonoObject
*, i
);
3893 if (strcmp (obj
->vtable
->klass
->name
, "DynamicMethod") == 0) {
3894 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
3896 * The referenced DynamicMethod should already be created by the managed
3897 * code, except in the case of circular references. In that case, we store
3898 * method in the refs array, and fix it up later when the referenced
3899 * DynamicMethod is created.
3901 if (method
->mhandle
) {
3902 ref
= method
->mhandle
;
3904 /* FIXME: GC object stored in unmanaged memory */
3907 /* FIXME: GC object stored in unmanaged memory */
3908 method
->referenced_by
= g_slist_append (method
->referenced_by
, mb
);
3910 handle_class
= mono_defaults
.methodhandle_class
;
3912 MonoException
*ex
= NULL
;
3913 ref
= mono_reflection_resolve_object (mb
->module
->image
, obj
, &handle_class
, NULL
, error
);
3914 if (!is_ok (error
)) {
3919 ex
= mono_get_exception_type_load (NULL
, NULL
);
3920 else if (mono_security_core_clr_enabled ())
3921 ex
= mono_security_core_clr_ensure_dynamic_method_resolved_object (ref
, handle_class
);
3925 mono_error_set_exception_instance (error
, ex
);
3930 rmb
.refs
[i
] = ref
; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3931 rmb
.refs
[i
+ 1] = handle_class
;
3934 MonoAssembly
*ass
= NULL
;
3936 MonoType
*owner_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)mb
->owner
, error
);
3937 if (!is_ok (error
)) {
3941 klass
= mono_class_from_mono_type (owner_type
);
3942 ass
= klass
->image
->assembly
;
3944 klass
= mono_defaults
.object_class
;
3945 ass
= (mb
->module
&& mb
->module
->image
) ? mb
->module
->image
->assembly
: NULL
;
3948 mb
->mhandle
= handle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3949 ((MonoDynamicMethod
*)handle
)->assembly
= ass
;
3951 return_val_if_nok (error
, FALSE
);
3953 release_data
= g_new (DynamicMethodReleaseData
, 1);
3954 release_data
->handle
= handle
;
3955 release_data
->domain
= mono_object_get_domain ((MonoObject
*)mb
);
3956 if (!mono_gc_reference_queue_add (queue
, (MonoObject
*)mb
, release_data
))
3957 g_free (release_data
);
3959 /* Fix up refs entries pointing at us */
3960 for (l
= mb
->referenced_by
; l
; l
= l
->next
) {
3961 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)l
->data
;
3962 MonoMethodWrapper
*wrapper
= (MonoMethodWrapper
*)method
->mhandle
;
3965 g_assert (method
->mhandle
);
3967 data
= (gpointer
*)wrapper
->method_data
;
3968 for (i
= 0; i
< GPOINTER_TO_UINT (data
[0]); i
+= 2) {
3969 if ((data
[i
+ 1] == mb
) && (data
[i
+ 1 + 1] == mono_defaults
.methodhandle_class
))
3970 data
[i
+ 1] = mb
->mhandle
;
3973 g_slist_free (mb
->referenced_by
);
3975 /* ilgen is no longer needed */
3978 domain
= mono_domain_get ();
3979 mono_domain_lock (domain
);
3980 if (!domain
->method_to_dyn_method
)
3981 domain
->method_to_dyn_method
= g_hash_table_new (NULL
, NULL
);
3982 g_hash_table_insert (domain
->method_to_dyn_method
, handle
, (gpointer
)(size_t)mono_gchandle_new_weakref ((MonoObject
*)mb
, TRUE
));
3983 mono_domain_unlock (domain
);
3989 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
3991 (void) reflection_create_dynamic_method (mb
, error
);
3994 #endif /* DISABLE_REFLECTION_EMIT */
3996 MonoMethodSignature
*
3997 mono_reflection_lookup_signature (MonoImage
*image
, MonoMethod
*method
, guint32 token
, MonoError
*error
)
3999 MonoMethodSignature
*sig
;
4000 g_assert (image_is_dynamic (image
));
4004 sig
= (MonoMethodSignature
*)g_hash_table_lookup (((MonoDynamicImage
*)image
)->vararg_aux_hash
, GUINT_TO_POINTER (token
));
4008 return mono_method_signature_checked (method
, error
);
4011 #ifndef DISABLE_REFLECTION_EMIT
4014 * ensure_complete_type:
4016 * Ensure that KLASS is completed if it is a dynamic type, or references
4020 ensure_complete_type (MonoClass
*klass
, MonoError
*error
)
4024 if (image_is_dynamic (klass
->image
) && !klass
->wastypebuilder
&& mono_class_has_ref_info (klass
)) {
4025 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info_raw (klass
); /* FIXME use handles */
4027 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4028 return_if_nok (error
);
4030 // Asserting here could break a lot of code
4031 //g_assert (klass->wastypebuilder);
4034 if (mono_class_is_ginst (klass
)) {
4035 MonoGenericInst
*inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
4038 for (i
= 0; i
< inst
->type_argc
; ++i
) {
4039 ensure_complete_type (mono_class_from_mono_type (inst
->type_argv
[i
]), error
);
4040 return_if_nok (error
);
4046 mono_reflection_resolve_object (MonoImage
*image
, MonoObject
*obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
4048 MonoClass
*oklass
= obj
->vtable
->klass
;
4049 gpointer result
= NULL
;
4053 if (strcmp (oklass
->name
, "String") == 0) {
4054 result
= mono_string_intern_checked ((MonoString
*)obj
, error
);
4055 return_val_if_nok (error
, NULL
);
4056 *handle_class
= mono_defaults
.string_class
;
4058 } else if (strcmp (oklass
->name
, "RuntimeType") == 0) {
4059 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
4060 return_val_if_nok (error
, NULL
);
4061 MonoClass
*mc
= mono_class_from_mono_type (type
);
4062 if (!mono_class_init (mc
)) {
4063 mono_error_set_for_class_failure (error
, mc
);
4068 MonoType
*inflated
= mono_class_inflate_generic_type_checked (type
, context
, error
);
4069 return_val_if_nok (error
, NULL
);
4071 result
= mono_class_from_mono_type (inflated
);
4072 mono_metadata_free_type (inflated
);
4074 result
= mono_class_from_mono_type (type
);
4076 *handle_class
= mono_defaults
.typehandle_class
;
4078 } else if (strcmp (oklass
->name
, "MonoMethod") == 0 ||
4079 strcmp (oklass
->name
, "MonoCMethod") == 0) {
4080 result
= ((MonoReflectionMethod
*)obj
)->method
;
4082 result
= mono_class_inflate_generic_method_checked ((MonoMethod
*)result
, context
, error
);
4083 mono_error_assert_ok (error
);
4085 *handle_class
= mono_defaults
.methodhandle_class
;
4087 } else if (strcmp (oklass
->name
, "MonoField") == 0) {
4088 MonoClassField
*field
= ((MonoReflectionField
*)obj
)->field
;
4090 ensure_complete_type (field
->parent
, error
);
4091 return_val_if_nok (error
, NULL
);
4094 MonoType
*inflated
= mono_class_inflate_generic_type_checked (&field
->parent
->byval_arg
, context
, error
);
4095 return_val_if_nok (error
, NULL
);
4097 MonoClass
*klass
= mono_class_from_mono_type (inflated
);
4098 MonoClassField
*inflated_field
;
4099 gpointer iter
= NULL
;
4100 mono_metadata_free_type (inflated
);
4101 while ((inflated_field
= mono_class_get_fields (klass
, &iter
))) {
4102 if (!strcmp (field
->name
, inflated_field
->name
))
4105 g_assert (inflated_field
&& !strcmp (field
->name
, inflated_field
->name
));
4106 result
= inflated_field
;
4110 *handle_class
= mono_defaults
.fieldhandle_class
;
4112 } else if (strcmp (oklass
->name
, "TypeBuilder") == 0) {
4113 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)obj
;
4114 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)tb
, error
);
4115 return_val_if_nok (error
, NULL
);
4118 klass
= type
->data
.klass
;
4119 if (klass
->wastypebuilder
) {
4120 /* Already created */
4124 mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb
, error
);
4125 return_val_if_nok (error
, NULL
);
4126 result
= type
->data
.klass
;
4129 *handle_class
= mono_defaults
.typehandle_class
;
4130 } else if (strcmp (oklass
->name
, "SignatureHelper") == 0) {
4131 MonoReflectionSigHelper
*helper
= (MonoReflectionSigHelper
*)obj
;
4132 MonoMethodSignature
*sig
;
4135 if (helper
->arguments
)
4136 nargs
= mono_array_length (helper
->arguments
);
4140 sig
= mono_metadata_signature_alloc (image
, nargs
);
4141 sig
->explicit_this
= helper
->call_conv
& 64 ? 1 : 0;
4142 sig
->hasthis
= helper
->call_conv
& 32 ? 1 : 0;
4144 if (helper
->unmanaged_call_conv
) { /* unmanaged */
4145 sig
->call_convention
= helper
->unmanaged_call_conv
- 1;
4146 sig
->pinvoke
= TRUE
;
4147 } else if (helper
->call_conv
& 0x02) {
4148 sig
->call_convention
= MONO_CALL_VARARG
;
4150 sig
->call_convention
= MONO_CALL_DEFAULT
;
4153 sig
->param_count
= nargs
;
4154 /* TODO: Copy type ? */
4155 sig
->ret
= helper
->return_type
->type
;
4156 for (i
= 0; i
< nargs
; ++i
) {
4157 sig
->params
[i
] = mono_type_array_get_and_resolve_raw (helper
->arguments
, i
, error
); /* FIXME use handles */
4158 if (!is_ok (error
)) {
4159 image_g_free (image
, sig
);
4165 *handle_class
= NULL
;
4166 } else if (strcmp (oklass
->name
, "DynamicMethod") == 0) {
4167 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
4168 /* Already created by the managed code */
4169 g_assert (method
->mhandle
);
4170 result
= method
->mhandle
;
4171 *handle_class
= mono_defaults
.methodhandle_class
;
4172 } else if (strcmp (oklass
->name
, "MonoArrayMethod") == 0) {
4173 MonoReflectionArrayMethod
*m
= (MonoReflectionArrayMethod
*)obj
;
4180 mtype
= mono_reflection_type_get_handle (m
->parent
, error
);
4181 return_val_if_nok (error
, NULL
);
4182 klass
= mono_class_from_mono_type (mtype
);
4184 /* Find the method */
4186 name
= mono_string_to_utf8_checked (m
->name
, error
);
4187 return_val_if_nok (error
, NULL
);
4189 while ((method
= mono_class_get_methods (klass
, &iter
))) {
4190 if (!strcmp (method
->name
, name
))
4197 // FIXME: Check parameters/return value etc. match
4200 *handle_class
= mono_defaults
.methodhandle_class
;
4201 } else if (is_sre_method_builder (oklass
) ||
4202 mono_is_sre_ctor_builder (oklass
) ||
4203 is_sre_field_builder (oklass
) ||
4204 is_sre_gparam_builder (oklass
) ||
4205 is_sre_generic_instance (oklass
) ||
4206 is_sre_array (oklass
) ||
4207 is_sre_byref (oklass
) ||
4208 is_sre_pointer (oklass
) ||
4209 !strcmp (oklass
->name
, "FieldOnTypeBuilderInst") ||
4210 !strcmp (oklass
->name
, "MethodOnTypeBuilderInst") ||
4211 !strcmp (oklass
->name
, "ConstructorOnTypeBuilderInst")) {
4212 static MonoMethod
*resolve_method
;
4213 if (!resolve_method
) {
4214 MonoMethod
*m
= mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4216 mono_memory_barrier ();
4221 obj
= mono_runtime_invoke_checked (resolve_method
, NULL
, args
, error
);
4222 mono_error_assert_ok (error
);
4224 return mono_reflection_resolve_object (image
, obj
, handle_class
, context
, error
);
4226 g_print ("%s\n", obj
->vtable
->klass
->name
);
4227 g_assert_not_reached ();
4232 #else /* DISABLE_REFLECTION_EMIT */
4235 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4237 g_assert_not_reached ();
4242 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4244 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4248 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4250 g_assert_not_reached ();
4255 mono_image_insert_string (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4257 g_assert_not_reached ();
4262 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
, MonoArrayHandle opt_param_types
, MonoError
*error
)
4264 g_assert_not_reached ();
4269 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObjectHandle obj
,
4270 gboolean create_open_instance
, gboolean register_token
, MonoError
*error
)
4272 g_assert_not_reached ();
4277 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
4284 MonoReflectionTypeHandle
4285 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb
, MonoError
*error
)
4287 g_assert_not_reached ();
4292 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb
, MonoError
*error
)
4298 mono_reflection_type_get_handle (MonoReflectionType
* ref
, MonoError
*error
)
4307 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref
, MonoError
*error
)
4310 if (MONO_HANDLE_IS_NULL (ref
))
4312 return MONO_HANDLE_GETVAL (ref
, type
);
4316 #endif /* DISABLE_REFLECTION_EMIT */
4319 mono_sre_generic_param_table_entry_free (GenericParamTableEntry
*entry
)
4321 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry
->gparam
);
4326 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, gboolean create_open_instance
, MonoError
*error
)
4329 if (MONO_HANDLE_IS_NULL (obj
)) {
4330 mono_error_set_argument_null (error
, "obj", "");
4333 return mono_image_create_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), obj
, create_open_instance
, TRUE
, error
);
4337 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb
,
4338 MonoReflectionMethodHandle method
,
4339 MonoArrayHandle opt_param_types
,
4343 if (MONO_HANDLE_IS_NULL (method
)) {
4344 mono_error_set_argument_null (error
, "method", "");
4348 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), MONO_HANDLE_CAST (MonoObject
, method
), opt_param_types
, error
);
4352 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
4355 mono_image_create_pefile (mb
, file
, &error
);
4356 mono_error_set_pending_exception (&error
);
4360 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
4363 mono_image_build_metadata (mb
, &error
);
4364 mono_error_set_pending_exception (&error
);
4368 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb
, MonoObjectHandle obj
, guint32 token
, MonoError
*error
)
4371 /* This function may be called by ModuleBuilder.FixupTokens to update
4372 * an existing token, so replace is okay here. */
4373 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb
, dynamic_image
), token
, obj
, MONO_DYN_IMAGE_TOK_REPLACE
);
4377 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb
, guint32 token
, MonoError
*error
)
4380 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
4381 return mono_dynamic_image_get_registered_token (dynamic_image
, token
, error
);
4384 #ifndef DISABLE_REFLECTION_EMIT
4386 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4389 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, &error
);
4390 mono_error_set_pending_exception (&error
);
4396 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4398 mono_reflection_dynimage_basic_init (assemblyb
);
4402 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb
, MonoError
*error
)
4404 MonoArrayHandle cattrs
= MONO_HANDLE_NEW_GET (MonoArray
, assemblyb
, cattrs
);
4406 MonoReflectionAssemblyHandle assembly_handle
= MONO_HANDLE_CAST (MonoReflectionAssembly
, assemblyb
);
4407 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_handle
, assembly
);
4408 g_assert (assembly
);
4410 mono_save_custom_attrs (assembly
->image
, assembly
, MONO_HANDLE_RAW (cattrs
));
4414 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype
,
4415 MonoReflectionTypeHandle t
,
4419 MONO_HANDLE_SETVAL (enumtype
, type
, MonoType
*, MONO_HANDLE_GETVAL (t
, type
));
4423 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb
, MonoError
*error
)
4426 mono_image_module_basic_init (moduleb
, error
);
4430 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module
, MonoStringHandle str
, MonoError
*error
)
4432 return mono_image_insert_string (module
, str
, error
);
4436 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb
, MonoReflectionTypeHandle ref_type
, MonoError
*error
)
4439 MonoDynamicImage
*image
= MONO_HANDLE_GETVAL (moduleb
, dynamic_image
);
4440 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4443 image
->wrappers_type
= mono_class_from_mono_type (type
);