2 * sre.c: Routines for creating an image at runtime
3 * and related System.Reflection.Emit icalls
7 * Paolo Molaro (lupus@ximian.com)
9 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
11 * Copyright 2011 Rodrigo Kumpera
12 * Copyright 2016 Microsoft
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
18 #include "mono/metadata/assembly.h"
19 #include "mono/metadata/debug-helpers.h"
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/exception.h"
23 #include "mono/metadata/gc-internals.h"
24 #include "mono/metadata/mono-ptr-array.h"
25 #include "mono/metadata/object-internals.h"
26 #include "mono/metadata/profiler-private.h"
27 #include "mono/metadata/reflection-internals.h"
28 #include "mono/metadata/reflection-cache.h"
29 #include "mono/metadata/sre-internals.h"
30 #include "mono/metadata/custom-attrs-internals.h"
31 #include "mono/metadata/security-manager.h"
32 #include "mono/metadata/security-core-clr.h"
33 #include "mono/metadata/tabledefs.h"
34 #include "mono/metadata/tokentype.h"
35 #include "mono/utils/checked-build.h"
36 #include "mono/utils/mono-digest.h"
38 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute
, System
.Runtime
.InteropServices
, MarshalAsAttribute
);
39 static GENERATE_GET_CLASS_WITH_CACHE (module_builder
, System
.Reflection
.Emit
, ModuleBuilder
);
41 #ifndef DISABLE_REFLECTION_EMIT
42 static guint32
mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
);
43 static guint32
mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelper
*helper
, MonoError
*error
);
44 static gboolean
ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
);
45 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
);
46 static gboolean
reflection_setup_internal_class (MonoReflectionTypeBuilder
*tb
, MonoError
*error
);
48 static gpointer
register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
);
51 static char* type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
);
52 static MonoReflectionType
*mono_reflection_type_get_underlying_system_type (MonoReflectionType
* t
, MonoError
*error
);
53 static gboolean
is_sre_array (MonoClass
*klass
);
54 static gboolean
is_sre_byref (MonoClass
*klass
);
55 static gboolean
is_sre_pointer (MonoClass
*klass
);
56 static gboolean
is_sre_generic_instance (MonoClass
*klass
);
57 static gboolean
is_sre_type_builder (MonoClass
*klass
);
58 static gboolean
is_sre_method_builder (MonoClass
*klass
);
59 static gboolean
is_sre_field_builder (MonoClass
*klass
);
60 static gboolean
is_sre_gparam_builder (MonoClass
*klass
);
61 static gboolean
is_sre_enum_builder (MonoClass
*klass
);
62 static gboolean
is_sr_mono_method (MonoClass
*klass
);
63 static gboolean
is_sr_mono_field (MonoClass
*klass
);
65 static guint32
mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
);
66 static guint32
mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
);
68 #define mono_type_array_get_and_resolve(array, index, error) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index), error)
70 static void mono_image_module_basic_init (MonoReflectionModuleBuilder
*module
);
73 mono_reflection_emit_init (void)
75 mono_dynamic_images_init ();
79 type_get_fully_qualified_name (MonoType
*type
)
81 MONO_REQ_GC_NEUTRAL_MODE
;
83 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
87 type_get_qualified_name (MonoType
*type
, MonoAssembly
*ass
)
89 MONO_REQ_GC_UNSAFE_MODE
;
94 klass
= mono_class_from_mono_type (type
);
96 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
97 ta
= klass
->image
->assembly
;
98 if (assembly_is_dynamic (ta
) || (ta
== ass
)) {
99 if (mono_class_is_ginst (klass
) || mono_class_is_gtd (klass
))
100 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
101 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_FULL_NAME
);
103 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_REFLECTION
);
106 return mono_type_get_name_full (type
, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
);
109 #ifndef DISABLE_REFLECTION_EMIT
113 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
117 image_g_malloc (MonoImage
*image
, guint size
)
119 MONO_REQ_GC_NEUTRAL_MODE
;
122 return mono_image_alloc (image
, size
);
124 return g_malloc (size
);
126 #endif /* !DISABLE_REFLECTION_EMIT */
131 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
135 mono_image_g_malloc0 (MonoImage
*image
, guint size
)
137 MONO_REQ_GC_NEUTRAL_MODE
;
140 return mono_image_alloc0 (image
, size
);
142 return g_malloc0 (size
);
147 * @image: a MonoImage
150 * If @image is NULL, free @ptr, otherwise do nothing.
153 image_g_free (MonoImage
*image
, gpointer ptr
)
159 #ifndef DISABLE_REFLECTION_EMIT
161 image_strdup (MonoImage
*image
, const char *s
)
163 MONO_REQ_GC_NEUTRAL_MODE
;
166 return mono_image_strdup (image
, s
);
172 #define image_g_new(image,struct_type, n_structs) \
173 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
175 #define image_g_new0(image,struct_type, n_structs) \
176 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
180 alloc_table (MonoDynamicTable
*table
, guint nrows
)
182 mono_dynimage_alloc_table (table
, nrows
);
186 string_heap_insert (MonoDynamicStream
*sh
, const char *str
)
188 return mono_dynstream_insert_string (sh
, str
);
192 mono_image_add_stream_data (MonoDynamicStream
*stream
, const char *data
, guint32 len
)
194 return mono_dynstream_add_data (stream
, data
, len
);
198 * Despite the name, we handle also TypeSpec (with the above helper).
201 mono_image_typedef_or_ref (MonoDynamicImage
*assembly
, MonoType
*type
)
203 return mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, TRUE
);
207 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
208 * dest may be misaligned.
211 swap_with_size (char *dest
, const char* val
, int len
, int nelem
) {
212 MONO_REQ_GC_NEUTRAL_MODE
;
213 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
216 for (elem
= 0; elem
< nelem
; ++elem
) {
242 g_assert_not_reached ();
248 memcpy (dest
, val
, len
* nelem
);
253 mono_reflection_method_count_clauses (MonoReflectionILGen
*ilgen
)
255 MONO_REQ_GC_UNSAFE_MODE
;
257 guint32 num_clauses
= 0;
260 MonoILExceptionInfo
*ex_info
;
261 for (i
= 0; i
< mono_array_length (ilgen
->ex_handlers
); ++i
) {
262 ex_info
= (MonoILExceptionInfo
*)mono_array_addr (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
263 if (ex_info
->handlers
)
264 num_clauses
+= mono_array_length (ex_info
->handlers
);
272 #ifndef DISABLE_REFLECTION_EMIT
273 static MonoExceptionClause
*
274 method_encode_clauses (MonoImage
*image
, MonoDynamicImage
*assembly
, MonoReflectionILGen
*ilgen
, guint32 num_clauses
, MonoError
*error
)
276 MONO_REQ_GC_UNSAFE_MODE
;
278 mono_error_init (error
);
280 MonoExceptionClause
*clauses
;
281 MonoExceptionClause
*clause
;
282 MonoILExceptionInfo
*ex_info
;
283 MonoILExceptionBlock
*ex_block
;
284 guint32 finally_start
;
285 int i
, j
, clause_index
;;
287 clauses
= image_g_new0 (image
, MonoExceptionClause
, num_clauses
);
290 for (i
= mono_array_length (ilgen
->ex_handlers
) - 1; i
>= 0; --i
) {
291 ex_info
= (MonoILExceptionInfo
*)mono_array_addr (ilgen
->ex_handlers
, MonoILExceptionInfo
, i
);
292 finally_start
= ex_info
->start
+ ex_info
->len
;
293 if (!ex_info
->handlers
)
295 for (j
= 0; j
< mono_array_length (ex_info
->handlers
); ++j
) {
296 ex_block
= (MonoILExceptionBlock
*)mono_array_addr (ex_info
->handlers
, MonoILExceptionBlock
, j
);
297 clause
= &(clauses
[clause_index
]);
299 clause
->flags
= ex_block
->type
;
300 clause
->try_offset
= ex_info
->start
;
302 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FINALLY
)
303 clause
->try_len
= finally_start
- ex_info
->start
;
305 clause
->try_len
= ex_info
->len
;
306 clause
->handler_offset
= ex_block
->start
;
307 clause
->handler_len
= ex_block
->len
;
308 if (ex_block
->extype
) {
309 MonoType
*extype
= mono_reflection_type_get_handle ((MonoReflectionType
*)ex_block
->extype
, error
);
311 if (!is_ok (error
)) {
312 image_g_free (image
, clauses
);
315 clause
->data
.catch_class
= mono_class_from_mono_type (extype
);
317 if (ex_block
->type
== MONO_EXCEPTION_CLAUSE_FILTER
)
318 clause
->data
.filter_offset
= ex_block
->filter_offset
;
320 clause
->data
.filter_offset
= 0;
322 finally_start
= ex_block
->start
+ ex_block
->len
;
330 #endif /* !DISABLE_REFLECTION_EMIT */
332 #ifndef DISABLE_REFLECTION_EMIT
334 * LOCKING: Acquires the loader lock.
337 mono_save_custom_attrs (MonoImage
*image
, void *obj
, MonoArray
*cattrs
)
339 MONO_REQ_GC_UNSAFE_MODE
;
341 MonoCustomAttrInfo
*ainfo
, *tmp
;
343 if (!cattrs
|| !mono_array_length (cattrs
))
346 ainfo
= mono_custom_attrs_from_builders (image
, image
, cattrs
);
349 tmp
= (MonoCustomAttrInfo
*)mono_image_property_lookup (image
, obj
, MONO_PROP_DYNAMIC_CATTR
);
351 mono_custom_attrs_free (tmp
);
352 mono_image_property_insert (image
, obj
, MONO_PROP_DYNAMIC_CATTR
, ainfo
);
353 mono_loader_unlock ();
359 mono_reflection_resolution_scope_from_image (MonoDynamicImage
*assembly
, MonoImage
*image
)
361 MONO_REQ_GC_UNSAFE_MODE
;
363 MonoDynamicTable
*table
;
366 guint32 cols
[MONO_ASSEMBLY_SIZE
];
370 if ((token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, image
))))
373 if (assembly_is_dynamic (image
->assembly
) && (image
->assembly
== assembly
->image
.assembly
)) {
374 table
= &assembly
->tables
[MONO_TABLE_MODULEREF
];
375 token
= table
->next_idx
++;
377 alloc_table (table
, table
->rows
);
378 values
= table
->values
+ token
* MONO_MODULEREF_SIZE
;
379 values
[MONO_MODULEREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->module_name
);
381 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
382 token
|= MONO_RESOLUTION_SCOPE_MODULEREF
;
383 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
388 if (assembly_is_dynamic (image
->assembly
))
390 memset (cols
, 0, sizeof (cols
));
392 /* image->assembly->image is the manifest module */
393 image
= image
->assembly
->image
;
394 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_ASSEMBLY
], 0, cols
, MONO_ASSEMBLY_SIZE
);
397 table
= &assembly
->tables
[MONO_TABLE_ASSEMBLYREF
];
398 token
= table
->next_idx
++;
400 alloc_table (table
, table
->rows
);
401 values
= table
->values
+ token
* MONO_ASSEMBLYREF_SIZE
;
402 values
[MONO_ASSEMBLYREF_NAME
] = string_heap_insert (&assembly
->sheap
, image
->assembly_name
);
403 values
[MONO_ASSEMBLYREF_MAJOR_VERSION
] = cols
[MONO_ASSEMBLY_MAJOR_VERSION
];
404 values
[MONO_ASSEMBLYREF_MINOR_VERSION
] = cols
[MONO_ASSEMBLY_MINOR_VERSION
];
405 values
[MONO_ASSEMBLYREF_BUILD_NUMBER
] = cols
[MONO_ASSEMBLY_BUILD_NUMBER
];
406 values
[MONO_ASSEMBLYREF_REV_NUMBER
] = cols
[MONO_ASSEMBLY_REV_NUMBER
];
407 values
[MONO_ASSEMBLYREF_FLAGS
] = 0;
408 values
[MONO_ASSEMBLYREF_CULTURE
] = 0;
409 values
[MONO_ASSEMBLYREF_HASH_VALUE
] = 0;
411 if (strcmp ("", image
->assembly
->aname
.culture
)) {
412 values
[MONO_ASSEMBLYREF_CULTURE
] = string_heap_insert (&assembly
->sheap
,
413 image
->assembly
->aname
.culture
);
416 if ((pubkey
= mono_image_get_public_key (image
, &publen
))) {
419 mono_digest_get_public_token (pubtoken
+ 1, (guchar
*)pubkey
, publen
);
420 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = mono_image_add_stream_data (&assembly
->blob
, (char*)pubtoken
, 9);
422 values
[MONO_ASSEMBLYREF_PUBLIC_KEY
] = 0;
424 token
<<= MONO_RESOLUTION_SCOPE_BITS
;
425 token
|= MONO_RESOLUTION_SCOPE_ASSEMBLYREF
;
426 g_hash_table_insert (assembly
->handleref
, image
, GUINT_TO_POINTER (token
));
430 #ifndef DISABLE_REFLECTION_EMIT
432 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
)
434 MONO_REQ_GC_UNSAFE_MODE
;
436 mono_error_init (error
);
437 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
439 rmb
->ilgen
= mb
->ilgen
;
440 rmb
->rtype
= (MonoReflectionType
*)mb
->rtype
;
441 return_val_if_nok (error
, FALSE
);
442 rmb
->parameters
= mb
->parameters
;
443 rmb
->generic_params
= mb
->generic_params
;
444 rmb
->generic_container
= mb
->generic_container
;
445 rmb
->opt_types
= NULL
;
446 rmb
->pinfo
= mb
->pinfo
;
447 rmb
->attrs
= mb
->attrs
;
448 rmb
->iattrs
= mb
->iattrs
;
449 rmb
->call_conv
= mb
->call_conv
;
450 rmb
->code
= mb
->code
;
451 rmb
->type
= mb
->type
;
452 rmb
->name
= mb
->name
;
453 rmb
->table_idx
= &mb
->table_idx
;
454 rmb
->init_locals
= mb
->init_locals
;
455 rmb
->skip_visibility
= FALSE
;
456 rmb
->return_modreq
= mb
->return_modreq
;
457 rmb
->return_modopt
= mb
->return_modopt
;
458 rmb
->param_modreq
= mb
->param_modreq
;
459 rmb
->param_modopt
= mb
->param_modopt
;
460 rmb
->permissions
= mb
->permissions
;
461 rmb
->mhandle
= mb
->mhandle
;
466 rmb
->charset
= mb
->charset
;
467 rmb
->extra_flags
= mb
->extra_flags
;
468 rmb
->native_cc
= mb
->native_cc
;
469 rmb
->dllentry
= mb
->dllentry
;
477 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
479 MONO_REQ_GC_UNSAFE_MODE
;
481 const char *name
= mb
->attrs
& METHOD_ATTRIBUTE_STATIC
? ".cctor": ".ctor";
483 mono_error_init (error
);
485 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
487 rmb
->ilgen
= mb
->ilgen
;
488 rmb
->rtype
= mono_type_get_object_checked (mono_domain_get (), &mono_defaults
.void_class
->byval_arg
, error
);
489 return_val_if_nok (error
, FALSE
);
490 rmb
->parameters
= mb
->parameters
;
491 rmb
->generic_params
= NULL
;
492 rmb
->generic_container
= NULL
;
493 rmb
->opt_types
= NULL
;
494 rmb
->pinfo
= mb
->pinfo
;
495 rmb
->attrs
= mb
->attrs
;
496 rmb
->iattrs
= mb
->iattrs
;
497 rmb
->call_conv
= mb
->call_conv
;
499 rmb
->type
= mb
->type
;
500 rmb
->name
= mono_string_new (mono_domain_get (), name
);
501 rmb
->table_idx
= &mb
->table_idx
;
502 rmb
->init_locals
= mb
->init_locals
;
503 rmb
->skip_visibility
= FALSE
;
504 rmb
->return_modreq
= NULL
;
505 rmb
->return_modopt
= NULL
;
506 rmb
->param_modreq
= mb
->param_modreq
;
507 rmb
->param_modopt
= mb
->param_modopt
;
508 rmb
->permissions
= mb
->permissions
;
509 rmb
->mhandle
= mb
->mhandle
;
517 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder
*rmb
, MonoReflectionDynamicMethod
*mb
)
519 MONO_REQ_GC_UNSAFE_MODE
;
521 memset (rmb
, 0, sizeof (ReflectionMethodBuilder
));
523 rmb
->ilgen
= mb
->ilgen
;
524 rmb
->rtype
= mb
->rtype
;
525 rmb
->parameters
= mb
->parameters
;
526 rmb
->generic_params
= NULL
;
527 rmb
->generic_container
= NULL
;
528 rmb
->opt_types
= NULL
;
530 rmb
->attrs
= mb
->attrs
;
532 rmb
->call_conv
= mb
->call_conv
;
534 rmb
->type
= (MonoObject
*) mb
->owner
;
535 rmb
->name
= mb
->name
;
536 rmb
->table_idx
= NULL
;
537 rmb
->init_locals
= mb
->init_locals
;
538 rmb
->skip_visibility
= mb
->skip_visibility
;
539 rmb
->return_modreq
= NULL
;
540 rmb
->return_modopt
= NULL
;
541 rmb
->param_modreq
= NULL
;
542 rmb
->param_modopt
= NULL
;
543 rmb
->permissions
= NULL
;
544 rmb
->mhandle
= mb
->mhandle
;
548 #else /* DISABLE_REFLECTION_EMIT */
550 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionMethodBuilder
*mb
, MonoError
*error
) {
551 g_assert_not_reached ();
555 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
*rmb
, MonoReflectionCtorBuilder
*mb
, MonoError
*error
)
557 g_assert_not_reached ();
560 #endif /* DISABLE_REFLECTION_EMIT */
562 #ifndef DISABLE_REFLECTION_EMIT
564 mono_image_add_memberef_row (MonoDynamicImage
*assembly
, guint32 parent
, const char *name
, guint32 sig
)
566 MONO_REQ_GC_NEUTRAL_MODE
;
568 MonoDynamicTable
*table
;
570 guint32 token
, pclass
;
572 switch (parent
& MONO_TYPEDEFORREF_MASK
) {
573 case MONO_TYPEDEFORREF_TYPEREF
:
574 pclass
= MONO_MEMBERREF_PARENT_TYPEREF
;
576 case MONO_TYPEDEFORREF_TYPESPEC
:
577 pclass
= MONO_MEMBERREF_PARENT_TYPESPEC
;
579 case MONO_TYPEDEFORREF_TYPEDEF
:
580 pclass
= MONO_MEMBERREF_PARENT_TYPEDEF
;
583 g_warning ("unknown typeref or def token 0x%08x for %s", parent
, name
);
586 /* extract the index */
587 parent
>>= MONO_TYPEDEFORREF_BITS
;
589 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
591 if (assembly
->save
) {
592 alloc_table (table
, table
->rows
+ 1);
593 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
594 values
[MONO_MEMBERREF_CLASS
] = pclass
| (parent
<< MONO_MEMBERREF_PARENT_BITS
);
595 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
596 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
599 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
606 * Insert a memberef row into the metadata: the token that point to the memberref
607 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
608 * mono_image_get_fieldref_token()).
609 * The sig param is an index to an already built signature.
612 mono_image_get_memberref_token (MonoDynamicImage
*assembly
, MonoType
*type
, const char *name
, guint32 sig
)
614 MONO_REQ_GC_NEUTRAL_MODE
;
616 guint32 parent
= mono_image_typedef_or_ref (assembly
, type
);
617 return mono_image_add_memberef_row (assembly
, parent
, name
, sig
);
622 mono_image_get_methodref_token (MonoDynamicImage
*assembly
, MonoMethod
*method
, gboolean create_typespec
)
624 MONO_REQ_GC_NEUTRAL_MODE
;
627 MonoMethodSignature
*sig
;
629 create_typespec
= create_typespec
&& method
->is_generic
&& method
->klass
->image
!= &assembly
->image
;
631 if (create_typespec
) {
632 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1)));
637 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
638 if (token
&& !create_typespec
)
641 g_assert (!method
->is_inflated
);
644 * A methodref signature can't contain an unmanaged calling convention.
646 sig
= mono_metadata_signature_dup (mono_method_signature (method
));
647 if ((sig
->call_convention
!= MONO_CALL_DEFAULT
) && (sig
->call_convention
!= MONO_CALL_VARARG
))
648 sig
->call_convention
= MONO_CALL_DEFAULT
;
649 token
= mono_image_get_memberref_token (assembly
, &method
->klass
->byval_arg
,
650 method
->name
, mono_dynimage_encode_method_signature (assembly
, sig
));
652 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
655 if (create_typespec
) {
656 MonoDynamicTable
*table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
657 g_assert (mono_metadata_token_table (token
) == MONO_TABLE_MEMBERREF
);
658 token
= (mono_metadata_token_index (token
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
660 if (assembly
->save
) {
663 alloc_table (table
, table
->rows
+ 1);
664 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
665 values
[MONO_METHODSPEC_METHOD
] = token
;
666 values
[MONO_METHODSPEC_SIGNATURE
] = mono_dynimage_encode_generic_method_sig (assembly
, &mono_method_get_generic_container (method
)->context
);
669 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
671 /*methodspec and memberef tokens are diferent, */
672 g_hash_table_insert (assembly
->handleref
, GUINT_TO_POINTER (GPOINTER_TO_UINT (method
) + 1), GUINT_TO_POINTER (token
));
679 mono_image_get_varargs_method_token (MonoDynamicImage
*assembly
, guint32 original
,
680 const gchar
*name
, guint32 sig
)
682 MonoDynamicTable
*table
;
686 table
= &assembly
->tables
[MONO_TABLE_MEMBERREF
];
688 if (assembly
->save
) {
689 alloc_table (table
, table
->rows
+ 1);
690 values
= table
->values
+ table
->next_idx
* MONO_MEMBERREF_SIZE
;
691 values
[MONO_MEMBERREF_CLASS
] = original
;
692 values
[MONO_MEMBERREF_NAME
] = string_heap_insert (&assembly
->sheap
, name
);
693 values
[MONO_MEMBERREF_SIGNATURE
] = sig
;
696 token
= MONO_TOKEN_MEMBER_REF
| table
->next_idx
;
705 is_field_on_inst (MonoClassField
*field
)
707 return mono_class_is_ginst (field
->parent
) && mono_class_get_generic_class (field
->parent
)->is_dynamic
;
710 #ifndef DISABLE_REFLECTION_EMIT
712 mono_image_get_fieldref_token (MonoDynamicImage
*assembly
, MonoObject
*f
, MonoClassField
*field
)
718 g_assert (field
->parent
);
720 token
= GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly
->handleref_managed
, f
));
724 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
) {
725 int index
= field
- field
->parent
->fields
;
726 type
= mono_field_get_type (&mono_class_get_generic_class (field
->parent
)->container_class
->fields
[index
]);
728 type
= mono_field_get_type (field
);
730 token
= mono_image_get_memberref_token (assembly
, &field
->parent
->byval_arg
,
731 mono_field_get_name (field
),
732 mono_dynimage_encode_fieldref_signature (assembly
, field
->parent
->image
, type
));
733 mono_g_hash_table_insert (assembly
->handleref_managed
, f
, GUINT_TO_POINTER(token
));
738 method_encode_methodspec (MonoDynamicImage
*assembly
, MonoMethod
*method
)
740 MonoDynamicTable
*table
;
742 guint32 token
, mtoken
= 0, sig
;
743 MonoMethodInflated
*imethod
;
744 MonoMethod
*declaring
;
746 table
= &assembly
->tables
[MONO_TABLE_METHODSPEC
];
748 g_assert (method
->is_inflated
);
749 imethod
= (MonoMethodInflated
*) method
;
750 declaring
= imethod
->declaring
;
752 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature (declaring
));
753 mtoken
= mono_image_get_memberref_token (assembly
, &method
->klass
->byval_arg
, declaring
->name
, sig
);
755 if (!mono_method_signature (declaring
)->generic_param_count
)
758 switch (mono_metadata_token_table (mtoken
)) {
759 case MONO_TABLE_MEMBERREF
:
760 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODREF
;
762 case MONO_TABLE_METHOD
:
763 mtoken
= (mono_metadata_token_index (mtoken
) << MONO_METHODDEFORREF_BITS
) | MONO_METHODDEFORREF_METHODDEF
;
766 g_assert_not_reached ();
769 sig
= mono_dynimage_encode_generic_method_sig (assembly
, mono_method_get_context (method
));
771 if (assembly
->save
) {
772 alloc_table (table
, table
->rows
+ 1);
773 values
= table
->values
+ table
->next_idx
* MONO_METHODSPEC_SIZE
;
774 values
[MONO_METHODSPEC_METHOD
] = mtoken
;
775 values
[MONO_METHODSPEC_SIGNATURE
] = sig
;
778 token
= MONO_TOKEN_METHOD_SPEC
| table
->next_idx
;
785 mono_image_get_methodspec_token (MonoDynamicImage
*assembly
, MonoMethod
*method
)
787 MonoMethodInflated
*imethod
;
790 token
= GPOINTER_TO_UINT (g_hash_table_lookup (assembly
->handleref
, method
));
794 g_assert (method
->is_inflated
);
795 imethod
= (MonoMethodInflated
*) method
;
797 if (mono_method_signature (imethod
->declaring
)->generic_param_count
) {
798 token
= method_encode_methodspec (assembly
, method
);
800 guint32 sig
= mono_dynimage_encode_method_signature (
801 assembly
, mono_method_signature (imethod
->declaring
));
802 token
= mono_image_get_memberref_token (
803 assembly
, &method
->klass
->byval_arg
, method
->name
, sig
);
806 g_hash_table_insert (assembly
->handleref
, method
, GUINT_TO_POINTER(token
));
811 mono_image_get_inflated_method_token (MonoDynamicImage
*assembly
, MonoMethod
*m
)
813 MonoMethodInflated
*imethod
= (MonoMethodInflated
*) m
;
816 sig
= mono_dynimage_encode_method_signature (assembly
, mono_method_signature (imethod
->declaring
));
817 token
= mono_image_get_memberref_token (
818 assembly
, &m
->klass
->byval_arg
, m
->name
, sig
);
824 mono_image_get_sighelper_token (MonoDynamicImage
*assembly
, MonoReflectionSigHelper
*helper
, MonoError
*error
)
827 MonoDynamicTable
*table
;
830 mono_error_init (error
);
832 table
= &assembly
->tables
[MONO_TABLE_STANDALONESIG
];
833 idx
= table
->next_idx
++;
835 alloc_table (table
, table
->rows
);
836 values
= table
->values
+ idx
* MONO_STAND_ALONE_SIGNATURE_SIZE
;
838 values
[MONO_STAND_ALONE_SIGNATURE
] =
839 mono_dynimage_encode_reflection_sighelper (assembly
, helper
, error
);
840 return_val_if_nok (error
, 0);
846 reflection_cc_to_file (int call_conv
) {
847 switch (call_conv
& 0x3) {
849 case 1: return MONO_CALL_DEFAULT
;
850 case 2: return MONO_CALL_VARARG
;
852 g_assert_not_reached ();
856 #endif /* !DISABLE_REFLECTION_EMIT */
858 struct _ArrayMethod
{
860 MonoMethodSignature
*sig
;
866 mono_sre_array_method_free (ArrayMethod
*am
)
873 #ifndef DISABLE_REFLECTION_EMIT
875 mono_image_get_array_token (MonoDynamicImage
*assembly
, MonoReflectionArrayMethod
*m
, MonoError
*error
)
880 MonoMethodSignature
*sig
;
881 ArrayMethod
*am
= NULL
;
884 mono_error_init (error
);
886 nparams
= mono_array_length (m
->parameters
);
887 sig
= (MonoMethodSignature
*)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * nparams
);
889 sig
->sentinelpos
= -1;
890 sig
->call_convention
= reflection_cc_to_file (m
->call_conv
);
891 sig
->param_count
= nparams
;
893 sig
->ret
= mono_reflection_type_get_handle (m
->ret
, error
);
897 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
899 mtype
= mono_reflection_type_get_handle (m
->parent
, error
);
903 for (i
= 0; i
< nparams
; ++i
) {
904 sig
->params
[i
] = mono_type_array_get_and_resolve (m
->parameters
, i
, error
);
909 name
= mono_string_to_utf8_checked (m
->name
, error
);
912 for (tmp
= assembly
->array_methods
; tmp
; tmp
= tmp
->next
) {
913 am
= (ArrayMethod
*)tmp
->data
;
914 if (strcmp (name
, am
->name
) == 0 &&
915 mono_metadata_type_equal (am
->parent
, mtype
) &&
916 mono_metadata_signature_equal (am
->sig
, sig
)) {
919 m
->table_idx
= am
->token
& 0xffffff;
923 am
= g_new0 (ArrayMethod
, 1);
927 am
->token
= mono_image_get_memberref_token (assembly
, am
->parent
, name
,
928 mono_dynimage_encode_method_signature (assembly
, sig
));
929 assembly
->array_methods
= g_list_prepend (assembly
->array_methods
, am
);
930 m
->table_idx
= am
->token
& 0xffffff;
941 #ifndef DISABLE_REFLECTION_EMIT
944 * mono_image_insert_string:
945 * @module: module builder object
948 * Insert @str into the user string stream of @module.
951 mono_image_insert_string (MonoReflectionModuleBuilder
*module
, MonoString
*str
)
953 MonoDynamicImage
*assembly
;
958 if (!module
->dynamic_image
)
959 mono_image_module_basic_init (module
);
961 assembly
= module
->dynamic_image
;
963 if (assembly
->save
) {
964 mono_metadata_encode_value (1 | (str
->length
* 2), b
, &b
);
965 idx
= mono_image_add_stream_data (&assembly
->us
, buf
, b
-buf
);
966 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
968 char *swapped
= g_malloc (2 * mono_string_length (str
));
969 const char *p
= (const char*)mono_string_chars (str
);
971 swap_with_size (swapped
, p
, 2, mono_string_length (str
));
972 mono_image_add_stream_data (&assembly
->us
, swapped
, str
->length
* 2);
976 mono_image_add_stream_data (&assembly
->us
, (const char*)mono_string_chars (str
), str
->length
* 2);
978 mono_image_add_stream_data (&assembly
->us
, "", 1);
980 idx
= assembly
->us
.index
++;
983 mono_dynamic_image_register_token (assembly
, MONO_TOKEN_STRING
| idx
, (MonoObject
*)str
);
985 return MONO_TOKEN_STRING
| idx
;
989 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObject
*obj
, MonoArray
*opt_param_types
, MonoError
*error
)
993 MonoMethodSignature
*sig
;
995 mono_error_init (error
);
997 klass
= obj
->vtable
->klass
;
998 if (strcmp (klass
->name
, "MonoMethod") == 0 || strcmp (klass
->name
, "MonoCMethod") == 0) {
999 MonoMethod
*method
= ((MonoReflectionMethod
*)obj
)->method
;
1000 MonoMethodSignature
*old
;
1001 guint32 sig_token
, parent
;
1004 g_assert (opt_param_types
&& (mono_method_signature (method
)->sentinelpos
>= 0));
1006 nargs
= mono_array_length (opt_param_types
);
1007 old
= mono_method_signature (method
);
1008 sig
= mono_metadata_signature_alloc ( &assembly
->image
, old
->param_count
+ nargs
);
1010 sig
->hasthis
= old
->hasthis
;
1011 sig
->explicit_this
= old
->explicit_this
;
1012 sig
->call_convention
= old
->call_convention
;
1013 sig
->generic_param_count
= old
->generic_param_count
;
1014 sig
->param_count
= old
->param_count
+ nargs
;
1015 sig
->sentinelpos
= old
->param_count
;
1016 sig
->ret
= old
->ret
;
1018 for (i
= 0; i
< old
->param_count
; i
++)
1019 sig
->params
[i
] = old
->params
[i
];
1021 for (i
= 0; i
< nargs
; i
++) {
1022 MonoReflectionType
*rt
= mono_array_get (opt_param_types
, MonoReflectionType
*, i
);
1023 sig
->params
[old
->param_count
+ i
] = mono_reflection_type_get_handle (rt
, error
);
1024 if (!is_ok (error
)) goto fail
;
1027 parent
= mono_image_typedef_or_ref (assembly
, &method
->klass
->byval_arg
);
1028 g_assert ((parent
& MONO_TYPEDEFORREF_MASK
) == MONO_MEMBERREF_PARENT_TYPEREF
);
1029 parent
>>= MONO_TYPEDEFORREF_BITS
;
1031 parent
<<= MONO_MEMBERREF_PARENT_BITS
;
1032 parent
|= MONO_MEMBERREF_PARENT_TYPEREF
;
1034 sig_token
= mono_dynimage_encode_method_signature (assembly
, sig
);
1035 token
= mono_image_get_varargs_method_token (assembly
, parent
, method
->name
, sig_token
);
1036 } else if (strcmp (klass
->name
, "MethodBuilder") == 0) {
1037 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)obj
;
1038 ReflectionMethodBuilder rmb
;
1039 guint32 parent
, sig_token
;
1040 int nopt_args
, nparams
, ngparams
, i
;
1042 if (!mono_reflection_methodbuilder_from_method_builder (&rmb
, mb
, error
))
1045 rmb
.opt_types
= opt_param_types
;
1046 nopt_args
= mono_array_length (opt_param_types
);
1048 nparams
= rmb
.parameters
? mono_array_length (rmb
.parameters
): 0;
1049 ngparams
= rmb
.generic_params
? mono_array_length (rmb
.generic_params
): 0;
1050 sig
= mono_metadata_signature_alloc (&assembly
->image
, nparams
+ nopt_args
);
1052 sig
->hasthis
= !(rmb
.attrs
& METHOD_ATTRIBUTE_STATIC
);
1053 sig
->explicit_this
= (rmb
.call_conv
& 0x40) == 0x40;
1054 sig
->call_convention
= rmb
.call_conv
;
1055 sig
->generic_param_count
= ngparams
;
1056 sig
->param_count
= nparams
+ nopt_args
;
1057 sig
->sentinelpos
= nparams
;
1058 sig
->ret
= mono_reflection_type_get_handle (rmb
.rtype
, error
);
1059 if (!is_ok (error
)) goto fail
;
1061 for (i
= 0; i
< nparams
; i
++) {
1062 MonoReflectionType
*rt
= mono_array_get (rmb
.parameters
, MonoReflectionType
*, i
);
1063 sig
->params
[i
] = mono_reflection_type_get_handle (rt
, error
);
1064 if (!is_ok (error
)) goto fail
;
1067 for (i
= 0; i
< nopt_args
; i
++) {
1068 MonoReflectionType
*rt
= mono_array_get (opt_param_types
, MonoReflectionType
*, i
);
1069 sig
->params
[nparams
+ i
] = mono_reflection_type_get_handle (rt
, error
);
1070 if (!is_ok (error
)) goto fail
;
1073 // FIXME: This doesn't work, we don't use 'sig' for anything
1074 // The token fixup doesn't work either
1075 g_assert_not_reached ();
1077 sig_token
= mono_dynimage_encode_method_builder_signature (assembly
, &rmb
, error
);
1081 parent
= mono_image_create_token (assembly
, obj
, TRUE
, TRUE
, error
);
1082 if (!mono_error_ok (error
))
1084 g_assert (mono_metadata_token_table (parent
) == MONO_TABLE_METHOD
);
1086 parent
= mono_metadata_token_index (parent
) << MONO_MEMBERREF_PARENT_BITS
;
1087 parent
|= MONO_MEMBERREF_PARENT_METHODDEF
;
1089 char *name
= mono_string_to_utf8_checked (rmb
.name
, error
);
1090 if (!is_ok (error
)) goto fail
;
1091 token
= mono_image_get_varargs_method_token (
1092 assembly
, parent
, name
, sig_token
);
1095 g_error ("requested method token for %s\n", klass
->name
);
1098 g_hash_table_insert (assembly
->vararg_aux_hash
, GUINT_TO_POINTER (token
), sig
);
1099 mono_dynamic_image_register_token (assembly
, token
, obj
);
1102 g_assert (!mono_error_ok (error
));
1107 * mono_image_create_token:
1108 * @assembly: a dynamic assembly
1110 * @register_token: Whenever to register the token in the assembly->tokens hash.
1112 * Get a token to insert in the IL code stream for the given MemberInfo.
1113 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1114 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1118 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObject
*obj
,
1119 gboolean create_open_instance
, gboolean register_token
,
1125 mono_error_init (error
);
1127 klass
= obj
->vtable
->klass
;
1129 /* Check for user defined reflection objects */
1130 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1131 if (klass
->image
!= mono_defaults
.corlib
|| (strcmp (klass
->name
, "TypeDelegator") == 0)) {
1132 mono_error_set_not_supported (error
, "User defined subclasses of System.Type are not yet supported");
1136 if (strcmp (klass
->name
, "RuntimeType") == 0) {
1137 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
1138 return_val_if_nok (error
, 0);
1139 MonoClass
*mc
= mono_class_from_mono_type (type
);
1140 token
= mono_metadata_token_from_dor (
1141 mono_dynimage_encode_typedef_or_ref_full (assembly
, type
, !mono_class_is_gtd (mc
) || create_open_instance
));
1142 } else if (strcmp (klass
->name
, "MonoCMethod") == 0 ||
1143 strcmp (klass
->name
, "MonoMethod") == 0) {
1144 MonoReflectionMethod
*m
= (MonoReflectionMethod
*)obj
;
1145 if (m
->method
->is_inflated
) {
1146 if (create_open_instance
)
1147 token
= mono_image_get_methodspec_token (assembly
, m
->method
);
1149 token
= mono_image_get_inflated_method_token (assembly
, m
->method
);
1150 } else if ((m
->method
->klass
->image
== &assembly
->image
) &&
1151 !mono_class_is_ginst (m
->method
->klass
)) {
1152 static guint32 method_table_idx
= 0xffffff;
1153 if (m
->method
->klass
->wastypebuilder
) {
1154 /* we use the same token as the one that was assigned
1155 * to the Methodbuilder.
1156 * FIXME: do the equivalent for Fields.
1158 token
= m
->method
->token
;
1161 * Each token should have a unique index, but the indexes are
1162 * assigned by managed code, so we don't know about them. An
1163 * easy solution is to count backwards...
1165 method_table_idx
--;
1166 token
= MONO_TOKEN_METHOD_DEF
| method_table_idx
;
1169 token
= mono_image_get_methodref_token (assembly
, m
->method
, create_open_instance
);
1171 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1172 } else if (strcmp (klass
->name
, "MonoField") == 0) {
1173 MonoReflectionField
*f
= (MonoReflectionField
*)obj
;
1174 if ((f
->field
->parent
->image
== &assembly
->image
) && !is_field_on_inst (f
->field
)) {
1175 static guint32 field_table_idx
= 0xffffff;
1177 token
= MONO_TOKEN_FIELD_DEF
| field_table_idx
;
1179 token
= mono_image_get_fieldref_token (assembly
, (MonoObject
*)f
, f
->field
);
1181 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1182 } else if (strcmp (klass
->name
, "MonoArrayMethod") == 0) {
1183 MonoReflectionArrayMethod
*m
= (MonoReflectionArrayMethod
*)obj
;
1184 token
= mono_image_get_array_token (assembly
, m
, error
);
1185 return_val_if_nok (error
, 0);
1186 } else if (strcmp (klass
->name
, "SignatureHelper") == 0) {
1187 MonoReflectionSigHelper
*s
= (MonoReflectionSigHelper
*)obj
;
1188 token
= MONO_TOKEN_SIGNATURE
| mono_image_get_sighelper_token (assembly
, s
, error
);
1189 return_val_if_nok (error
, 0);
1190 } else if (strcmp (klass
->name
, "EnumBuilder") == 0) {
1191 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
1192 return_val_if_nok (error
, 0);
1193 token
= mono_metadata_token_from_dor (
1194 mono_image_typedef_or_ref (assembly
, type
));
1196 g_error ("requested token for %s\n", klass
->name
);
1200 mono_image_register_token (assembly
, token
, obj
);
1208 #ifndef DISABLE_REFLECTION_EMIT
1211 * mono_reflection_dynimage_basic_init:
1212 * @assembly: an assembly builder object
1214 * Create the MonoImage that represents the assembly builder and setup some
1215 * of the helper hash table and the basic metadata streams.
1218 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
1221 MonoDynamicAssembly
*assembly
;
1222 MonoDynamicImage
*image
;
1223 MonoDomain
*domain
= mono_object_domain (assemblyb
);
1225 if (assemblyb
->dynamic_assembly
)
1229 /* assembly->assembly.image might be GC allocated */
1230 assembly
= assemblyb
->dynamic_assembly
= (MonoDynamicAssembly
*)GC_MALLOC (sizeof (MonoDynamicAssembly
));
1232 assembly
= assemblyb
->dynamic_assembly
= g_new0 (MonoDynamicAssembly
, 1);
1235 mono_profiler_assembly_event (&assembly
->assembly
, MONO_PROFILE_START_LOAD
);
1237 assembly
->assembly
.ref_count
= 1;
1238 assembly
->assembly
.dynamic
= TRUE
;
1239 assembly
->assembly
.corlib_internal
= assemblyb
->corlib_internal
;
1240 assemblyb
->assembly
.assembly
= (MonoAssembly
*)assembly
;
1241 assembly
->assembly
.basedir
= mono_string_to_utf8_checked (assemblyb
->dir
, &error
);
1242 if (mono_error_set_pending_exception (&error
))
1244 if (assemblyb
->culture
) {
1245 assembly
->assembly
.aname
.culture
= mono_string_to_utf8_checked (assemblyb
->culture
, &error
);
1246 if (mono_error_set_pending_exception (&error
))
1249 assembly
->assembly
.aname
.culture
= g_strdup ("");
1251 if (assemblyb
->version
) {
1252 char *vstr
= mono_string_to_utf8_checked (assemblyb
->version
, &error
);
1253 if (mono_error_set_pending_exception (&error
))
1255 char **version
= g_strsplit (vstr
, ".", 4);
1256 char **parts
= version
;
1257 assembly
->assembly
.aname
.major
= atoi (*parts
++);
1258 assembly
->assembly
.aname
.minor
= atoi (*parts
++);
1259 assembly
->assembly
.aname
.build
= *parts
!= NULL
? atoi (*parts
++) : 0;
1260 assembly
->assembly
.aname
.revision
= *parts
!= NULL
? atoi (*parts
) : 0;
1262 g_strfreev (version
);
1265 assembly
->assembly
.aname
.major
= 0;
1266 assembly
->assembly
.aname
.minor
= 0;
1267 assembly
->assembly
.aname
.build
= 0;
1268 assembly
->assembly
.aname
.revision
= 0;
1271 assembly
->run
= assemblyb
->access
!= 2;
1272 assembly
->save
= assemblyb
->access
!= 1;
1273 assembly
->domain
= domain
;
1275 char *assembly_name
= mono_string_to_utf8_checked (assemblyb
->name
, &error
);
1276 if (mono_error_set_pending_exception (&error
))
1278 image
= mono_dynamic_image_create (assembly
, assembly_name
, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1279 image
->initial_image
= TRUE
;
1280 assembly
->assembly
.aname
.name
= image
->image
.name
;
1281 assembly
->assembly
.image
= &image
->image
;
1282 if (assemblyb
->pktoken
&& assemblyb
->pktoken
->max_length
) {
1283 /* -1 to correct for the trailing NULL byte */
1284 if (assemblyb
->pktoken
->max_length
!= MONO_PUBLIC_KEY_TOKEN_LENGTH
- 1) {
1285 g_error ("Public key token length invalid for assembly %s: %i", assembly
->assembly
.aname
.name
, assemblyb
->pktoken
->max_length
);
1287 memcpy (&assembly
->assembly
.aname
.public_key_token
, mono_array_addr (assemblyb
->pktoken
, guint8
, 0), assemblyb
->pktoken
->max_length
);
1290 mono_domain_assemblies_lock (domain
);
1291 domain
->domain_assemblies
= g_slist_append (domain
->domain_assemblies
, assembly
);
1292 mono_domain_assemblies_unlock (domain
);
1294 register_assembly (mono_object_domain (assemblyb
), &assemblyb
->assembly
, &assembly
->assembly
);
1296 mono_profiler_assembly_loaded (&assembly
->assembly
, MONO_PROFILE_OK
);
1298 mono_assembly_invoke_load_hook ((MonoAssembly
*)assembly
);
1301 #endif /* !DISABLE_REFLECTION_EMIT */
1303 #ifndef DISABLE_REFLECTION_EMIT
1305 register_assembly (MonoDomain
*domain
, MonoReflectionAssembly
*res
, MonoAssembly
*assembly
)
1307 CACHE_OBJECT (MonoReflectionAssembly
*, assembly
, res
, NULL
);
1311 register_module (MonoDomain
*domain
, MonoReflectionModuleBuilder
*res
, MonoDynamicImage
*module
)
1313 CACHE_OBJECT (MonoReflectionModuleBuilder
*, module
, res
, NULL
);
1317 image_module_basic_init (MonoReflectionModuleBuilder
*moduleb
, MonoError
*error
)
1319 MonoDynamicImage
*image
= moduleb
->dynamic_image
;
1320 MonoReflectionAssemblyBuilder
*ab
= moduleb
->assemblyb
;
1321 mono_error_init (error
);
1324 MonoImage
**new_modules
;
1326 char *name
, *fqname
;
1328 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1329 * we don't know which module it belongs to, since that is only
1330 * determined at assembly save time.
1332 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1333 name
= mono_string_to_utf8_checked (ab
->name
, error
);
1334 return_val_if_nok (error
, FALSE
);
1335 fqname
= mono_string_to_utf8_checked (moduleb
->module
.fqname
, error
);
1336 if (!is_ok (error
)) {
1340 image
= mono_dynamic_image_create (ab
->dynamic_assembly
, name
, fqname
);
1342 moduleb
->module
.image
= &image
->image
;
1343 moduleb
->dynamic_image
= image
;
1344 register_module (mono_object_domain (moduleb
), moduleb
, image
);
1346 /* register the module with the assembly */
1347 ass
= ab
->dynamic_assembly
->assembly
.image
;
1348 module_count
= ass
->module_count
;
1349 new_modules
= g_new0 (MonoImage
*, module_count
+ 1);
1352 memcpy (new_modules
, ass
->modules
, module_count
* sizeof (MonoImage
*));
1353 new_modules
[module_count
] = &image
->image
;
1354 mono_image_addref (&image
->image
);
1356 g_free (ass
->modules
);
1357 ass
->modules
= new_modules
;
1358 ass
->module_count
++;
1364 mono_image_module_basic_init (MonoReflectionModuleBuilder
*moduleb
)
1367 (void) image_module_basic_init (moduleb
, &error
);
1368 mono_error_set_pending_exception (&error
);
1374 is_corlib_type (MonoClass
*klass
)
1376 return klass
->image
== mono_defaults
.corlib
;
1379 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1380 static MonoClass *cached_class; \
1382 return cached_class == _class; \
1383 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1384 cached_class = _class; \
1392 #ifndef DISABLE_REFLECTION_EMIT
1394 is_sre_array (MonoClass
*klass
)
1396 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ArrayType");
1400 is_sre_byref (MonoClass
*klass
)
1402 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ByRefType");
1406 is_sre_pointer (MonoClass
*klass
)
1408 check_corlib_type_cached (klass
, "System.Reflection.Emit", "PointerType");
1412 is_sre_generic_instance (MonoClass
*klass
)
1414 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilderInstantiation");
1418 is_sre_type_builder (MonoClass
*klass
)
1420 check_corlib_type_cached (klass
, "System.Reflection.Emit", "TypeBuilder");
1424 is_sre_method_builder (MonoClass
*klass
)
1426 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodBuilder");
1430 mono_is_sre_ctor_builder (MonoClass
*klass
)
1432 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorBuilder");
1436 is_sre_field_builder (MonoClass
*klass
)
1438 check_corlib_type_cached (klass
, "System.Reflection.Emit", "FieldBuilder");
1442 is_sre_gparam_builder (MonoClass
*klass
)
1444 check_corlib_type_cached (klass
, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1448 is_sre_enum_builder (MonoClass
*klass
)
1450 check_corlib_type_cached (klass
, "System.Reflection.Emit", "EnumBuilder");
1454 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1456 check_corlib_type_cached (klass
, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1460 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1462 check_corlib_type_cached (klass
, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1465 static MonoReflectionType
*
1466 mono_reflection_type_get_underlying_system_type (MonoReflectionType
* t
, MonoError
*error
)
1468 static MonoMethod
*method_get_underlying_system_type
= NULL
;
1469 MonoReflectionType
*rt
;
1470 MonoMethod
*usertype_method
;
1472 mono_error_init (error
);
1474 if (!method_get_underlying_system_type
)
1475 method_get_underlying_system_type
= mono_class_get_method_from_name (mono_defaults
.systemtype_class
, "get_UnderlyingSystemType", 0);
1477 usertype_method
= mono_object_get_virtual_method ((MonoObject
*) t
, method_get_underlying_system_type
);
1479 rt
= (MonoReflectionType
*) mono_runtime_invoke_checked (usertype_method
, t
, NULL
, error
);
1485 mono_reflection_type_get_handle (MonoReflectionType
* ref
, MonoError
*error
)
1488 mono_error_init (error
);
1495 if (mono_reflection_is_usertype (ref
)) {
1496 ref
= mono_reflection_type_get_underlying_system_type (ref
, error
);
1497 if (ref
== NULL
|| mono_reflection_is_usertype (ref
) || !is_ok (error
))
1503 klass
= mono_object_class (ref
);
1505 if (is_sre_array (klass
)) {
1507 MonoReflectionArrayType
*sre_array
= (MonoReflectionArrayType
*)ref
;
1508 MonoType
*base
= mono_reflection_type_get_handle (sre_array
->element_type
, error
);
1509 return_val_if_nok (error
, NULL
);
1511 if (sre_array
->rank
== 0) //single dimentional array
1512 res
= &mono_array_class_get (mono_class_from_mono_type (base
), 1)->byval_arg
;
1514 res
= &mono_bounded_array_class_get (mono_class_from_mono_type (base
), sre_array
->rank
, TRUE
)->byval_arg
;
1515 sre_array
->type
.type
= res
;
1517 } else if (is_sre_byref (klass
)) {
1519 MonoReflectionDerivedType
*sre_byref
= (MonoReflectionDerivedType
*)ref
;
1520 MonoType
*base
= mono_reflection_type_get_handle (sre_byref
->element_type
, error
);
1521 return_val_if_nok (error
, NULL
);
1523 res
= &mono_class_from_mono_type (base
)->this_arg
;
1524 sre_byref
->type
.type
= res
;
1526 } else if (is_sre_pointer (klass
)) {
1528 MonoReflectionDerivedType
*sre_pointer
= (MonoReflectionDerivedType
*)ref
;
1529 MonoType
*base
= mono_reflection_type_get_handle (sre_pointer
->element_type
, error
);
1530 return_val_if_nok (error
, NULL
);
1532 res
= &mono_ptr_class_get (base
)->byval_arg
;
1533 sre_pointer
->type
.type
= res
;
1535 } else if (is_sre_generic_instance (klass
)) {
1536 MonoType
*res
, **types
;
1537 MonoReflectionGenericClass
*gclass
= (MonoReflectionGenericClass
*)ref
;
1540 count
= mono_array_length (gclass
->type_arguments
);
1541 types
= g_new0 (MonoType
*, count
);
1542 for (i
= 0; i
< count
; ++i
) {
1543 MonoReflectionType
*t
= (MonoReflectionType
*)mono_array_get (gclass
->type_arguments
, gpointer
, i
);
1544 types
[i
] = mono_reflection_type_get_handle (t
, error
);
1545 if (!types
[i
] || !is_ok (error
)) {
1551 res
= mono_reflection_bind_generic_parameters (gclass
->generic_type
, count
, types
, error
);
1554 gclass
->type
.type
= res
;
1556 } else if (is_sre_gparam_builder (klass
)) {
1557 MonoReflectionGenericParam
*gparam
= (MonoReflectionGenericParam
*)ref
;
1558 MonoGenericParamFull
*param
;
1562 image
= &gparam
->tbuilder
->module
->dynamic_image
->image
;
1564 param
= mono_image_new0 (image
, MonoGenericParamFull
, 1);
1566 param
->info
.name
= mono_string_to_utf8_image (image
, gparam
->name
, error
);
1567 mono_error_assert_ok (error
);
1568 param
->param
.num
= gparam
->index
;
1570 if (gparam
->mbuilder
) {
1571 if (!gparam
->mbuilder
->generic_container
) {
1572 gparam
->mbuilder
->generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (image
, sizeof (MonoGenericContainer
));
1573 gparam
->mbuilder
->generic_container
->is_method
= TRUE
;
1575 * Cannot set owner.method, since the MonoMethod is not created yet.
1576 * Set the image field instead, so type_in_image () works.
1578 gparam
->mbuilder
->generic_container
->is_anonymous
= TRUE
;
1579 gparam
->mbuilder
->generic_container
->owner
.image
= image
;
1581 param
->param
.owner
= gparam
->mbuilder
->generic_container
;
1582 } else if (gparam
->tbuilder
) {
1583 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)(gparam
->tbuilder
), error
);
1584 mono_error_assert_ok (error
);
1585 MonoClass
*owner
= mono_class_from_mono_type (type
);
1586 g_assert (mono_class_is_gtd (owner
));
1587 param
->param
.owner
= mono_class_get_generic_container (owner
);
1590 pklass
= mono_class_from_generic_parameter_internal ((MonoGenericParam
*) param
);
1592 gparam
->type
.type
= &pklass
->byval_arg
;
1594 mono_class_set_ref_info (pklass
, gparam
);
1595 mono_image_append_class_to_reflection_info_set (pklass
);
1597 return &pklass
->byval_arg
;
1598 } else if (is_sre_enum_builder (klass
)) {
1599 MonoReflectionEnumBuilder
*ebuilder
= (MonoReflectionEnumBuilder
*)ref
;
1601 return mono_reflection_type_get_handle ((MonoReflectionType
*)ebuilder
->tb
, error
);
1602 } else if (is_sre_type_builder (klass
)) {
1603 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)ref
;
1605 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1606 reflection_setup_internal_class (tb
, error
);
1607 mono_error_assert_ok (error
);
1608 g_assert (ref
->type
);
1612 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref
)->byval_arg
));
1617 * LOCKING: Assumes the loader lock is held.
1619 static MonoMethodSignature
*
1620 parameters_to_signature (MonoImage
*image
, MonoArray
*parameters
, MonoError
*error
) {
1621 MonoMethodSignature
*sig
;
1624 mono_error_init (error
);
1626 count
= parameters
? mono_array_length (parameters
): 0;
1628 sig
= (MonoMethodSignature
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_SIGNATURE
+ sizeof (MonoType
*) * count
);
1629 sig
->param_count
= count
;
1630 sig
->sentinelpos
= -1; /* FIXME */
1631 for (i
= 0; i
< count
; ++i
) {
1632 sig
->params
[i
] = mono_type_array_get_and_resolve (parameters
, i
, error
);
1633 if (!is_ok (error
)) {
1634 image_g_free (image
, sig
);
1642 * LOCKING: Assumes the loader lock is held.
1644 static MonoMethodSignature
*
1645 ctor_builder_to_signature (MonoImage
*image
, MonoReflectionCtorBuilder
*ctor
, MonoError
*error
) {
1646 MonoMethodSignature
*sig
;
1648 mono_error_init (error
);
1650 sig
= parameters_to_signature (image
, ctor
->parameters
, error
);
1651 return_val_if_nok (error
, NULL
);
1652 sig
->hasthis
= ctor
->attrs
& METHOD_ATTRIBUTE_STATIC
? 0: 1;
1653 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1658 * LOCKING: Assumes the loader lock is held.
1660 static MonoMethodSignature
*
1661 method_builder_to_signature (MonoImage
*image
, MonoReflectionMethodBuilder
*method
, MonoError
*error
) {
1662 MonoMethodSignature
*sig
;
1664 mono_error_init (error
);
1666 sig
= parameters_to_signature (image
, method
->parameters
, error
);
1667 return_val_if_nok (error
, NULL
);
1668 sig
->hasthis
= method
->attrs
& METHOD_ATTRIBUTE_STATIC
? 0: 1;
1669 if (method
->rtype
) {
1670 sig
->ret
= mono_reflection_type_get_handle ((MonoReflectionType
*)method
->rtype
, error
);
1671 if (!is_ok (error
)) {
1672 image_g_free (image
, sig
);
1676 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1678 sig
->generic_param_count
= method
->generic_params
? mono_array_length (method
->generic_params
) : 0;
1682 static MonoMethodSignature
*
1683 dynamic_method_to_signature (MonoReflectionDynamicMethod
*method
, MonoError
*error
) {
1684 MonoMethodSignature
*sig
;
1686 mono_error_init (error
);
1688 sig
= parameters_to_signature (NULL
, method
->parameters
, error
);
1689 return_val_if_nok (error
, NULL
);
1690 sig
->hasthis
= method
->attrs
& METHOD_ATTRIBUTE_STATIC
? 0: 1;
1691 if (method
->rtype
) {
1692 sig
->ret
= mono_reflection_type_get_handle (method
->rtype
, error
);
1693 if (!is_ok (error
)) {
1698 sig
->ret
= &mono_defaults
.void_class
->byval_arg
;
1700 sig
->generic_param_count
= 0;
1705 get_prop_name_and_type (MonoObject
*prop
, char **name
, MonoType
**type
, MonoError
*error
)
1707 mono_error_init (error
);
1708 MonoClass
*klass
= mono_object_class (prop
);
1709 if (strcmp (klass
->name
, "PropertyBuilder") == 0) {
1710 MonoReflectionPropertyBuilder
*pb
= (MonoReflectionPropertyBuilder
*)prop
;
1711 *name
= mono_string_to_utf8_checked (pb
->name
, error
);
1712 return_if_nok (error
);
1713 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)pb
->type
, error
);
1715 MonoReflectionProperty
*p
= (MonoReflectionProperty
*)prop
;
1716 *name
= g_strdup (p
->property
->name
);
1717 if (p
->property
->get
)
1718 *type
= mono_method_signature (p
->property
->get
)->ret
;
1720 *type
= mono_method_signature (p
->property
->set
)->params
[mono_method_signature (p
->property
->set
)->param_count
- 1];
1725 get_field_name_and_type (MonoObject
*field
, char **name
, MonoType
**type
, MonoError
*error
)
1727 mono_error_init (error
);
1728 MonoClass
*klass
= mono_object_class (field
);
1729 if (strcmp (klass
->name
, "FieldBuilder") == 0) {
1730 MonoReflectionFieldBuilder
*fb
= (MonoReflectionFieldBuilder
*)field
;
1731 *name
= mono_string_to_utf8_checked (fb
->name
, error
);
1732 return_if_nok (error
);
1733 *type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
1735 MonoReflectionField
*f
= (MonoReflectionField
*)field
;
1736 *name
= g_strdup (mono_field_get_name (f
->field
));
1737 *type
= f
->field
->type
;
1741 #else /* DISABLE_REFLECTION_EMIT */
1744 is_sre_type_builder (MonoClass
*klass
)
1750 is_sre_generic_instance (MonoClass
*klass
)
1756 mono_is_sre_ctor_builder (MonoClass
*klass
)
1762 mono_is_sre_method_on_tb_inst (MonoClass
*klass
)
1768 mono_is_sre_ctor_on_tb_inst (MonoClass
*klass
)
1773 #endif /* !DISABLE_REFLECTION_EMIT */
1777 is_sr_mono_field (MonoClass
*klass
)
1779 check_corlib_type_cached (klass
, "System.Reflection", "MonoField");
1783 mono_is_sr_mono_property (MonoClass
*klass
)
1785 check_corlib_type_cached (klass
, "System.Reflection", "MonoProperty");
1789 is_sr_mono_method (MonoClass
*klass
)
1791 check_corlib_type_cached (klass
, "System.Reflection", "MonoMethod");
1795 mono_is_sr_mono_cmethod (MonoClass
*klass
)
1797 check_corlib_type_cached (klass
, "System.Reflection", "MonoCMethod");
1801 mono_class_is_reflection_method_or_constructor (MonoClass
*klass
)
1803 return is_sr_mono_method (klass
) || mono_is_sr_mono_cmethod (klass
);
1807 mono_is_sre_type_builder (MonoClass
*klass
)
1809 return is_sre_type_builder (klass
);
1813 mono_is_sre_generic_instance (MonoClass
*klass
)
1815 return is_sre_generic_instance (klass
);
1821 * encode_cattr_value:
1822 * Encode a value in a custom attribute stream of bytes.
1823 * The value to encode is either supplied as an object in argument val
1824 * (valuetypes are boxed), or as a pointer to the data in the
1826 * @type represents the type of the value
1827 * @buffer is the start of the buffer
1828 * @p the current position in the buffer
1829 * @buflen contains the size of the buffer and is used to return the new buffer size
1830 * if this needs to be realloced.
1831 * @retbuffer and @retp return the start and the position of the buffer
1832 * @error set on error.
1835 encode_cattr_value (MonoAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, MonoObject
*arg
, char *argval
, MonoError
*error
)
1837 MonoTypeEnum simple_type
;
1839 mono_error_init (error
);
1840 if ((p
-buffer
) + 10 >= *buflen
) {
1843 newbuf
= (char *)g_realloc (buffer
, *buflen
);
1844 p
= newbuf
+ (p
-buffer
);
1848 argval
= ((char*)arg
+ sizeof (MonoObject
));
1849 simple_type
= type
->type
;
1851 switch (simple_type
) {
1852 case MONO_TYPE_BOOLEAN
:
1857 case MONO_TYPE_CHAR
:
1860 swap_with_size (p
, argval
, 2, 1);
1866 swap_with_size (p
, argval
, 4, 1);
1870 swap_with_size (p
, argval
, 8, 1);
1875 swap_with_size (p
, argval
, 8, 1);
1878 case MONO_TYPE_VALUETYPE
:
1879 if (type
->data
.klass
->enumtype
) {
1880 simple_type
= mono_class_enum_basetype (type
->data
.klass
)->type
;
1883 g_warning ("generic valutype %s not handled in custom attr value decoding", type
->data
.klass
->name
);
1886 case MONO_TYPE_STRING
: {
1893 str
= mono_string_to_utf8_checked ((MonoString
*)arg
, error
);
1894 return_if_nok (error
);
1895 slen
= strlen (str
);
1896 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
1900 newbuf
= (char *)g_realloc (buffer
, *buflen
);
1901 p
= newbuf
+ (p
-buffer
);
1904 mono_metadata_encode_value (slen
, p
, &p
);
1905 memcpy (p
, str
, slen
);
1910 case MONO_TYPE_CLASS
: {
1919 arg_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)arg
, error
);
1920 return_if_nok (error
);
1922 str
= type_get_qualified_name (arg_type
, NULL
);
1923 slen
= strlen (str
);
1924 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
1928 newbuf
= (char *)g_realloc (buffer
, *buflen
);
1929 p
= newbuf
+ (p
-buffer
);
1932 mono_metadata_encode_value (slen
, p
, &p
);
1933 memcpy (p
, str
, slen
);
1938 case MONO_TYPE_SZARRAY
: {
1940 MonoClass
*eclass
, *arg_eclass
;
1943 *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff; *p
++ = 0xff;
1946 len
= mono_array_length ((MonoArray
*)arg
);
1948 *p
++ = (len
>> 8) & 0xff;
1949 *p
++ = (len
>> 16) & 0xff;
1950 *p
++ = (len
>> 24) & 0xff;
1952 *retbuffer
= buffer
;
1953 eclass
= type
->data
.klass
;
1954 arg_eclass
= mono_object_class (arg
)->element_class
;
1957 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
1958 eclass
= mono_defaults
.object_class
;
1960 if (eclass
== mono_defaults
.object_class
&& arg_eclass
->valuetype
) {
1961 char *elptr
= mono_array_addr ((MonoArray
*)arg
, char, 0);
1962 int elsize
= mono_class_array_element_size (arg_eclass
);
1963 for (i
= 0; i
< len
; ++i
) {
1964 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &arg_eclass
->byval_arg
, NULL
, elptr
, error
);
1965 return_if_nok (error
);
1968 } else if (eclass
->valuetype
&& arg_eclass
->valuetype
) {
1969 char *elptr
= mono_array_addr ((MonoArray
*)arg
, char, 0);
1970 int elsize
= mono_class_array_element_size (eclass
);
1971 for (i
= 0; i
< len
; ++i
) {
1972 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &eclass
->byval_arg
, NULL
, elptr
, error
);
1973 return_if_nok (error
);
1977 for (i
= 0; i
< len
; ++i
) {
1978 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &eclass
->byval_arg
, mono_array_get ((MonoArray
*)arg
, MonoObject
*, i
), NULL
, error
);
1979 return_if_nok (error
);
1984 case MONO_TYPE_OBJECT
: {
1990 * The parameter type is 'object' but the type of the actual
1991 * argument is not. So we have to add type information to the blob
1992 * too. This is completely undocumented in the spec.
1996 *p
++ = MONO_TYPE_STRING
; // It's same hack as MS uses
2001 klass
= mono_object_class (arg
);
2003 if (mono_object_isinst_checked (arg
, mono_defaults
.systemtype_class
, error
)) {
2007 return_if_nok (error
);
2010 if (klass
->enumtype
) {
2012 } else if (klass
== mono_defaults
.string_class
) {
2013 simple_type
= MONO_TYPE_STRING
;
2016 } else if (klass
->rank
== 1) {
2018 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_OBJECT
)
2019 /* See Partition II, Appendix B3 */
2022 *p
++ = klass
->element_class
->byval_arg
.type
;
2023 encode_cattr_value (assembly
, buffer
, p
, &buffer
, &p
, buflen
, &klass
->byval_arg
, arg
, NULL
, error
);
2024 return_if_nok (error
);
2026 } else if (klass
->byval_arg
.type
>= MONO_TYPE_BOOLEAN
&& klass
->byval_arg
.type
<= MONO_TYPE_R8
) {
2027 *p
++ = simple_type
= klass
->byval_arg
.type
;
2030 g_error ("unhandled type in custom attr");
2032 str
= type_get_qualified_name (mono_class_get_type(klass
), NULL
);
2033 slen
= strlen (str
);
2034 if ((p
-buffer
) + 10 + slen
>= *buflen
) {
2038 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2039 p
= newbuf
+ (p
-buffer
);
2042 mono_metadata_encode_value (slen
, p
, &p
);
2043 memcpy (p
, str
, slen
);
2046 simple_type
= mono_class_enum_basetype (klass
)->type
;
2050 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type
);
2053 *retbuffer
= buffer
;
2057 encode_field_or_prop_type (MonoType
*type
, char *p
, char **retp
)
2059 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2060 char *str
= type_get_qualified_name (type
, NULL
);
2061 int slen
= strlen (str
);
2065 * This seems to be optional...
2068 mono_metadata_encode_value (slen
, p
, &p
);
2069 memcpy (p
, str
, slen
);
2072 } else if (type
->type
== MONO_TYPE_OBJECT
) {
2074 } else if (type
->type
== MONO_TYPE_CLASS
) {
2075 /* it should be a type: encode_cattr_value () has the check */
2078 mono_metadata_encode_value (type
->type
, p
, &p
);
2079 if (type
->type
== MONO_TYPE_SZARRAY
)
2080 /* See the examples in Partition VI, Annex B */
2081 encode_field_or_prop_type (&type
->data
.klass
->byval_arg
, p
, &p
);
2087 #ifndef DISABLE_REFLECTION_EMIT
2089 encode_named_val (MonoReflectionAssembly
*assembly
, char *buffer
, char *p
, char **retbuffer
, char **retp
, guint32
*buflen
, MonoType
*type
, char *name
, MonoObject
*value
, MonoError
*error
)
2093 mono_error_init (error
);
2095 /* Preallocate a large enough buffer */
2096 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
) {
2097 char *str
= type_get_qualified_name (type
, NULL
);
2100 } else if (type
->type
== MONO_TYPE_SZARRAY
&& type
->data
.klass
->enumtype
) {
2101 char *str
= type_get_qualified_name (&type
->data
.klass
->byval_arg
, NULL
);
2107 len
+= strlen (name
);
2109 if ((p
-buffer
) + 20 + len
>= *buflen
) {
2113 newbuf
= (char *)g_realloc (buffer
, *buflen
);
2114 p
= newbuf
+ (p
-buffer
);
2118 encode_field_or_prop_type (type
, p
, &p
);
2120 len
= strlen (name
);
2121 mono_metadata_encode_value (len
, p
, &p
);
2122 memcpy (p
, name
, len
);
2124 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, buflen
, type
, value
, NULL
, error
);
2125 return_if_nok (error
);
2127 *retbuffer
= buffer
;
2131 * mono_reflection_get_custom_attrs_blob:
2132 * @ctor: custom attribute constructor
2133 * @ctorArgs: arguments o the constructor
2139 * Creates the blob of data that needs to be saved in the metadata and that represents
2140 * the custom attributed described by @ctor, @ctorArgs etc.
2141 * Returns: a Byte array representing the blob of data.
2144 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
2147 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, &error
);
2148 mono_error_cleanup (&error
);
2153 * mono_reflection_get_custom_attrs_blob_checked:
2154 * @ctor: custom attribute constructor
2155 * @ctorArgs: arguments o the constructor
2160 * @error: set on error
2162 * Creates the blob of data that needs to be saved in the metadata and that represents
2163 * the custom attributed described by @ctor, @ctorArgs etc.
2164 * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
2167 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
, MonoError
*error
)
2169 MonoArray
*result
= NULL
;
2170 MonoMethodSignature
*sig
;
2175 mono_error_init (error
);
2177 if (strcmp (ctor
->vtable
->klass
->name
, "MonoCMethod")) {
2178 /* sig is freed later so allocate it in the heap */
2179 sig
= ctor_builder_to_signature (NULL
, (MonoReflectionCtorBuilder
*)ctor
, error
);
2180 if (!is_ok (error
)) {
2185 sig
= mono_method_signature (((MonoReflectionMethod
*)ctor
)->method
);
2188 g_assert (mono_array_length (ctorArgs
) == sig
->param_count
);
2190 p
= buffer
= (char *)g_malloc (buflen
);
2191 /* write the prolog */
2194 for (i
= 0; i
< sig
->param_count
; ++i
) {
2195 arg
= mono_array_get (ctorArgs
, MonoObject
*, i
);
2196 encode_cattr_value (assembly
->assembly
, buffer
, p
, &buffer
, &p
, &buflen
, sig
->params
[i
], arg
, NULL
, error
);
2197 if (!is_ok (error
)) goto leave
;
2201 i
+= mono_array_length (properties
);
2203 i
+= mono_array_length (fields
);
2205 *p
++ = (i
>> 8) & 0xff;
2208 for (i
= 0; i
< mono_array_length (properties
); ++i
) {
2212 prop
= (MonoObject
*)mono_array_get (properties
, gpointer
, i
);
2213 get_prop_name_and_type (prop
, &pname
, &ptype
, error
);
2214 if (!is_ok (error
)) goto leave
;
2215 *p
++ = 0x54; /* PROPERTY signature */
2216 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ptype
, pname
, (MonoObject
*)mono_array_get (propValues
, gpointer
, i
), error
);
2218 if (!is_ok (error
)) goto leave
;
2224 for (i
= 0; i
< mono_array_length (fields
); ++i
) {
2228 field
= (MonoObject
*)mono_array_get (fields
, gpointer
, i
);
2229 get_field_name_and_type (field
, &fname
, &ftype
, error
);
2230 if (!is_ok (error
)) goto leave
;
2231 *p
++ = 0x53; /* FIELD signature */
2232 encode_named_val (assembly
, buffer
, p
, &buffer
, &p
, &buflen
, ftype
, fname
, (MonoObject
*)mono_array_get (fieldValues
, gpointer
, i
), error
);
2234 if (!is_ok (error
)) goto leave
;
2238 g_assert (p
- buffer
<= buflen
);
2239 buflen
= p
- buffer
;
2240 result
= mono_array_new_checked (mono_domain_get (), mono_defaults
.byte_class
, buflen
, error
);
2243 p
= mono_array_addr (result
, char, 0);
2244 memcpy (p
, buffer
, buflen
);
2247 if (strcmp (ctor
->vtable
->klass
->name
, "MonoCMethod"))
2253 * reflection_setup_internal_class:
2254 * @tb: a TypeBuilder object
2255 * @error: set on error
2257 * Creates a MonoClass that represents the TypeBuilder.
2258 * This is a trick that lets us simplify a lot of reflection code
2259 * (and will allow us to support Build and Run assemblies easier).
2261 * Returns TRUE on success. On failure, returns FALSE and sets @error.
2264 reflection_setup_internal_class (MonoReflectionTypeBuilder
*tb
, MonoError
*error
)
2266 MonoClass
*klass
, *parent
;
2268 mono_error_init (error
);
2270 mono_loader_lock ();
2273 MonoType
*parent_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)tb
->parent
, error
);
2274 if (!is_ok (error
)) {
2275 mono_loader_unlock ();
2278 /* check so we can compile corlib correctly */
2279 if (strcmp (mono_object_class (tb
->parent
)->name
, "TypeBuilder") == 0) {
2280 /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
2281 parent
= parent_type
->data
.klass
;
2283 parent
= mono_class_from_mono_type (parent_type
);
2289 /* the type has already being created: it means we just have to change the parent */
2290 if (tb
->type
.type
) {
2291 klass
= mono_class_from_mono_type (tb
->type
.type
);
2292 klass
->parent
= NULL
;
2293 /* fool mono_class_setup_parent */
2294 klass
->supertypes
= NULL
;
2295 mono_class_setup_parent (klass
, parent
);
2296 mono_class_setup_mono_type (klass
);
2297 mono_loader_unlock ();
2302 * The size calculation here warrants some explaining.
2303 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2304 * meaning we need to alloc enough space to morth a def into a gtd.
2306 klass
= (MonoClass
*)mono_image_alloc0 (&tb
->module
->dynamic_image
->image
, MAX (sizeof (MonoClassDef
), sizeof (MonoClassGtd
)));
2307 klass
->class_kind
= MONO_CLASS_DEF
;
2309 klass
->image
= &tb
->module
->dynamic_image
->image
;
2311 klass
->inited
= 1; /* we lie to the runtime */
2312 klass
->name
= mono_string_to_utf8_image (klass
->image
, tb
->name
, error
);
2315 klass
->name_space
= mono_string_to_utf8_image (klass
->image
, tb
->nspace
, error
);
2318 klass
->type_token
= MONO_TOKEN_TYPE_DEF
| tb
->table_idx
;
2319 mono_class_set_flags (klass
, tb
->attrs
);
2321 mono_profiler_class_event (klass
, MONO_PROFILE_START_LOAD
);
2323 klass
->element_class
= klass
;
2325 if (mono_class_get_ref_info (klass
) == NULL
) {
2326 mono_class_set_ref_info (klass
, tb
);
2328 /* Put into cache so mono_class_get_checked () will find it.
2329 Skip nested types as those should not be available on the global scope. */
2330 if (!tb
->nesting_type
)
2331 mono_image_add_to_name_cache (klass
->image
, klass
->name_space
, klass
->name
, tb
->table_idx
);
2334 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2335 by performing a mono_class_get which does the full resolution.
2337 Working around this semantics would require us to write a lot of code for no clear advantage.
2339 mono_image_append_class_to_reflection_info_set (klass
);
2341 g_assert (mono_class_get_ref_info (klass
) == tb
);
2344 mono_dynamic_image_register_token (tb
->module
->dynamic_image
, MONO_TOKEN_TYPE_DEF
| tb
->table_idx
, (MonoObject
*)tb
);
2346 if (parent
!= NULL
) {
2347 mono_class_setup_parent (klass
, parent
);
2348 } else if (strcmp (klass
->name
, "Object") == 0 && strcmp (klass
->name_space
, "System") == 0) {
2349 const char *old_n
= klass
->name
;
2350 /* trick to get relative numbering right when compiling corlib */
2351 klass
->name
= "BuildingObject";
2352 mono_class_setup_parent (klass
, mono_defaults
.object_class
);
2353 klass
->name
= old_n
;
2356 if ((!strcmp (klass
->name
, "ValueType") && !strcmp (klass
->name_space
, "System")) ||
2357 (!strcmp (klass
->name
, "Object") && !strcmp (klass
->name_space
, "System")) ||
2358 (!strcmp (klass
->name
, "Enum") && !strcmp (klass
->name_space
, "System"))) {
2359 klass
->instance_size
= sizeof (MonoObject
);
2360 klass
->size_inited
= 1;
2361 mono_class_setup_vtable_general (klass
, NULL
, 0, NULL
);
2364 mono_class_setup_mono_type (klass
);
2366 mono_class_setup_supertypes (klass
);
2369 * FIXME: handle interfaces.
2372 tb
->type
.type
= &klass
->byval_arg
;
2374 if (tb
->nesting_type
) {
2375 reflection_setup_internal_class ((MonoReflectionTypeBuilder
*)tb
->nesting_type
, error
);
2376 g_assert (tb
->nesting_type
->type
);
2377 MonoType
*nesting_type
= mono_reflection_type_get_handle (tb
->nesting_type
, error
);
2378 if (!is_ok (error
)) goto failure
;
2379 klass
->nested_in
= mono_class_from_mono_type (nesting_type
);
2382 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2384 mono_profiler_class_loaded (klass
, MONO_PROFILE_OK
);
2386 mono_loader_unlock ();
2390 mono_loader_unlock ();
2395 * reflection_create_generic_class:
2396 * @tb: a TypeBuilder object
2397 * @error: set on error
2399 * Creates the generic class after all generic parameters have been added.
2400 * On success returns TRUE, on failure returns FALSE and sets @error.
2403 reflection_create_generic_class (MonoReflectionTypeBuilder
*tb
, MonoError
*error
)
2408 mono_error_init (error
);
2410 reflection_setup_internal_class (tb
, error
);
2412 klass
= mono_class_from_mono_type (tb
->type
.type
);
2414 count
= tb
->generic_params
? mono_array_length (tb
->generic_params
) : 0;
2419 MonoGenericContainer
*generic_container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2421 generic_container
->owner
.klass
= klass
;
2422 generic_container
->type_argc
= count
;
2423 generic_container
->type_params
= (MonoGenericParamFull
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericParamFull
) * count
);
2425 klass
->class_kind
= MONO_CLASS_GTD
;
2426 mono_class_set_generic_container (klass
, generic_container
);
2429 for (i
= 0; i
< count
; i
++) {
2430 MonoReflectionGenericParam
*gparam
= (MonoReflectionGenericParam
*)mono_array_get (tb
->generic_params
, gpointer
, i
);
2431 MonoType
*param_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gparam
, error
);
2432 return_val_if_nok (error
, FALSE
);
2433 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) param_type
->data
.generic_param
;
2434 generic_container
->type_params
[i
] = *param
;
2435 /*Make sure we are a diferent type instance */
2436 generic_container
->type_params
[i
].param
.owner
= generic_container
;
2437 generic_container
->type_params
[i
].info
.pklass
= NULL
;
2438 generic_container
->type_params
[i
].info
.flags
= gparam
->attrs
;
2440 g_assert (generic_container
->type_params
[i
].param
.owner
);
2443 generic_container
->context
.class_inst
= mono_get_shared_generic_inst (generic_container
);
2447 static MonoMarshalSpec
*
2448 mono_marshal_spec_from_builder (MonoImage
*image
, MonoAssembly
*assembly
,
2449 MonoReflectionMarshal
*minfo
, MonoError
*error
)
2451 MonoMarshalSpec
*res
;
2453 mono_error_init (error
);
2455 res
= image_g_new0 (image
, MonoMarshalSpec
, 1);
2456 res
->native
= (MonoMarshalNative
)minfo
->type
;
2458 switch (minfo
->type
) {
2459 case MONO_NATIVE_LPARRAY
:
2460 res
->data
.array_data
.elem_type
= (MonoMarshalNative
)minfo
->eltype
;
2461 if (minfo
->has_size
) {
2462 res
->data
.array_data
.param_num
= minfo
->param_num
;
2463 res
->data
.array_data
.num_elem
= minfo
->count
;
2464 res
->data
.array_data
.elem_mult
= minfo
->param_num
== -1 ? 0 : 1;
2467 res
->data
.array_data
.param_num
= -1;
2468 res
->data
.array_data
.num_elem
= -1;
2469 res
->data
.array_data
.elem_mult
= -1;
2473 case MONO_NATIVE_BYVALTSTR
:
2474 case MONO_NATIVE_BYVALARRAY
:
2475 res
->data
.array_data
.num_elem
= minfo
->count
;
2478 case MONO_NATIVE_CUSTOM
:
2479 if (minfo
->marshaltyperef
) {
2480 MonoType
*marshaltyperef
= mono_reflection_type_get_handle ((MonoReflectionType
*)minfo
->marshaltyperef
, error
);
2481 if (!is_ok (error
)) {
2482 image_g_free (image
, res
);
2485 res
->data
.custom_data
.custom_name
=
2486 type_get_fully_qualified_name (marshaltyperef
);
2488 if (minfo
->mcookie
) {
2489 res
->data
.custom_data
.cookie
= mono_string_to_utf8_checked (minfo
->mcookie
, error
);
2490 if (!is_ok (error
)) {
2491 image_g_free (image
, res
);
2503 #endif /* !DISABLE_REFLECTION_EMIT */
2505 MonoReflectionMarshalAsAttribute
*
2506 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain
*domain
, MonoClass
*klass
,
2507 MonoMarshalSpec
*spec
, MonoError
*error
)
2509 MonoReflectionType
*rt
;
2510 MonoReflectionMarshalAsAttribute
*minfo
;
2513 mono_error_init (error
);
2515 minfo
= (MonoReflectionMarshalAsAttribute
*)mono_object_new_checked (domain
, mono_class_get_marshal_as_attribute_class (), error
);
2518 minfo
->utype
= spec
->native
;
2520 switch (minfo
->utype
) {
2521 case MONO_NATIVE_LPARRAY
:
2522 minfo
->array_subtype
= spec
->data
.array_data
.elem_type
;
2523 minfo
->size_const
= spec
->data
.array_data
.num_elem
;
2524 if (spec
->data
.array_data
.param_num
!= -1)
2525 minfo
->size_param_index
= spec
->data
.array_data
.param_num
;
2528 case MONO_NATIVE_BYVALTSTR
:
2529 case MONO_NATIVE_BYVALARRAY
:
2530 minfo
->size_const
= spec
->data
.array_data
.num_elem
;
2533 case MONO_NATIVE_CUSTOM
:
2534 if (spec
->data
.custom_data
.custom_name
) {
2535 mtype
= mono_reflection_type_from_name_checked (spec
->data
.custom_data
.custom_name
, klass
->image
, error
);
2536 return_val_if_nok (error
, NULL
);
2539 rt
= mono_type_get_object_checked (domain
, mtype
, error
);
2543 MONO_OBJECT_SETREF (minfo
, marshal_type_ref
, rt
);
2546 MONO_OBJECT_SETREF (minfo
, marshal_type
, mono_string_new (domain
, spec
->data
.custom_data
.custom_name
));
2548 if (spec
->data
.custom_data
.cookie
)
2549 MONO_OBJECT_SETREF (minfo
, marshal_cookie
, mono_string_new (domain
, spec
->data
.custom_data
.cookie
));
2559 #ifndef DISABLE_REFLECTION_EMIT
2561 reflection_methodbuilder_to_mono_method (MonoClass
*klass
,
2562 ReflectionMethodBuilder
*rmb
,
2563 MonoMethodSignature
*sig
,
2567 MonoMethodWrapper
*wrapperm
;
2568 MonoMarshalSpec
**specs
;
2569 MonoReflectionMethodAux
*method_aux
;
2574 mono_error_init (error
);
2576 * Methods created using a MethodBuilder should have their memory allocated
2577 * inside the image mempool, while dynamic methods should have their memory
2580 dynamic
= rmb
->refs
!= NULL
;
2581 image
= dynamic
? NULL
: klass
->image
;
2584 g_assert (!mono_class_is_ginst (klass
));
2586 mono_loader_lock ();
2588 if ((rmb
->attrs
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) ||
2589 (rmb
->iattrs
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
))
2590 m
= (MonoMethod
*)image_g_new0 (image
, MonoMethodPInvoke
, 1);
2592 m
= (MonoMethod
*)image_g_new0 (image
, MonoMethodWrapper
, 1);
2594 wrapperm
= (MonoMethodWrapper
*)m
;
2596 m
->dynamic
= dynamic
;
2598 m
->flags
= rmb
->attrs
;
2599 m
->iflags
= rmb
->iattrs
;
2600 m
->name
= mono_string_to_utf8_image_ignore (image
, rmb
->name
);
2603 m
->sre_method
= TRUE
;
2604 m
->skip_visibility
= rmb
->skip_visibility
;
2606 m
->token
= MONO_TOKEN_METHOD_DEF
| (*rmb
->table_idx
);
2608 if (m
->iflags
& METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL
) {
2609 if (klass
== mono_defaults
.string_class
&& !strcmp (m
->name
, ".ctor"))
2612 m
->signature
->pinvoke
= 1;
2613 } else if (m
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
) {
2614 m
->signature
->pinvoke
= 1;
2616 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2618 method_aux
->dllentry
= rmb
->dllentry
? mono_string_to_utf8_image (image
, rmb
->dllentry
, error
) : image_strdup (image
, m
->name
);
2619 mono_error_assert_ok (error
);
2620 method_aux
->dll
= mono_string_to_utf8_image (image
, rmb
->dll
, error
);
2621 mono_error_assert_ok (error
);
2623 ((MonoMethodPInvoke
*)m
)->piflags
= (rmb
->native_cc
<< 8) | (rmb
->charset
? (rmb
->charset
- 1) * 2 : 0) | rmb
->extra_flags
;
2625 if (image_is_dynamic (klass
->image
))
2626 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
2628 mono_loader_unlock ();
2631 } else if (!(m
->flags
& METHOD_ATTRIBUTE_ABSTRACT
) &&
2632 !(m
->iflags
& METHOD_IMPL_ATTRIBUTE_RUNTIME
)) {
2633 MonoMethodHeader
*header
;
2635 gint32 max_stack
, i
;
2636 gint32 num_locals
= 0;
2637 gint32 num_clauses
= 0;
2641 code
= mono_array_addr (rmb
->ilgen
->code
, guint8
, 0);
2642 code_size
= rmb
->ilgen
->code_len
;
2643 max_stack
= rmb
->ilgen
->max_stack
;
2644 num_locals
= rmb
->ilgen
->locals
? mono_array_length (rmb
->ilgen
->locals
) : 0;
2645 if (rmb
->ilgen
->ex_handlers
)
2646 num_clauses
= mono_reflection_method_count_clauses (rmb
->ilgen
);
2649 code
= mono_array_addr (rmb
->code
, guint8
, 0);
2650 code_size
= mono_array_length (rmb
->code
);
2651 /* we probably need to run a verifier on the code... */
2661 header
= (MonoMethodHeader
*)mono_image_g_malloc0 (image
, MONO_SIZEOF_METHOD_HEADER
+ num_locals
* sizeof (MonoType
*));
2662 header
->code_size
= code_size
;
2663 header
->code
= (const unsigned char *)image_g_malloc (image
, code_size
);
2664 memcpy ((char*)header
->code
, code
, code_size
);
2665 header
->max_stack
= max_stack
;
2666 header
->init_locals
= rmb
->init_locals
;
2667 header
->num_locals
= num_locals
;
2669 for (i
= 0; i
< num_locals
; ++i
) {
2670 MonoReflectionLocalBuilder
*lb
=
2671 mono_array_get (rmb
->ilgen
->locals
, MonoReflectionLocalBuilder
*, i
);
2673 header
->locals
[i
] = image_g_new0 (image
, MonoType
, 1);
2674 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)lb
->type
, error
);
2675 mono_error_assert_ok (error
);
2676 memcpy (header
->locals
[i
], type
, MONO_SIZEOF_TYPE
);
2679 header
->num_clauses
= num_clauses
;
2681 header
->clauses
= method_encode_clauses (image
, (MonoDynamicImage
*)klass
->image
,
2682 rmb
->ilgen
, num_clauses
, error
);
2683 mono_error_assert_ok (error
);
2686 wrapperm
->header
= header
;
2689 if (rmb
->generic_params
) {
2690 int count
= mono_array_length (rmb
->generic_params
);
2691 MonoGenericContainer
*container
;
2693 container
= (MonoGenericContainer
*)mono_image_alloc0 (klass
->image
, sizeof (MonoGenericContainer
));
2694 container
->is_method
= TRUE
;
2695 container
->is_anonymous
= FALSE
;
2696 container
->type_argc
= count
;
2697 container
->type_params
= image_g_new0 (image
, MonoGenericParamFull
, count
);
2698 container
->owner
.method
= m
;
2700 m
->is_generic
= TRUE
;
2701 mono_method_set_generic_container (m
, container
);
2703 for (i
= 0; i
< count
; i
++) {
2704 MonoReflectionGenericParam
*gp
=
2705 mono_array_get (rmb
->generic_params
, MonoReflectionGenericParam
*, i
);
2706 MonoType
*gp_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gp
, error
);
2707 mono_error_assert_ok (error
);
2708 MonoGenericParamFull
*param
= (MonoGenericParamFull
*) gp_type
->data
.generic_param
;
2709 container
->type_params
[i
] = *param
;
2710 container
->type_params
[i
].param
.owner
= container
;
2712 gp
->type
.type
->data
.generic_param
= (MonoGenericParam
*)&container
->type_params
[i
];
2714 MonoClass
*gklass
= mono_class_from_mono_type (gp_type
);
2715 gklass
->wastypebuilder
= TRUE
;
2719 * The method signature might have pointers to generic parameters that belong to other methods.
2720 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2721 * generic parameters.
2723 for (i
= 0; i
< m
->signature
->param_count
; ++i
) {
2724 MonoType
*t
= m
->signature
->params
[i
];
2725 if (t
->type
== MONO_TYPE_MVAR
) {
2726 MonoGenericParam
*gparam
= t
->data
.generic_param
;
2727 if (gparam
->num
< count
) {
2728 m
->signature
->params
[i
] = mono_metadata_type_dup (image
, m
->signature
->params
[i
]);
2729 m
->signature
->params
[i
]->data
.generic_param
= mono_generic_container_get_param (container
, gparam
->num
);
2735 if (mono_class_is_gtd (klass
)) {
2736 container
->parent
= mono_class_get_generic_container (klass
);
2737 container
->context
.class_inst
= mono_class_get_generic_container (klass
)->context
.class_inst
;
2739 container
->context
.method_inst
= mono_get_shared_generic_inst (container
);
2743 MonoMethodWrapper
*mw
= (MonoMethodWrapper
*)m
;
2747 m
->wrapper_type
= MONO_WRAPPER_DYNAMIC_METHOD
;
2749 mw
->method_data
= data
= image_g_new (image
, gpointer
, rmb
->nrefs
+ 1);
2750 data
[0] = GUINT_TO_POINTER (rmb
->nrefs
);
2751 for (i
= 0; i
< rmb
->nrefs
; ++i
)
2752 data
[i
+ 1] = rmb
->refs
[i
];
2757 /* Parameter info */
2760 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2761 method_aux
->param_names
= image_g_new0 (image
, char *, mono_method_signature (m
)->param_count
+ 1);
2762 for (i
= 0; i
<= m
->signature
->param_count
; ++i
) {
2763 MonoReflectionParamBuilder
*pb
;
2764 if ((pb
= mono_array_get (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
2765 if ((i
> 0) && (pb
->attrs
)) {
2766 /* Make a copy since it might point to a shared type structure */
2767 m
->signature
->params
[i
- 1] = mono_metadata_type_dup (klass
->image
, m
->signature
->params
[i
- 1]);
2768 m
->signature
->params
[i
- 1]->attrs
= pb
->attrs
;
2771 if (pb
->attrs
& PARAM_ATTRIBUTE_HAS_DEFAULT
) {
2772 MonoDynamicImage
*assembly
;
2774 MonoTypeEnum def_type
;
2778 if (!method_aux
->param_defaults
) {
2779 method_aux
->param_defaults
= image_g_new0 (image
, guint8
*, m
->signature
->param_count
+ 1);
2780 method_aux
->param_default_types
= image_g_new0 (image
, guint32
, m
->signature
->param_count
+ 1);
2782 assembly
= (MonoDynamicImage
*)klass
->image
;
2783 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &def_type
);
2784 /* Copy the data from the blob since it might get realloc-ed */
2785 p
= assembly
->blob
.data
+ idx
;
2786 len
= mono_metadata_decode_blob_size (p
, &p2
);
2788 method_aux
->param_defaults
[i
] = (uint8_t *)image_g_malloc (image
, len
);
2789 method_aux
->param_default_types
[i
] = def_type
;
2790 memcpy ((gpointer
)method_aux
->param_defaults
[i
], p
, len
);
2794 method_aux
->param_names
[i
] = mono_string_to_utf8_image (image
, pb
->name
, error
);
2795 mono_error_assert_ok (error
);
2798 if (!method_aux
->param_cattr
)
2799 method_aux
->param_cattr
= image_g_new0 (image
, MonoCustomAttrInfo
*, m
->signature
->param_count
+ 1);
2800 method_aux
->param_cattr
[i
] = mono_custom_attrs_from_builders (image
, klass
->image
, pb
->cattrs
);
2806 /* Parameter marshalling */
2809 for (i
= 0; i
< mono_array_length (rmb
->pinfo
); ++i
) {
2810 MonoReflectionParamBuilder
*pb
;
2811 if ((pb
= mono_array_get (rmb
->pinfo
, MonoReflectionParamBuilder
*, i
))) {
2812 if (pb
->marshal_info
) {
2814 specs
= image_g_new0 (image
, MonoMarshalSpec
*, sig
->param_count
+ 1);
2815 specs
[pb
->position
] =
2816 mono_marshal_spec_from_builder (image
, klass
->image
->assembly
, pb
->marshal_info
, error
);
2817 if (!is_ok (error
)) {
2818 mono_loader_unlock ();
2819 image_g_free (image
, specs
);
2820 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
2826 if (specs
!= NULL
) {
2828 method_aux
= image_g_new0 (image
, MonoReflectionMethodAux
, 1);
2829 method_aux
->param_marshall
= specs
;
2832 if (image_is_dynamic (klass
->image
) && method_aux
)
2833 g_hash_table_insert (((MonoDynamicImage
*)klass
->image
)->method_aux_hash
, m
, method_aux
);
2835 mono_loader_unlock ();
2841 ctorbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionCtorBuilder
* mb
, MonoError
*error
)
2843 ReflectionMethodBuilder rmb
;
2844 MonoMethodSignature
*sig
;
2846 mono_loader_lock ();
2848 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb
, mb
, error
))
2851 g_assert (klass
->image
!= NULL
);
2852 sig
= ctor_builder_to_signature (klass
->image
, mb
, error
);
2853 mono_loader_unlock ();
2854 return_val_if_nok (error
, NULL
);
2856 mb
->mhandle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
2857 return_val_if_nok (error
, NULL
);
2858 mono_save_custom_attrs (klass
->image
, mb
->mhandle
, mb
->cattrs
);
2860 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
) {
2861 /* ilgen is no longer needed */
2869 methodbuilder_to_mono_method (MonoClass
*klass
, MonoReflectionMethodBuilder
* mb
, MonoError
*error
)
2871 ReflectionMethodBuilder rmb
;
2872 MonoMethodSignature
*sig
;
2874 mono_error_init (error
);
2876 mono_loader_lock ();
2878 if (!mono_reflection_methodbuilder_from_method_builder (&rmb
, mb
, error
))
2881 g_assert (klass
->image
!= NULL
);
2882 sig
= method_builder_to_signature (klass
->image
, mb
, error
);
2883 mono_loader_unlock ();
2884 return_val_if_nok (error
, NULL
);
2886 mb
->mhandle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
2887 return_val_if_nok (error
, NULL
);
2888 mono_save_custom_attrs (klass
->image
, mb
->mhandle
, mb
->cattrs
);
2890 if (!((MonoDynamicImage
*)(MonoDynamicImage
*)klass
->image
)->save
)
2891 /* ilgen is no longer needed */
2897 #ifndef DISABLE_REFLECTION_EMIT
2900 * fix_partial_generic_class:
2901 * @klass: a generic instantiation MonoClass
2902 * @error: set on error
2904 * Assumes that the generic container of @klass has its vtable
2905 * initialized, and updates the parent class, interfaces, methods and
2906 * fields of @klass by inflating the types using the generic context.
2908 * On success returns TRUE, on failure returns FALSE and sets @error.
2912 fix_partial_generic_class (MonoClass
*klass
, MonoError
*error
)
2914 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
2917 mono_error_init (error
);
2919 if (klass
->wastypebuilder
)
2922 if (klass
->parent
!= gklass
->parent
) {
2923 MonoType
*parent_type
= mono_class_inflate_generic_type_checked (&gklass
->parent
->byval_arg
, &mono_class_get_generic_class (klass
)->context
, error
);
2924 if (mono_error_ok (error
)) {
2925 MonoClass
*parent
= mono_class_from_mono_type (parent_type
);
2926 mono_metadata_free_type (parent_type
);
2927 if (parent
!= klass
->parent
) {
2928 /*fool mono_class_setup_parent*/
2929 klass
->supertypes
= NULL
;
2930 mono_class_setup_parent (klass
, parent
);
2933 if (gklass
->wastypebuilder
)
2934 klass
->wastypebuilder
= TRUE
;
2939 if (!mono_class_get_generic_class (klass
)->need_sync
)
2942 int mcount
= mono_class_get_method_count (klass
);
2943 int gmcount
= mono_class_get_method_count (gklass
);
2944 if (mcount
!= gmcount
) {
2945 mono_class_set_method_count (klass
, gmcount
);
2946 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * (gmcount
+ 1));
2948 for (i
= 0; i
< gmcount
; i
++) {
2949 klass
->methods
[i
] = mono_class_inflate_generic_method_full_checked (
2950 gklass
->methods
[i
], klass
, mono_class_get_context (klass
), error
);
2951 mono_error_assert_ok (error
);
2955 if (klass
->interface_count
&& klass
->interface_count
!= gklass
->interface_count
) {
2956 klass
->interface_count
= gklass
->interface_count
;
2957 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * gklass
->interface_count
);
2958 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
2960 for (i
= 0; i
< gklass
->interface_count
; ++i
) {
2961 MonoType
*iface_type
= mono_class_inflate_generic_type_checked (&gklass
->interfaces
[i
]->byval_arg
, mono_class_get_context (klass
), error
);
2962 return_val_if_nok (error
, FALSE
);
2964 klass
->interfaces
[i
] = mono_class_from_mono_type (iface_type
);
2965 mono_metadata_free_type (iface_type
);
2967 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
2970 klass
->interfaces_inited
= 1;
2973 int fcount
= mono_class_get_field_count (klass
);
2974 int gfcount
= mono_class_get_field_count (gklass
);
2975 if (fcount
!= gfcount
) {
2976 mono_class_set_field_count (klass
, gfcount
);
2977 klass
->fields
= image_g_new0 (klass
->image
, MonoClassField
, gfcount
);
2979 for (i
= 0; i
< gfcount
; i
++) {
2980 klass
->fields
[i
] = gklass
->fields
[i
];
2981 klass
->fields
[i
].parent
= klass
;
2982 klass
->fields
[i
].type
= mono_class_inflate_generic_type_checked (gklass
->fields
[i
].type
, mono_class_get_context (klass
), error
);
2983 return_val_if_nok (error
, FALSE
);
2987 /*We can only finish with this klass once it's parent has as well*/
2988 if (gklass
->wastypebuilder
)
2989 klass
->wastypebuilder
= TRUE
;
2994 * ensure_generic_class_runtime_vtable:
2995 * @klass a generic class
2996 * @error set on error
2998 * Ensures that the generic container of @klass has a vtable and
2999 * returns TRUE on success. On error returns FALSE and sets @error.
3002 ensure_generic_class_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3004 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
3006 mono_error_init (error
);
3008 if (!ensure_runtime_vtable (gklass
, error
))
3011 return fix_partial_generic_class (klass
, error
);
3015 * ensure_runtime_vtable:
3017 * @error set on error
3019 * Ensures that @klass has a vtable and returns TRUE on success. On
3020 * error returns FALSE and sets @error.
3023 ensure_runtime_vtable (MonoClass
*klass
, MonoError
*error
)
3025 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info (klass
);
3028 mono_error_init (error
);
3030 if (!image_is_dynamic (klass
->image
) || (!tb
&& !mono_class_is_ginst (klass
)) || klass
->wastypebuilder
)
3033 if (!ensure_runtime_vtable (klass
->parent
, error
))
3037 num
= tb
->ctors
? mono_array_length (tb
->ctors
): 0;
3038 num
+= tb
->num_methods
;
3039 mono_class_set_method_count (klass
, num
);
3040 klass
->methods
= (MonoMethod
**)mono_image_alloc (klass
->image
, sizeof (MonoMethod
*) * num
);
3041 num
= tb
->ctors
? mono_array_length (tb
->ctors
): 0;
3042 for (i
= 0; i
< num
; ++i
) {
3043 MonoMethod
*ctor
= ctorbuilder_to_mono_method (klass
, mono_array_get (tb
->ctors
, MonoReflectionCtorBuilder
*, i
), error
);
3046 klass
->methods
[i
] = ctor
;
3048 num
= tb
->num_methods
;
3050 for (i
= 0; i
< num
; ++i
) {
3051 MonoMethod
*meth
= methodbuilder_to_mono_method (klass
, mono_array_get (tb
->methods
, MonoReflectionMethodBuilder
*, i
), error
);
3054 klass
->methods
[j
++] = meth
;
3057 if (tb
->interfaces
) {
3058 klass
->interface_count
= mono_array_length (tb
->interfaces
);
3059 klass
->interfaces
= (MonoClass
**)mono_image_alloc (klass
->image
, sizeof (MonoClass
*) * klass
->interface_count
);
3060 for (i
= 0; i
< klass
->interface_count
; ++i
) {
3061 MonoType
*iface
= mono_type_array_get_and_resolve (tb
->interfaces
, i
, error
);
3062 return_val_if_nok (error
, FALSE
);
3063 klass
->interfaces
[i
] = mono_class_from_mono_type (iface
);
3064 if (!ensure_runtime_vtable (klass
->interfaces
[i
], error
))
3067 klass
->interfaces_inited
= 1;
3069 } else if (mono_class_is_ginst (klass
)){
3070 if (!ensure_generic_class_runtime_vtable (klass
, error
)) {
3071 mono_class_set_type_load_failure (klass
, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error
));
3076 if (mono_class_is_interface (klass
) && !mono_class_is_ginst (klass
)) {
3078 int mcount
= mono_class_get_method_count (klass
);
3079 for (i
= 0; i
< mcount
; ++i
) {
3080 MonoMethod
*im
= klass
->methods
[i
];
3081 if (!(im
->flags
& METHOD_ATTRIBUTE_STATIC
))
3082 im
->slot
= slot_num
++;
3085 klass
->interfaces_packed
= NULL
; /*make setup_interface_offsets happy*/
3086 mono_class_setup_interface_offsets (klass
);
3087 mono_class_setup_interface_id (klass
);
3091 * The generic vtable is needed even if image->run is not set since some
3092 * runtime code like ves_icall_Type_GetMethodsByName depends on
3093 * method->slot being defined.
3097 * tb->methods could not be freed since it is used for determining
3098 * overrides during dynamic vtable construction.
3105 mono_reflection_method_get_handle (MonoObject
*method
, MonoError
*error
)
3107 mono_error_init (error
);
3108 MonoClass
*klass
= mono_object_class (method
);
3109 if (is_sr_mono_method (klass
)) {
3110 MonoReflectionMethod
*sr_method
= (MonoReflectionMethod
*)method
;
3111 return sr_method
->method
;
3113 if (is_sre_method_builder (klass
)) {
3114 MonoReflectionMethodBuilder
*mb
= (MonoReflectionMethodBuilder
*)method
;
3117 if (mono_is_sre_method_on_tb_inst (klass
)) {
3118 MonoClass
*handle_class
;
3120 MonoMethod
*result
= mono_reflection_resolve_object (NULL
, method
, &handle_class
, NULL
, error
);
3121 return_val_if_nok (error
, NULL
);
3126 g_error ("Can't handle methods of type %s:%s", klass
->name_space
, klass
->name
);
3131 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
3133 MonoReflectionTypeBuilder
*tb
;
3135 MonoReflectionMethod
*m
;
3137 mono_error_init (error
);
3141 g_assert (image_is_dynamic (klass
->image
));
3143 if (!mono_class_get_ref_info (klass
))
3146 g_assert (strcmp (((MonoObject
*)mono_class_get_ref_info (klass
))->vtable
->klass
->name
, "TypeBuilder") == 0);
3148 tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info (klass
);
3152 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3153 MonoReflectionMethodBuilder
*mb
=
3154 mono_array_get (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3155 if (mb
->override_methods
)
3156 onum
+= mono_array_length (mb
->override_methods
);
3161 *overrides
= g_new0 (MonoMethod
*, onum
* 2);
3164 for (i
= 0; i
< tb
->num_methods
; ++i
) {
3165 MonoReflectionMethodBuilder
*mb
=
3166 mono_array_get (tb
->methods
, MonoReflectionMethodBuilder
*, i
);
3167 if (mb
->override_methods
) {
3168 for (j
= 0; j
< mono_array_length (mb
->override_methods
); ++j
) {
3169 m
= mono_array_get (mb
->override_methods
, MonoReflectionMethod
*, j
);
3171 (*overrides
) [onum
* 2] = mono_reflection_method_get_handle ((MonoObject
*)m
, error
);
3172 return_if_nok (error
);
3173 (*overrides
) [onum
* 2 + 1] = mb
->mhandle
;
3175 g_assert (mb
->mhandle
);
3183 *num_overrides
= onum
;
3186 /* This initializes the same data as mono_class_setup_fields () */
3188 typebuilder_setup_fields (MonoClass
*klass
, MonoError
*error
)
3190 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info (klass
);
3191 MonoReflectionFieldBuilder
*fb
;
3192 MonoClassField
*field
;
3194 MonoImage
*image
= klass
->image
;
3196 int i
, instance_size
, packing_size
= 0;
3199 if (klass
->parent
) {
3200 if (!klass
->parent
->size_inited
)
3201 mono_class_init (klass
->parent
);
3202 instance_size
= klass
->parent
->instance_size
;
3204 instance_size
= sizeof (MonoObject
);
3207 int fcount
= tb
->num_fields
;
3208 mono_class_set_field_count (klass
, fcount
);
3210 mono_error_init (error
);
3212 if (tb
->class_size
) {
3213 packing_size
= tb
->packing_size
;
3214 instance_size
+= tb
->class_size
;
3217 klass
->fields
= image_g_new0 (image
, MonoClassField
, fcount
);
3218 mono_class_alloc_ext (klass
);
3219 ext
= mono_class_get_ext (klass
);
3220 ext
->field_def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, fcount
);
3222 This is, guess what, a hack.
3223 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3224 On the static path no field class is resolved, only types are built. This is the right thing to do
3226 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3228 klass
->size_inited
= 1;
3230 for (i
= 0; i
< fcount
; ++i
) {
3231 MonoArray
*rva_data
;
3232 fb
= (MonoReflectionFieldBuilder
*)mono_array_get (tb
->fields
, gpointer
, i
);
3233 field
= &klass
->fields
[i
];
3234 field
->parent
= klass
;
3235 field
->name
= mono_string_to_utf8_image (image
, fb
->name
, error
);
3236 if (!mono_error_ok (error
))
3239 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3240 return_if_nok (error
);
3241 field
->type
= mono_metadata_type_dup (klass
->image
, type
);
3242 field
->type
->attrs
= fb
->attrs
;
3244 field
->type
= mono_reflection_type_get_handle ((MonoReflectionType
*)fb
->type
, error
);
3245 return_if_nok (error
);
3248 if ((fb
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
) && (rva_data
= fb
->rva_data
)) {
3249 char *base
= mono_array_addr (rva_data
, char, 0);
3250 size_t size
= mono_array_length (rva_data
);
3251 char *data
= (char *)mono_image_alloc (klass
->image
, size
);
3252 memcpy (data
, base
, size
);
3253 ext
->field_def_values
[i
].data
= data
;
3255 if (fb
->offset
!= -1)
3256 field
->offset
= fb
->offset
;
3258 mono_save_custom_attrs (klass
->image
, field
, fb
->cattrs
);
3260 if (fb
->def_value
) {
3261 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3262 field
->type
->attrs
|= FIELD_ATTRIBUTE_HAS_DEFAULT
;
3263 idx
= mono_dynimage_encode_constant (assembly
, fb
->def_value
, &ext
->field_def_values
[i
].def_type
);
3264 /* Copy the data from the blob since it might get realloc-ed */
3265 p
= assembly
->blob
.data
+ idx
;
3266 len
= mono_metadata_decode_blob_size (p
, &p2
);
3268 ext
->field_def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3269 memcpy ((gpointer
)ext
->field_def_values
[i
].data
, p
, len
);
3273 mono_class_layout_fields (klass
, instance_size
, packing_size
, TRUE
);
3277 typebuilder_setup_properties (MonoClass
*klass
, MonoError
*error
)
3279 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info (klass
);
3280 MonoReflectionPropertyBuilder
*pb
;
3281 MonoImage
*image
= klass
->image
;
3282 MonoProperty
*properties
;
3286 mono_error_init (error
);
3288 ext
= mono_class_get_ext (klass
);
3290 mono_class_set_ext (klass
, ext
= image_g_new0 (image
, MonoClassExt
, 1));
3292 ext
->property
.count
= tb
->properties
? mono_array_length (tb
->properties
) : 0;
3293 ext
->property
.first
= 0;
3295 properties
= image_g_new0 (image
, MonoProperty
, ext
->property
.count
);
3296 ext
->properties
= properties
;
3297 for (i
= 0; i
< ext
->property
.count
; ++i
) {
3298 pb
= mono_array_get (tb
->properties
, MonoReflectionPropertyBuilder
*, i
);
3299 properties
[i
].parent
= klass
;
3300 properties
[i
].attrs
= pb
->attrs
;
3301 properties
[i
].name
= mono_string_to_utf8_image (image
, pb
->name
, error
);
3302 if (!mono_error_ok (error
))
3305 properties
[i
].get
= pb
->get_method
->mhandle
;
3307 properties
[i
].set
= pb
->set_method
->mhandle
;
3309 mono_save_custom_attrs (klass
->image
, &properties
[i
], pb
->cattrs
);
3310 if (pb
->def_value
) {
3313 MonoDynamicImage
*assembly
= (MonoDynamicImage
*)klass
->image
;
3314 if (!ext
->prop_def_values
)
3315 ext
->prop_def_values
= image_g_new0 (image
, MonoFieldDefaultValue
, ext
->property
.count
);
3316 properties
[i
].attrs
|= PROPERTY_ATTRIBUTE_HAS_DEFAULT
;
3317 idx
= mono_dynimage_encode_constant (assembly
, pb
->def_value
, &ext
->prop_def_values
[i
].def_type
);
3318 /* Copy the data from the blob since it might get realloc-ed */
3319 p
= assembly
->blob
.data
+ idx
;
3320 len
= mono_metadata_decode_blob_size (p
, &p2
);
3322 ext
->prop_def_values
[i
].data
= (const char *)mono_image_alloc (image
, len
);
3323 memcpy ((gpointer
)ext
->prop_def_values
[i
].data
, p
, len
);
3329 typebuilder_setup_events (MonoClass
*klass
, MonoError
*error
)
3331 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info (klass
);
3332 MonoReflectionEventBuilder
*eb
;
3333 MonoImage
*image
= klass
->image
;
3338 mono_error_init (error
);
3340 ext
= mono_class_get_ext (klass
);
3342 mono_class_set_ext (klass
, ext
= image_g_new0 (image
, MonoClassExt
, 1));
3344 ext
->event
.count
= tb
->events
? mono_array_length (tb
->events
) : 0;
3345 ext
->event
.first
= 0;
3347 events
= image_g_new0 (image
, MonoEvent
, ext
->event
.count
);
3348 ext
->events
= events
;
3349 for (i
= 0; i
< ext
->event
.count
; ++i
) {
3350 eb
= mono_array_get (tb
->events
, MonoReflectionEventBuilder
*, i
);
3351 events
[i
].parent
= klass
;
3352 events
[i
].attrs
= eb
->attrs
;
3353 events
[i
].name
= mono_string_to_utf8_image (image
, eb
->name
, error
);
3354 if (!mono_error_ok (error
))
3357 events
[i
].add
= eb
->add_method
->mhandle
;
3358 if (eb
->remove_method
)
3359 events
[i
].remove
= eb
->remove_method
->mhandle
;
3360 if (eb
->raise_method
)
3361 events
[i
].raise
= eb
->raise_method
->mhandle
;
3363 #ifndef MONO_SMALL_CONFIG
3364 if (eb
->other_methods
) {
3366 events
[i
].other
= image_g_new0 (image
, MonoMethod
*, mono_array_length (eb
->other_methods
) + 1);
3367 for (j
= 0; j
< mono_array_length (eb
->other_methods
); ++j
) {
3368 MonoReflectionMethodBuilder
*mb
=
3369 mono_array_get (eb
->other_methods
,
3370 MonoReflectionMethodBuilder
*, j
);
3371 events
[i
].other
[j
] = mb
->mhandle
;
3375 mono_save_custom_attrs (klass
->image
, &events
[i
], eb
->cattrs
);
3379 struct remove_instantiations_user_data
3386 remove_instantiations_of_and_ensure_contents (gpointer key
,
3390 struct remove_instantiations_user_data
*data
= (struct remove_instantiations_user_data
*)user_data
;
3391 MonoType
*type
= (MonoType
*)key
;
3392 MonoClass
*klass
= data
->klass
;
3393 gboolean already_failed
= !is_ok (data
->error
);
3395 MonoError
*error
= already_failed
? &lerror
: data
->error
;
3397 if ((type
->type
== MONO_TYPE_GENERICINST
) && (type
->data
.generic_class
->container_class
== klass
)) {
3398 MonoClass
*inst_klass
= mono_class_from_mono_type (type
);
3399 //Ensure it's safe to use it.
3400 if (!fix_partial_generic_class (inst_klass
, error
)) {
3401 mono_class_set_type_load_failure (inst_klass
, "Could not initialized generic type instance due to: %s", mono_error_get_message (error
));
3402 // Marked the class with failure, but since some other instantiation already failed,
3403 // just report that one, and swallow the error from this one.
3405 mono_error_cleanup (error
);
3413 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder
*tb
)
3418 MonoReflectionType
* res
;
3421 mono_error_init (&error
);
3423 reflection_create_generic_class (tb
, &error
);
3424 mono_error_assert_ok (&error
);
3426 domain
= mono_object_domain (tb
);
3427 klass
= mono_class_from_mono_type (tb
->type
.type
);
3429 mono_save_custom_attrs (klass
->image
, klass
, tb
->cattrs
);
3432 * we need to lock the domain because the lock will be taken inside
3433 * So, we need to keep the locking order correct.
3435 mono_loader_lock ();
3436 mono_domain_lock (domain
);
3437 if (klass
->wastypebuilder
) {
3438 mono_domain_unlock (domain
);
3439 mono_loader_unlock ();
3441 res
= mono_type_get_object_checked (mono_object_domain (tb
), &klass
->byval_arg
, &error
);
3442 mono_error_set_pending_exception (&error
);
3447 * Fields to set in klass:
3448 * the various flags: delegate/unicode/contextbound etc.
3450 mono_class_set_flags (klass
, tb
->attrs
);
3451 klass
->has_cctor
= 1;
3453 mono_class_setup_parent (klass
, klass
->parent
);
3454 /* fool mono_class_setup_supertypes */
3455 klass
->supertypes
= NULL
;
3456 mono_class_setup_supertypes (klass
);
3457 mono_class_setup_mono_type (klass
);
3459 /* enums are done right away */
3460 if (!klass
->enumtype
)
3461 if (!ensure_runtime_vtable (klass
, &error
))
3465 for (i
= 0; i
< mono_array_length (tb
->subtypes
); ++i
) {
3466 MonoReflectionTypeBuilder
*subtb
= mono_array_get (tb
->subtypes
, MonoReflectionTypeBuilder
*, i
);
3467 mono_class_alloc_ext (klass
);
3469 if (!subtb
->type
.type
) {
3470 reflection_setup_internal_class (subtb
, &error
);
3471 mono_error_assert_ok (&error
);
3474 MonoType
*subtype
= mono_reflection_type_get_handle ((MonoReflectionType
*)subtb
, &error
);
3475 if (!is_ok (&error
)) goto failure
;
3476 mono_class_get_ext (klass
)->nested_classes
= g_list_prepend_image (klass
->image
, mono_class_get_ext (klass
)->nested_classes
, mono_class_from_mono_type (subtype
));
3480 klass
->nested_classes_inited
= TRUE
;
3482 typebuilder_setup_fields (klass
, &error
);
3483 if (!mono_error_ok (&error
))
3485 typebuilder_setup_properties (klass
, &error
);
3486 if (!mono_error_ok (&error
))
3489 typebuilder_setup_events (klass
, &error
);
3490 if (!mono_error_ok (&error
))
3493 klass
->wastypebuilder
= TRUE
;
3495 if (tb
->generic_params
) {
3496 for (i
= 0; i
< mono_array_length (tb
->generic_params
); i
++) {
3497 MonoReflectionGenericParam
*gparam
= (MonoReflectionGenericParam
*)mono_array_get (tb
->generic_params
, gpointer
, i
);
3498 MonoType
*param_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)gparam
, &error
);
3499 MonoClass
*gklass
= mono_class_from_mono_type (param_type
);
3501 gklass
->wastypebuilder
= TRUE
;
3506 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3507 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3508 * we want to return normal System.MonoType objects, so clear these out from the cache.
3510 * Together with this we must ensure the contents of all instances to match the created type.
3512 if (domain
->type_hash
&& mono_class_is_gtd (klass
)) {
3513 struct remove_instantiations_user_data data
;
3515 data
.error
= &error
;
3516 mono_error_assert_ok (&error
);
3517 mono_g_hash_table_foreach_remove (domain
->type_hash
, remove_instantiations_of_and_ensure_contents
, &data
);
3518 if (!is_ok (&error
))
3522 mono_domain_unlock (domain
);
3523 mono_loader_unlock ();
3525 if (klass
->enumtype
&& !mono_class_is_valid_enum (klass
)) {
3526 mono_class_set_type_load_failure (klass
, "Not a valid enumeration");
3527 mono_error_set_type_load_class (&error
, klass
, "Not a valid enumeration");
3528 goto failure_unlocked
;
3531 res
= mono_type_get_object_checked (mono_object_domain (tb
), &klass
->byval_arg
, &error
);
3532 if (!is_ok (&error
))
3533 goto failure_unlocked
;
3535 g_assert (res
!= (MonoReflectionType
*)tb
);
3540 mono_class_set_type_load_failure (klass
, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error
));
3541 klass
->wastypebuilder
= TRUE
;
3542 mono_domain_unlock (domain
);
3543 mono_loader_unlock ();
3545 mono_error_set_pending_exception (&error
);
3552 } DynamicMethodReleaseData
;
3555 * The runtime automatically clean up those after finalization.
3557 static MonoReferenceQueue
*dynamic_method_queue
;
3560 free_dynamic_method (void *dynamic_method
)
3562 DynamicMethodReleaseData
*data
= (DynamicMethodReleaseData
*)dynamic_method
;
3563 MonoDomain
*domain
= data
->domain
;
3564 MonoMethod
*method
= data
->handle
;
3567 mono_domain_lock (domain
);
3568 dis_link
= (guint32
)(size_t)g_hash_table_lookup (domain
->method_to_dyn_method
, method
);
3569 g_hash_table_remove (domain
->method_to_dyn_method
, method
);
3570 mono_domain_unlock (domain
);
3571 g_assert (dis_link
);
3572 mono_gchandle_free (dis_link
);
3574 mono_runtime_free_method (domain
, method
);
3579 reflection_create_dynamic_method (MonoReflectionDynamicMethod
*mb
, MonoError
*error
)
3581 MonoReferenceQueue
*queue
;
3583 DynamicMethodReleaseData
*release_data
;
3584 ReflectionMethodBuilder rmb
;
3585 MonoMethodSignature
*sig
;
3591 mono_error_init (error
);
3593 if (mono_runtime_is_shutting_down ()) {
3594 mono_error_set_generic_error (error
, "System", "InvalidOperationException", "");
3598 if (!(queue
= dynamic_method_queue
)) {
3599 mono_loader_lock ();
3600 if (!(queue
= dynamic_method_queue
))
3601 queue
= dynamic_method_queue
= mono_gc_reference_queue_new (free_dynamic_method
);
3602 mono_loader_unlock ();
3605 sig
= dynamic_method_to_signature (mb
, error
);
3606 return_val_if_nok (error
, FALSE
);
3608 reflection_methodbuilder_from_dynamic_method (&rmb
, mb
);
3611 * Resolve references.
3614 * Every second entry in the refs array is reserved for storing handle_class,
3615 * which is needed by the ldtoken implementation in the JIT.
3617 rmb
.nrefs
= mb
->nrefs
;
3618 rmb
.refs
= g_new0 (gpointer
, mb
->nrefs
+ 1);
3619 for (i
= 0; i
< mb
->nrefs
; i
+= 2) {
3620 MonoClass
*handle_class
;
3622 MonoObject
*obj
= mono_array_get (mb
->refs
, MonoObject
*, i
);
3624 if (strcmp (obj
->vtable
->klass
->name
, "DynamicMethod") == 0) {
3625 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
3627 * The referenced DynamicMethod should already be created by the managed
3628 * code, except in the case of circular references. In that case, we store
3629 * method in the refs array, and fix it up later when the referenced
3630 * DynamicMethod is created.
3632 if (method
->mhandle
) {
3633 ref
= method
->mhandle
;
3635 /* FIXME: GC object stored in unmanaged memory */
3638 /* FIXME: GC object stored in unmanaged memory */
3639 method
->referenced_by
= g_slist_append (method
->referenced_by
, mb
);
3641 handle_class
= mono_defaults
.methodhandle_class
;
3643 MonoException
*ex
= NULL
;
3644 ref
= mono_reflection_resolve_object (mb
->module
->image
, obj
, &handle_class
, NULL
, error
);
3645 if (!is_ok (error
)) {
3650 ex
= mono_get_exception_type_load (NULL
, NULL
);
3651 else if (mono_security_core_clr_enabled ())
3652 ex
= mono_security_core_clr_ensure_dynamic_method_resolved_object (ref
, handle_class
);
3656 mono_error_set_exception_instance (error
, ex
);
3661 rmb
.refs
[i
] = ref
; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3662 rmb
.refs
[i
+ 1] = handle_class
;
3666 MonoType
*owner_type
= mono_reflection_type_get_handle ((MonoReflectionType
*)mb
->owner
, error
);
3667 if (!is_ok (error
)) {
3671 klass
= mono_class_from_mono_type (owner_type
);
3673 klass
= mono_defaults
.object_class
;
3676 mb
->mhandle
= handle
= reflection_methodbuilder_to_mono_method (klass
, &rmb
, sig
, error
);
3678 return_val_if_nok (error
, FALSE
);
3680 release_data
= g_new (DynamicMethodReleaseData
, 1);
3681 release_data
->handle
= handle
;
3682 release_data
->domain
= mono_object_get_domain ((MonoObject
*)mb
);
3683 if (!mono_gc_reference_queue_add (queue
, (MonoObject
*)mb
, release_data
))
3684 g_free (release_data
);
3686 /* Fix up refs entries pointing at us */
3687 for (l
= mb
->referenced_by
; l
; l
= l
->next
) {
3688 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)l
->data
;
3689 MonoMethodWrapper
*wrapper
= (MonoMethodWrapper
*)method
->mhandle
;
3692 g_assert (method
->mhandle
);
3694 data
= (gpointer
*)wrapper
->method_data
;
3695 for (i
= 0; i
< GPOINTER_TO_UINT (data
[0]); i
+= 2) {
3696 if ((data
[i
+ 1] == mb
) && (data
[i
+ 1 + 1] == mono_defaults
.methodhandle_class
))
3697 data
[i
+ 1] = mb
->mhandle
;
3700 g_slist_free (mb
->referenced_by
);
3702 /* ilgen is no longer needed */
3705 domain
= mono_domain_get ();
3706 mono_domain_lock (domain
);
3707 if (!domain
->method_to_dyn_method
)
3708 domain
->method_to_dyn_method
= g_hash_table_new (NULL
, NULL
);
3709 g_hash_table_insert (domain
->method_to_dyn_method
, handle
, (gpointer
)(size_t)mono_gchandle_new_weakref ((MonoObject
*)mb
, TRUE
));
3710 mono_domain_unlock (domain
);
3716 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod
*mb
)
3719 (void) reflection_create_dynamic_method (mb
, &error
);
3720 mono_error_set_pending_exception (&error
);
3723 #endif /* DISABLE_REFLECTION_EMIT */
3725 MonoMethodSignature
*
3726 mono_reflection_lookup_signature (MonoImage
*image
, MonoMethod
*method
, guint32 token
, MonoError
*error
)
3728 MonoMethodSignature
*sig
;
3729 g_assert (image_is_dynamic (image
));
3731 mono_error_init (error
);
3733 sig
= (MonoMethodSignature
*)g_hash_table_lookup (((MonoDynamicImage
*)image
)->vararg_aux_hash
, GUINT_TO_POINTER (token
));
3737 return mono_method_signature_checked (method
, error
);
3740 #ifndef DISABLE_REFLECTION_EMIT
3743 * ensure_complete_type:
3745 * Ensure that KLASS is completed if it is a dynamic type, or references
3749 ensure_complete_type (MonoClass
*klass
, MonoError
*error
)
3751 mono_error_init (error
);
3753 if (image_is_dynamic (klass
->image
) && !klass
->wastypebuilder
&& mono_class_get_ref_info (klass
)) {
3754 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)mono_class_get_ref_info (klass
);
3756 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL
, (MonoObject
*)tb
, error
);
3757 return_if_nok (error
);
3759 // Asserting here could break a lot of code
3760 //g_assert (klass->wastypebuilder);
3763 if (mono_class_is_ginst (klass
)) {
3764 MonoGenericInst
*inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
3767 for (i
= 0; i
< inst
->type_argc
; ++i
) {
3768 ensure_complete_type (mono_class_from_mono_type (inst
->type_argv
[i
]), error
);
3769 return_if_nok (error
);
3775 mono_reflection_resolve_object (MonoImage
*image
, MonoObject
*obj
, MonoClass
**handle_class
, MonoGenericContext
*context
, MonoError
*error
)
3777 MonoClass
*oklass
= obj
->vtable
->klass
;
3778 gpointer result
= NULL
;
3780 mono_error_init (error
);
3782 if (strcmp (oklass
->name
, "String") == 0) {
3783 result
= mono_string_intern_checked ((MonoString
*)obj
, error
);
3784 return_val_if_nok (error
, NULL
);
3785 *handle_class
= mono_defaults
.string_class
;
3787 } else if (strcmp (oklass
->name
, "RuntimeType") == 0) {
3788 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)obj
, error
);
3789 return_val_if_nok (error
, NULL
);
3790 MonoClass
*mc
= mono_class_from_mono_type (type
);
3791 if (!mono_class_init (mc
)) {
3792 mono_error_set_for_class_failure (error
, mc
);
3797 MonoType
*inflated
= mono_class_inflate_generic_type_checked (type
, context
, error
);
3798 return_val_if_nok (error
, NULL
);
3800 result
= mono_class_from_mono_type (inflated
);
3801 mono_metadata_free_type (inflated
);
3803 result
= mono_class_from_mono_type (type
);
3805 *handle_class
= mono_defaults
.typehandle_class
;
3807 } else if (strcmp (oklass
->name
, "MonoMethod") == 0 ||
3808 strcmp (oklass
->name
, "MonoCMethod") == 0) {
3809 result
= ((MonoReflectionMethod
*)obj
)->method
;
3811 result
= mono_class_inflate_generic_method_checked ((MonoMethod
*)result
, context
, error
);
3812 mono_error_assert_ok (error
);
3814 *handle_class
= mono_defaults
.methodhandle_class
;
3816 } else if (strcmp (oklass
->name
, "MonoField") == 0) {
3817 MonoClassField
*field
= ((MonoReflectionField
*)obj
)->field
;
3819 ensure_complete_type (field
->parent
, error
);
3820 return_val_if_nok (error
, NULL
);
3823 MonoType
*inflated
= mono_class_inflate_generic_type_checked (&field
->parent
->byval_arg
, context
, error
);
3824 return_val_if_nok (error
, NULL
);
3826 MonoClass
*klass
= mono_class_from_mono_type (inflated
);
3827 MonoClassField
*inflated_field
;
3828 gpointer iter
= NULL
;
3829 mono_metadata_free_type (inflated
);
3830 while ((inflated_field
= mono_class_get_fields (klass
, &iter
))) {
3831 if (!strcmp (field
->name
, inflated_field
->name
))
3834 g_assert (inflated_field
&& !strcmp (field
->name
, inflated_field
->name
));
3835 result
= inflated_field
;
3839 *handle_class
= mono_defaults
.fieldhandle_class
;
3841 } else if (strcmp (oklass
->name
, "TypeBuilder") == 0) {
3842 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)obj
;
3843 MonoType
*type
= mono_reflection_type_get_handle ((MonoReflectionType
*)tb
, error
);
3844 return_val_if_nok (error
, NULL
);
3847 klass
= type
->data
.klass
;
3848 if (klass
->wastypebuilder
) {
3849 /* Already created */
3853 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL
, (MonoObject
*)tb
, error
);
3854 return_val_if_nok (error
, NULL
);
3855 result
= type
->data
.klass
;
3858 *handle_class
= mono_defaults
.typehandle_class
;
3859 } else if (strcmp (oklass
->name
, "SignatureHelper") == 0) {
3860 MonoReflectionSigHelper
*helper
= (MonoReflectionSigHelper
*)obj
;
3861 MonoMethodSignature
*sig
;
3864 if (helper
->arguments
)
3865 nargs
= mono_array_length (helper
->arguments
);
3869 sig
= mono_metadata_signature_alloc (image
, nargs
);
3870 sig
->explicit_this
= helper
->call_conv
& 64 ? 1 : 0;
3871 sig
->hasthis
= helper
->call_conv
& 32 ? 1 : 0;
3873 if (helper
->unmanaged_call_conv
) { /* unmanaged */
3874 sig
->call_convention
= helper
->unmanaged_call_conv
- 1;
3875 sig
->pinvoke
= TRUE
;
3876 } else if (helper
->call_conv
& 0x02) {
3877 sig
->call_convention
= MONO_CALL_VARARG
;
3879 sig
->call_convention
= MONO_CALL_DEFAULT
;
3882 sig
->param_count
= nargs
;
3883 /* TODO: Copy type ? */
3884 sig
->ret
= helper
->return_type
->type
;
3885 for (i
= 0; i
< nargs
; ++i
) {
3886 sig
->params
[i
] = mono_type_array_get_and_resolve (helper
->arguments
, i
, error
);
3887 if (!is_ok (error
)) {
3888 image_g_free (image
, sig
);
3894 *handle_class
= NULL
;
3895 } else if (strcmp (oklass
->name
, "DynamicMethod") == 0) {
3896 MonoReflectionDynamicMethod
*method
= (MonoReflectionDynamicMethod
*)obj
;
3897 /* Already created by the managed code */
3898 g_assert (method
->mhandle
);
3899 result
= method
->mhandle
;
3900 *handle_class
= mono_defaults
.methodhandle_class
;
3901 } else if (strcmp (oklass
->name
, "MonoArrayMethod") == 0) {
3902 MonoReflectionArrayMethod
*m
= (MonoReflectionArrayMethod
*)obj
;
3909 mtype
= mono_reflection_type_get_handle (m
->parent
, error
);
3910 return_val_if_nok (error
, NULL
);
3911 klass
= mono_class_from_mono_type (mtype
);
3913 /* Find the method */
3915 name
= mono_string_to_utf8_checked (m
->name
, error
);
3916 return_val_if_nok (error
, NULL
);
3918 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3919 if (!strcmp (method
->name
, name
))
3926 // FIXME: Check parameters/return value etc. match
3929 *handle_class
= mono_defaults
.methodhandle_class
;
3930 } else if (is_sre_method_builder (oklass
) ||
3931 mono_is_sre_ctor_builder (oklass
) ||
3932 is_sre_field_builder (oklass
) ||
3933 is_sre_gparam_builder (oklass
) ||
3934 is_sre_generic_instance (oklass
) ||
3935 is_sre_array (oklass
) ||
3936 is_sre_byref (oklass
) ||
3937 is_sre_pointer (oklass
) ||
3938 !strcmp (oklass
->name
, "FieldOnTypeBuilderInst") ||
3939 !strcmp (oklass
->name
, "MethodOnTypeBuilderInst") ||
3940 !strcmp (oklass
->name
, "ConstructorOnTypeBuilderInst")) {
3941 static MonoMethod
*resolve_method
;
3942 if (!resolve_method
) {
3943 MonoMethod
*m
= mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
3945 mono_memory_barrier ();
3950 obj
= mono_runtime_invoke_checked (resolve_method
, NULL
, args
, error
);
3951 mono_error_assert_ok (error
);
3953 return mono_reflection_resolve_object (image
, obj
, handle_class
, context
, error
);
3955 g_print ("%s\n", obj
->vtable
->klass
->name
);
3956 g_assert_not_reached ();
3961 #else /* DISABLE_REFLECTION_EMIT */
3964 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
3966 g_assert_not_reached ();
3971 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
3973 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
3977 mono_image_module_basic_init (MonoReflectionModuleBuilder
*moduleb
)
3979 g_assert_not_reached ();
3983 mono_image_insert_string (MonoReflectionModuleBuilder
*module
, MonoString
*str
)
3985 g_assert_not_reached ();
3990 mono_image_create_method_token (MonoDynamicImage
*assembly
, MonoObject
*obj
, MonoArray
*opt_param_types
, MonoError
*error
)
3992 g_assert_not_reached ();
3997 mono_image_create_token (MonoDynamicImage
*assembly
, MonoObject
*obj
,
3998 gboolean create_open_instance
, gboolean register_token
, MonoError
*error
)
4000 g_assert_not_reached ();
4005 mono_reflection_get_dynamic_overrides (MonoClass
*klass
, MonoMethod
***overrides
, int *num_overrides
, MonoError
*error
)
4007 mono_error_init (error
);
4013 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder
*tb
)
4015 g_assert_not_reached ();
4020 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod
*mb
)
4025 mono_reflection_type_get_handle (MonoReflectionType
* ref
, MonoError
*error
)
4027 mono_error_init (error
);
4033 #endif /* DISABLE_REFLECTION_EMIT */
4036 mono_sre_generic_param_table_entry_free (GenericParamTableEntry
*entry
)
4038 mono_gc_deregister_root ((char*) &entry
->gparam
);
4043 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
, gboolean create_open_instance
)
4045 MONO_CHECK_ARG_NULL (obj
, 0);
4048 gint32 result
= mono_image_create_token (mb
->dynamic_image
, obj
, create_open_instance
, TRUE
, &error
);
4049 mono_error_set_pending_exception (&error
);
4054 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder
*mb
,
4055 MonoReflectionMethod
*method
,
4056 MonoArray
*opt_param_types
)
4058 MONO_CHECK_ARG_NULL (method
, 0);
4061 gint32 result
= mono_image_create_method_token (
4062 mb
->dynamic_image
, (MonoObject
*) method
, opt_param_types
, &error
);
4063 mono_error_set_pending_exception (&error
);
4068 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
4071 mono_image_create_pefile (mb
, file
, &error
);
4072 mono_error_set_pending_exception (&error
);
4076 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
4079 mono_image_build_metadata (mb
, &error
);
4080 mono_error_set_pending_exception (&error
);
4084 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
, guint32 token
)
4086 mono_image_register_token (mb
->dynamic_image
, token
, obj
);
4090 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder
*mb
, guint32 token
)
4094 mono_loader_lock ();
4095 obj
= (MonoObject
*)mono_g_hash_table_lookup (mb
->dynamic_image
->tokens
, GUINT_TO_POINTER (token
));
4096 mono_loader_unlock ();
4101 #ifndef DISABLE_REFLECTION_EMIT
4103 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly
*assembly
, MonoObject
*ctor
, MonoArray
*ctorArgs
, MonoArray
*properties
, MonoArray
*propValues
, MonoArray
*fields
, MonoArray
* fieldValues
)
4106 MonoArray
*result
= mono_reflection_get_custom_attrs_blob_checked (assembly
, ctor
, ctorArgs
, properties
, propValues
, fields
, fieldValues
, &error
);
4107 mono_error_set_pending_exception (&error
);
4113 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder
*assemblyb
)
4115 mono_reflection_dynimage_basic_init (assemblyb
);
4119 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType
*enumtype
,
4120 MonoReflectionType
*t
)
4122 enumtype
->type
= t
->type
;
4126 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilder
*moduleb
)
4128 mono_image_module_basic_init (moduleb
);
4132 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilder
*module
, MonoString
*str
)
4134 return mono_image_insert_string (module
, str
);
4138 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder
*moduleb
, MonoReflectionType
*type
)
4140 MonoDynamicImage
*image
= moduleb
->dynamic_image
;
4142 g_assert (type
->type
);
4143 image
->wrappers_type
= mono_class_from_mono_type (type
->type
);