1 /**
2 * \file
3 * Routines for creating an image at runtime
4 * and related System.Reflection.Emit icalls
5 *
6 *
7 * Author:
8 * Paolo Molaro (lupus@ximian.com)
9 *
10 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
12 * Copyright 2011 Rodrigo Kumpera
13 * Copyright 2016 Microsoft
14 *
15 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
16 */
17 #include <config.h>
18 #include <glib.h>
19 #include "mono/metadata/assembly.h"
20 #include "mono/metadata/debug-helpers.h"
21 #include "mono/metadata/dynamic-image-internals.h"
22 #include "mono/metadata/dynamic-stream-internals.h"
23 #include "mono/metadata/exception.h"
24 #include "mono/metadata/gc-internals.h"
25 #include "mono/metadata/mono-ptr-array.h"
26 #include "mono/metadata/object-internals.h"
27 #include "mono/metadata/profiler-private.h"
28 #include "mono/metadata/reflection-internals.h"
29 #include "mono/metadata/reflection-cache.h"
30 #include "mono/metadata/sre-internals.h"
31 #include "mono/metadata/custom-attrs-internals.h"
32 #include "mono/metadata/security-manager.h"
33 #include "mono/metadata/security-core-clr.h"
34 #include "mono/metadata/tabledefs.h"
35 #include "mono/metadata/tokentype.h"
36 #include "mono/utils/checked-build.h"
37 #include "mono/utils/mono-digest.h"
38 #include "mono/utils/w32api.h"
39
40 static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, "System.Runtime.InteropServices", "MarshalAsAttribute");
41 static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", "ModuleBuilder");
42
43 static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
44
45 #ifndef DISABLE_REFLECTION_EMIT
46 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
47 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
48 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
49 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
50 static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
51 static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
52
53
54 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
55 #endif
56
57 static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
58 static MonoReflectionTypeHandle mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error);
59 static gboolean is_sre_array (MonoClass *klass);
60 static gboolean is_sre_byref (MonoClass *klass);
61 static gboolean is_sre_pointer (MonoClass *klass);
62 static gboolean is_sre_generic_instance (MonoClass *klass);
63 static gboolean is_sre_type_builder (MonoClass *klass);
64 static gboolean is_sre_method_builder (MonoClass *klass);
65 static gboolean is_sre_field_builder (MonoClass *klass);
66 static gboolean is_sre_gparam_builder (MonoClass *klass);
67 static gboolean is_sre_enum_builder (MonoClass *klass);
68 static gboolean is_sr_mono_method (MonoClass *klass);
69 static gboolean is_sr_mono_field (MonoClass *klass);
70
71 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
72 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
73 static guint32 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error);
74
75
76 #ifndef DISABLE_REFLECTION_EMIT
77 static MonoType* mono_type_array_get_and_resolve_raw (MonoArray* array, int idx, MonoError* error);
78 #endif
79
80 static gboolean mono_image_module_basic_init (MonoReflectionModuleBuilderHandle module, MonoError *error);
81
82 void
mono_reflection_emit_init(void)83 mono_reflection_emit_init (void)
84 {
85 mono_dynamic_images_init ();
86 }
87
88 char*
string_to_utf8_image_raw(MonoImage * image,MonoString * s_raw,MonoError * error)89 string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
90 {
91 /* FIXME all callers to string_to_utf8_image_raw should use handles */
92 HANDLE_FUNCTION_ENTER ();
93 char* result = NULL;
94 error_init (error);
95 MONO_HANDLE_DCL (MonoString, s);
96 result = mono_string_to_utf8_image (image, s, error);
97 HANDLE_FUNCTION_RETURN_VAL (result);
98 }
99
100 static char*
type_get_fully_qualified_name(MonoType * type)101 type_get_fully_qualified_name (MonoType *type)
102 {
103 MONO_REQ_GC_NEUTRAL_MODE;
104
105 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
106 }
107
108 static char*
type_get_qualified_name(MonoType * type,MonoAssembly * ass)109 type_get_qualified_name (MonoType *type, MonoAssembly *ass)
110 {
111 MONO_REQ_GC_UNSAFE_MODE;
112
113 MonoClass *klass;
114 MonoAssembly *ta;
115
116 klass = mono_class_from_mono_type (type);
117 if (!klass)
118 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
119 ta = klass->image->assembly;
120 if (assembly_is_dynamic (ta) || (ta == ass)) {
121 if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
122 /* For generic type definitions, we want T, while REFLECTION returns T<K> */
123 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
124 else
125 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
126 }
127
128 return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
129 }
130
131 #ifndef DISABLE_REFLECTION_EMIT
132 /**
133 * mp_g_alloc:
134 *
135 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
136 * from the C heap.
137 */
138 static gpointer
image_g_malloc(MonoImage * image,guint size)139 image_g_malloc (MonoImage *image, guint size)
140 {
141 MONO_REQ_GC_NEUTRAL_MODE;
142
143 if (image)
144 return mono_image_alloc (image, size);
145 else
146 return g_malloc (size);
147 }
148 #endif /* !DISABLE_REFLECTION_EMIT */
149
150 /**
151 * image_g_alloc0:
152 *
153 * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
154 * from the C heap.
155 */
156 gpointer
mono_image_g_malloc0(MonoImage * image,guint size)157 mono_image_g_malloc0 (MonoImage *image, guint size)
158 {
159 MONO_REQ_GC_NEUTRAL_MODE;
160
161 if (image)
162 return mono_image_alloc0 (image, size);
163 else
164 return g_malloc0 (size);
165 }
166
167 /**
168 * image_g_free:
169 * @image: a MonoImage
170 * @ptr: pointer
171 *
172 * If @image is NULL, free @ptr, otherwise do nothing.
173 */
174 static void
image_g_free(MonoImage * image,gpointer ptr)175 image_g_free (MonoImage *image, gpointer ptr)
176 {
177 if (image == NULL)
178 g_free (ptr);
179 }
180
181 #ifndef DISABLE_REFLECTION_EMIT
182 static char*
image_strdup(MonoImage * image,const char * s)183 image_strdup (MonoImage *image, const char *s)
184 {
185 MONO_REQ_GC_NEUTRAL_MODE;
186
187 if (image)
188 return mono_image_strdup (image, s);
189 else
190 return g_strdup (s);
191 }
192 #endif
193
194 #define image_g_new(image,struct_type, n_structs) \
195 ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
196
197 #define image_g_new0(image,struct_type, n_structs) \
198 ((struct_type *) mono_image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
199
200
201 static void
alloc_table(MonoDynamicTable * table,guint nrows)202 alloc_table (MonoDynamicTable *table, guint nrows)
203 {
204 mono_dynimage_alloc_table (table, nrows);
205 }
206
207 static guint32
string_heap_insert(MonoDynamicStream * sh,const char * str)208 string_heap_insert (MonoDynamicStream *sh, const char *str)
209 {
210 return mono_dynstream_insert_string (sh, str);
211 }
212
213 static guint32
mono_image_add_stream_data(MonoDynamicStream * stream,const char * data,guint32 len)214 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
215 {
216 return mono_dynstream_add_data (stream, data, len);
217 }
218
219 /*
220 * Despite the name, we handle also TypeSpec (with the above helper).
221 */
222 static guint32
mono_image_typedef_or_ref(MonoDynamicImage * assembly,MonoType * type)223 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
224 {
225 return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
226 }
227
228 /*
229 * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
230 * dest may be misaligned.
231 */
232 static void
swap_with_size(char * dest,const char * val,int len,int nelem)233 swap_with_size (char *dest, const char* val, int len, int nelem) {
234 MONO_REQ_GC_NEUTRAL_MODE;
235 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
236 int elem;
237
238 for (elem = 0; elem < nelem; ++elem) {
239 switch (len) {
240 case 1:
241 *dest = *val;
242 break;
243 case 2:
244 dest [0] = val [1];
245 dest [1] = val [0];
246 break;
247 case 4:
248 dest [0] = val [3];
249 dest [1] = val [2];
250 dest [2] = val [1];
251 dest [3] = val [0];
252 break;
253 case 8:
254 dest [0] = val [7];
255 dest [1] = val [6];
256 dest [2] = val [5];
257 dest [3] = val [4];
258 dest [4] = val [3];
259 dest [5] = val [2];
260 dest [6] = val [1];
261 dest [7] = val [0];
262 break;
263 default:
264 g_assert_not_reached ();
265 }
266 dest += len;
267 val += len;
268 }
269 #else
270 memcpy (dest, val, len * nelem);
271 #endif
272 }
273
274 guint32
mono_reflection_method_count_clauses(MonoReflectionILGen * ilgen)275 mono_reflection_method_count_clauses (MonoReflectionILGen *ilgen)
276 {
277 MONO_REQ_GC_UNSAFE_MODE;
278
279 guint32 num_clauses = 0;
280 int i;
281
282 MonoILExceptionInfo *ex_info;
283 for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
284 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
285 if (ex_info->handlers)
286 num_clauses += mono_array_length (ex_info->handlers);
287 else
288 num_clauses++;
289 }
290
291 return num_clauses;
292 }
293
294 #ifndef DISABLE_REFLECTION_EMIT
295 static MonoExceptionClause*
method_encode_clauses(MonoImage * image,MonoDynamicImage * assembly,MonoReflectionILGen * ilgen,guint32 num_clauses,MonoError * error)296 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses, MonoError *error)
297 {
298 MONO_REQ_GC_UNSAFE_MODE;
299
300 error_init (error);
301
302 MonoExceptionClause *clauses;
303 MonoExceptionClause *clause;
304 MonoILExceptionInfo *ex_info;
305 MonoILExceptionBlock *ex_block;
306 guint32 finally_start;
307 int i, j, clause_index;;
308
309 clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
310
311 clause_index = 0;
312 for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
313 ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
314 finally_start = ex_info->start + ex_info->len;
315 if (!ex_info->handlers)
316 continue;
317 for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
318 ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
319 clause = &(clauses [clause_index]);
320
321 clause->flags = ex_block->type;
322 clause->try_offset = ex_info->start;
323
324 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FINALLY)
325 clause->try_len = finally_start - ex_info->start;
326 else
327 clause->try_len = ex_info->len;
328 clause->handler_offset = ex_block->start;
329 clause->handler_len = ex_block->len;
330 if (ex_block->extype) {
331 MonoType *extype = mono_reflection_type_get_handle ((MonoReflectionType*)ex_block->extype, error);
332
333 if (!is_ok (error)) {
334 image_g_free (image, clauses);
335 return NULL;
336 }
337 clause->data.catch_class = mono_class_from_mono_type (extype);
338 } else {
339 if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
340 clause->data.filter_offset = ex_block->filter_offset;
341 else
342 clause->data.filter_offset = 0;
343 }
344 finally_start = ex_block->start + ex_block->len;
345
346 clause_index ++;
347 }
348 }
349
350 return clauses;
351 }
352 #endif /* !DISABLE_REFLECTION_EMIT */
353
354 #ifndef DISABLE_REFLECTION_EMIT
355 /*
356 * LOCKING: Acquires the loader lock.
357 */
358 static void
mono_save_custom_attrs(MonoImage * image,void * obj,MonoArray * cattrs)359 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
360 {
361 MONO_REQ_GC_UNSAFE_MODE;
362
363 MonoCustomAttrInfo *ainfo, *tmp;
364
365 if (!cattrs || !mono_array_length (cattrs))
366 return;
367
368 ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
369
370 mono_loader_lock ();
371 tmp = (MonoCustomAttrInfo *)mono_image_property_lookup (image, obj, MONO_PROP_DYNAMIC_CATTR);
372 if (tmp)
373 mono_custom_attrs_free (tmp);
374 mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
375 mono_loader_unlock ();
376
377 }
378 #else
379 //FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
380 static void
mono_save_custom_attrs(MonoImage * image,void * obj,MonoArray * cattrs)381 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
382 {
383 }
384 #endif
385
386 guint32
mono_reflection_resolution_scope_from_image(MonoDynamicImage * assembly,MonoImage * image)387 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
388 {
389 MONO_REQ_GC_UNSAFE_MODE;
390
391 MonoDynamicTable *table;
392 guint32 token;
393 guint32 *values;
394 guint32 cols [MONO_ASSEMBLY_SIZE];
395 const char *pubkey;
396 guint32 publen;
397
398 if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
399 return token;
400
401 if (assembly_is_dynamic (image->assembly) && (image->assembly == assembly->image.assembly)) {
402 table = &assembly->tables [MONO_TABLE_MODULEREF];
403 token = table->next_idx ++;
404 table->rows ++;
405 alloc_table (table, table->rows);
406 values = table->values + token * MONO_MODULEREF_SIZE;
407 values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
408
409 token <<= MONO_RESOLUTION_SCOPE_BITS;
410 token |= MONO_RESOLUTION_SCOPE_MODULEREF;
411 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
412
413 return token;
414 }
415
416 if (assembly_is_dynamic (image->assembly))
417 /* FIXME: */
418 memset (cols, 0, sizeof (cols));
419 else {
420 /* image->assembly->image is the manifest module */
421 image = image->assembly->image;
422 mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
423 }
424
425 table = &assembly->tables [MONO_TABLE_ASSEMBLYREF];
426 token = table->next_idx ++;
427 table->rows ++;
428 alloc_table (table, table->rows);
429 values = table->values + token * MONO_ASSEMBLYREF_SIZE;
430 values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
431 values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
432 values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
433 values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
434 values [MONO_ASSEMBLYREF_REV_NUMBER] = cols [MONO_ASSEMBLY_REV_NUMBER];
435 values [MONO_ASSEMBLYREF_FLAGS] = 0;
436 values [MONO_ASSEMBLYREF_CULTURE] = 0;
437 values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
438
439 if (strcmp ("", image->assembly->aname.culture)) {
440 values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
441 image->assembly->aname.culture);
442 }
443
444 if ((pubkey = mono_image_get_public_key (image, &publen))) {
445 guchar pubtoken [9];
446 pubtoken [0] = 8;
447 mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
448 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
449 } else {
450 values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
451 }
452 token <<= MONO_RESOLUTION_SCOPE_BITS;
453 token |= MONO_RESOLUTION_SCOPE_ASSEMBLYREF;
454 g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
455 return token;
456 }
457
458 #ifndef DISABLE_REFLECTION_EMIT
459 gboolean
mono_reflection_methodbuilder_from_method_builder(ReflectionMethodBuilder * rmb,MonoReflectionMethodBuilder * mb,MonoError * error)460 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error)
461 {
462 MONO_REQ_GC_UNSAFE_MODE;
463
464 error_init (error);
465 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
466
467 rmb->ilgen = mb->ilgen;
468 rmb->rtype = (MonoReflectionType*)mb->rtype;
469 return_val_if_nok (error, FALSE);
470 rmb->parameters = mb->parameters;
471 rmb->generic_params = mb->generic_params;
472 rmb->generic_container = mb->generic_container;
473 rmb->opt_types = NULL;
474 rmb->pinfo = mb->pinfo;
475 rmb->attrs = mb->attrs;
476 rmb->iattrs = mb->iattrs;
477 rmb->call_conv = mb->call_conv;
478 rmb->code = mb->code;
479 rmb->type = mb->type;
480 rmb->name = mb->name;
481 rmb->table_idx = &mb->table_idx;
482 rmb->init_locals = mb->init_locals;
483 rmb->skip_visibility = FALSE;
484 rmb->return_modreq = mb->return_modreq;
485 rmb->return_modopt = mb->return_modopt;
486 rmb->param_modreq = mb->param_modreq;
487 rmb->param_modopt = mb->param_modopt;
488 rmb->permissions = mb->permissions;
489 rmb->mhandle = mb->mhandle;
490 rmb->nrefs = 0;
491 rmb->refs = NULL;
492
493 if (mb->dll) {
494 rmb->charset = mb->charset;
495 rmb->extra_flags = mb->extra_flags;
496 rmb->native_cc = mb->native_cc;
497 rmb->dllentry = mb->dllentry;
498 rmb->dll = mb->dll;
499 }
500
501 return TRUE;
502 }
503
504 gboolean
mono_reflection_methodbuilder_from_ctor_builder(ReflectionMethodBuilder * rmb,MonoReflectionCtorBuilder * mb,MonoError * error)505 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
506 {
507 MONO_REQ_GC_UNSAFE_MODE;
508
509 const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
510
511 error_init (error);
512
513 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
514
515 rmb->ilgen = mb->ilgen;
516 rmb->rtype = mono_type_get_object_checked (mono_domain_get (), &mono_defaults.void_class->byval_arg, error);
517 return_val_if_nok (error, FALSE);
518 rmb->parameters = mb->parameters;
519 rmb->generic_params = NULL;
520 rmb->generic_container = NULL;
521 rmb->opt_types = NULL;
522 rmb->pinfo = mb->pinfo;
523 rmb->attrs = mb->attrs;
524 rmb->iattrs = mb->iattrs;
525 rmb->call_conv = mb->call_conv;
526 rmb->code = NULL;
527 rmb->type = mb->type;
528 rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
529 return_val_if_nok (error, FALSE);
530 rmb->table_idx = &mb->table_idx;
531 rmb->init_locals = mb->init_locals;
532 rmb->skip_visibility = FALSE;
533 rmb->return_modreq = NULL;
534 rmb->return_modopt = NULL;
535 rmb->param_modreq = mb->param_modreq;
536 rmb->param_modopt = mb->param_modopt;
537 rmb->permissions = mb->permissions;
538 rmb->mhandle = mb->mhandle;
539 rmb->nrefs = 0;
540 rmb->refs = NULL;
541
542 return TRUE;
543 }
544
545 static void
reflection_methodbuilder_from_dynamic_method(ReflectionMethodBuilder * rmb,MonoReflectionDynamicMethod * mb)546 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
547 {
548 MONO_REQ_GC_UNSAFE_MODE;
549
550 memset (rmb, 0, sizeof (ReflectionMethodBuilder));
551
552 rmb->ilgen = mb->ilgen;
553 rmb->rtype = mb->rtype;
554 rmb->parameters = mb->parameters;
555 rmb->generic_params = NULL;
556 rmb->generic_container = NULL;
557 rmb->opt_types = NULL;
558 rmb->pinfo = NULL;
559 rmb->attrs = mb->attrs;
560 rmb->iattrs = 0;
561 rmb->call_conv = mb->call_conv;
562 rmb->code = NULL;
563 rmb->type = (MonoObject *) mb->owner;
564 rmb->name = mb->name;
565 rmb->table_idx = NULL;
566 rmb->init_locals = mb->init_locals;
567 rmb->skip_visibility = mb->skip_visibility;
568 rmb->return_modreq = NULL;
569 rmb->return_modopt = NULL;
570 rmb->param_modreq = NULL;
571 rmb->param_modopt = NULL;
572 rmb->permissions = NULL;
573 rmb->mhandle = mb->mhandle;
574 rmb->nrefs = 0;
575 rmb->refs = NULL;
576 }
577 #else /* DISABLE_REFLECTION_EMIT */
578 gboolean
mono_reflection_methodbuilder_from_method_builder(ReflectionMethodBuilder * rmb,MonoReflectionMethodBuilder * mb,MonoError * error)579 mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb, MonoError *error) {
580 g_assert_not_reached ();
581 return FALSE;
582 }
583 gboolean
mono_reflection_methodbuilder_from_ctor_builder(ReflectionMethodBuilder * rmb,MonoReflectionCtorBuilder * mb,MonoError * error)584 mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb, MonoError *error)
585 {
586 g_assert_not_reached ();
587 return FALSE;
588 }
589 #endif /* DISABLE_REFLECTION_EMIT */
590
591 #ifndef DISABLE_REFLECTION_EMIT
592 static guint32
mono_image_add_memberef_row(MonoDynamicImage * assembly,guint32 parent,const char * name,guint32 sig)593 mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
594 {
595 MONO_REQ_GC_NEUTRAL_MODE;
596
597 MonoDynamicTable *table;
598 guint32 *values;
599 guint32 token, pclass;
600
601 switch (parent & MONO_TYPEDEFORREF_MASK) {
602 case MONO_TYPEDEFORREF_TYPEREF:
603 pclass = MONO_MEMBERREF_PARENT_TYPEREF;
604 break;
605 case MONO_TYPEDEFORREF_TYPESPEC:
606 pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
607 break;
608 case MONO_TYPEDEFORREF_TYPEDEF:
609 pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
610 break;
611 default:
612 g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
613 return 0;
614 }
615 /* extract the index */
616 parent >>= MONO_TYPEDEFORREF_BITS;
617
618 table = &assembly->tables [MONO_TABLE_MEMBERREF];
619
620 if (assembly->save) {
621 alloc_table (table, table->rows + 1);
622 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
623 values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
624 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
625 values [MONO_MEMBERREF_SIGNATURE] = sig;
626 }
627
628 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
629 table->next_idx ++;
630
631 return token;
632 }
633
634 /*
635 * Insert a memberef row into the metadata: the token that point to the memberref
636 * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
637 * mono_image_get_fieldref_token()).
638 * The sig param is an index to an already built signature.
639 */
640 static guint32
mono_image_get_memberref_token(MonoDynamicImage * assembly,MonoType * type,const char * name,guint32 sig)641 mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
642 {
643 MONO_REQ_GC_NEUTRAL_MODE;
644
645 guint32 parent = mono_image_typedef_or_ref (assembly, type);
646 return mono_image_add_memberef_row (assembly, parent, name, sig);
647 }
648
649
650 guint32
mono_image_get_methodref_token(MonoDynamicImage * assembly,MonoMethod * method,gboolean create_typespec)651 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
652 {
653 MONO_REQ_GC_NEUTRAL_MODE;
654
655 guint32 token;
656 MonoMethodSignature *sig;
657
658 create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
659
660 if (create_typespec) {
661 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
662 if (token)
663 return token;
664 }
665
666 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
667 if (token && !create_typespec)
668 return token;
669
670 g_assert (!method->is_inflated);
671 if (!token) {
672 /*
673 * A methodref signature can't contain an unmanaged calling convention.
674 */
675 sig = mono_metadata_signature_dup (mono_method_signature (method));
676 if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
677 sig->call_convention = MONO_CALL_DEFAULT;
678 token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
679 method->name, mono_dynimage_encode_method_signature (assembly, sig));
680 g_free (sig);
681 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
682 }
683
684 if (create_typespec) {
685 MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
686 g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
687 token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
688
689 if (assembly->save) {
690 guint32 *values;
691
692 alloc_table (table, table->rows + 1);
693 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
694 values [MONO_METHODSPEC_METHOD] = token;
695 values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
696 }
697
698 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
699 table->next_idx ++;
700 /*methodspec and memberef tokens are diferent, */
701 g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
702 return token;
703 }
704 return token;
705 }
706
707 static guint32
mono_image_get_varargs_method_token(MonoDynamicImage * assembly,guint32 original,const gchar * name,guint32 sig)708 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
709 const gchar *name, guint32 sig)
710 {
711 MonoDynamicTable *table;
712 guint32 token;
713 guint32 *values;
714
715 table = &assembly->tables [MONO_TABLE_MEMBERREF];
716
717 if (assembly->save) {
718 alloc_table (table, table->rows + 1);
719 values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
720 values [MONO_MEMBERREF_CLASS] = original;
721 values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
722 values [MONO_MEMBERREF_SIGNATURE] = sig;
723 }
724
725 token = MONO_TOKEN_MEMBER_REF | table->next_idx;
726 table->next_idx ++;
727
728 return token;
729 }
730
731 #else /* DISABLE_REFLECTION_EMIT */
732
733 guint32
mono_image_get_methodref_token(MonoDynamicImage * assembly,MonoMethod * method,gboolean create_typespec)734 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
735 {
736 g_assert_not_reached ();
737 return -1;
738 }
739 #endif
740
741 static gboolean
is_field_on_inst(MonoClassField * field)742 is_field_on_inst (MonoClassField *field)
743 {
744 return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
745 }
746
747 static gboolean
is_field_on_gtd(MonoClassField * field)748 is_field_on_gtd (MonoClassField *field)
749 {
750 return mono_class_is_gtd (field->parent);
751 }
752
753 #ifndef DISABLE_REFLECTION_EMIT
754 static guint32
mono_image_get_fieldref_token(MonoDynamicImage * assembly,MonoClassField * field)755 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
756 {
757 MonoType *type;
758 guint32 token;
759
760 g_assert (field);
761 g_assert (field->parent);
762
763 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
764 if (token)
765 return token;
766
767 if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
768 int index = field - field->parent->fields;
769 type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
770 } else {
771 type = mono_field_get_type (field);
772 }
773 token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
774 mono_field_get_name (field),
775 mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
776 g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
777 return token;
778 }
779
780 static guint32
method_encode_methodspec(MonoDynamicImage * assembly,MonoMethod * method)781 method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
782 {
783 MonoDynamicTable *table;
784 guint32 *values;
785 guint32 token, mtoken = 0, sig;
786 MonoMethodInflated *imethod;
787 MonoMethod *declaring;
788
789 table = &assembly->tables [MONO_TABLE_METHODSPEC];
790
791 g_assert (method->is_inflated);
792 imethod = (MonoMethodInflated *) method;
793 declaring = imethod->declaring;
794
795 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (declaring));
796 mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg, declaring->name, sig);
797
798 if (!mono_method_signature (declaring)->generic_param_count)
799 return mtoken;
800
801 switch (mono_metadata_token_table (mtoken)) {
802 case MONO_TABLE_MEMBERREF:
803 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
804 break;
805 case MONO_TABLE_METHOD:
806 mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
807 break;
808 default:
809 g_assert_not_reached ();
810 }
811
812 sig = mono_dynimage_encode_generic_method_sig (assembly, mono_method_get_context (method));
813
814 if (assembly->save) {
815 alloc_table (table, table->rows + 1);
816 values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
817 values [MONO_METHODSPEC_METHOD] = mtoken;
818 values [MONO_METHODSPEC_SIGNATURE] = sig;
819 }
820
821 token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
822 table->next_idx ++;
823
824 return token;
825 }
826
827 static guint32
mono_image_get_methodspec_token(MonoDynamicImage * assembly,MonoMethod * method)828 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
829 {
830 MonoMethodInflated *imethod;
831 guint32 token;
832
833 token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
834 if (token)
835 return token;
836
837 g_assert (method->is_inflated);
838 imethod = (MonoMethodInflated *) method;
839
840 if (mono_method_signature (imethod->declaring)->generic_param_count) {
841 token = method_encode_methodspec (assembly, method);
842 } else {
843 guint32 sig = mono_dynimage_encode_method_signature (
844 assembly, mono_method_signature (imethod->declaring));
845 token = mono_image_get_memberref_token (
846 assembly, &method->klass->byval_arg, method->name, sig);
847 }
848
849 g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
850 return token;
851 }
852
853 static guint32
mono_image_get_inflated_method_token(MonoDynamicImage * assembly,MonoMethod * m)854 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
855 {
856 MonoMethodInflated *imethod = (MonoMethodInflated *) m;
857 guint32 sig, token;
858
859 sig = mono_dynimage_encode_method_signature (assembly, mono_method_signature (imethod->declaring));
860 token = mono_image_get_memberref_token (
861 assembly, &m->klass->byval_arg, m->name, sig);
862
863 return token;
864 }
865
866 static guint32
mono_image_get_sighelper_token(MonoDynamicImage * assembly,MonoReflectionSigHelperHandle helper,MonoError * error)867 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
868 {
869 guint32 idx;
870 MonoDynamicTable *table;
871 guint32 *values;
872
873 error_init (error);
874
875 table = &assembly->tables [MONO_TABLE_STANDALONESIG];
876 idx = table->next_idx ++;
877 table->rows ++;
878 alloc_table (table, table->rows);
879 values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
880
881 values [MONO_STAND_ALONE_SIGNATURE] =
882 mono_dynimage_encode_reflection_sighelper (assembly, helper, error);
883 return_val_if_nok (error, 0);
884
885 return idx;
886 }
887
888 static int
reflection_cc_to_file(int call_conv)889 reflection_cc_to_file (int call_conv) {
890 switch (call_conv & 0x3) {
891 case 0:
892 case 1: return MONO_CALL_DEFAULT;
893 case 2: return MONO_CALL_VARARG;
894 default:
895 g_assert_not_reached ();
896 }
897 return 0;
898 }
899 #endif /* !DISABLE_REFLECTION_EMIT */
900
901 struct _ArrayMethod {
902 MonoType *parent;
903 MonoMethodSignature *sig;
904 char *name;
905 guint32 token;
906 };
907
908 void
mono_sre_array_method_free(ArrayMethod * am)909 mono_sre_array_method_free (ArrayMethod *am)
910 {
911 g_free (am->sig);
912 g_free (am->name);
913 g_free (am);
914 }
915
916 #ifndef DISABLE_REFLECTION_EMIT
917 static guint32
mono_image_get_array_token(MonoDynamicImage * assembly,MonoReflectionArrayMethodHandle m,MonoError * error)918 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethodHandle m, MonoError *error)
919 {
920 MonoMethodSignature *sig = NULL;
921 char *name = NULL;
922
923 error_init (error);
924
925 MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
926 guint32 nparams = mono_array_handle_length (parameters);
927 sig = (MonoMethodSignature *)g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
928 sig->hasthis = 1;
929 sig->sentinelpos = -1;
930 sig->call_convention = reflection_cc_to_file (MONO_HANDLE_GETVAL (m, call_conv));
931 sig->param_count = nparams;
932 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW_GET (MonoReflectionType, m, ret);
933 if (!MONO_HANDLE_IS_NULL (ret)) {
934 sig->ret = mono_reflection_type_handle_mono_type (ret, error);
935 goto_if_nok (error, fail);
936 } else
937 sig->ret = &mono_defaults.void_class->byval_arg;
938
939 MonoReflectionTypeHandle parent = MONO_HANDLE_NEW_GET (MonoReflectionType, m, parent);
940 MonoType *mtype = mono_reflection_type_handle_mono_type (parent, error);
941 goto_if_nok (error, fail);
942
943 for (int i = 0; i < nparams; ++i) {
944 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
945 goto_if_nok (error, fail);
946 }
947
948 MonoStringHandle mname = MONO_HANDLE_NEW_GET (MonoString, m, name);
949 name = mono_string_handle_to_utf8 (mname, error);
950 goto_if_nok (error, fail);
951
952 ArrayMethod *am = NULL;
953 for (GList *tmp = assembly->array_methods; tmp; tmp = tmp->next) {
954 am = (ArrayMethod *)tmp->data;
955 if (strcmp (name, am->name) == 0 &&
956 mono_metadata_type_equal (am->parent, mtype) &&
957 mono_metadata_signature_equal (am->sig, sig)) {
958 g_free (name);
959 g_free (sig);
960 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
961 return am->token;
962 }
963 }
964 am = g_new0 (ArrayMethod, 1);
965 am->name = name;
966 am->sig = sig;
967 am->parent = mtype;
968 am->token = mono_image_get_memberref_token (assembly, am->parent, name,
969 mono_dynimage_encode_method_signature (assembly, sig));
970 assembly->array_methods = g_list_prepend (assembly->array_methods, am);
971 MONO_HANDLE_SETVAL (m, table_idx, guint32, am->token & 0xffffff);
972 return am->token;
973 fail:
974 g_free (name);
975 g_free (sig);
976 return 0;
977
978 }
979 #endif
980
981 #ifndef DISABLE_REFLECTION_EMIT
982
983 /*
984 * mono_image_insert_string:
985 * @module: module builder object
986 * @str: a string
987 *
988 * Insert @str into the user string stream of @module.
989 */
990 guint32
mono_image_insert_string(MonoReflectionModuleBuilderHandle ref_module,MonoStringHandle str,MonoError * error)991 mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStringHandle str, MonoError *error)
992 {
993 HANDLE_FUNCTION_ENTER ();
994 guint32 idx;
995 char buf [16];
996 char *b = buf;
997 guint32 token = 0;
998
999 MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1000 if (!assembly) {
1001 if (!mono_image_module_basic_init (ref_module, error))
1002 goto leave;
1003
1004 assembly = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1005 }
1006 g_assert (assembly != NULL);
1007
1008 if (assembly->save) {
1009 int32_t length = mono_string_length (MONO_HANDLE_RAW (str));
1010 mono_metadata_encode_value (1 | (length * 2), b, &b);
1011 idx = mono_image_add_stream_data (&assembly->us, buf, b-buf);
1012 /* pinned */
1013 uint32_t gchandle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, str), TRUE);
1014 const char *p = (const char*)mono_string_chars (MONO_HANDLE_RAW (str));
1015 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
1016 {
1017 char *swapped = g_malloc (2 * length);
1018
1019 swap_with_size (swapped, p, 2, length);
1020 mono_image_add_stream_data (&assembly->us, swapped, length * 2);
1021 g_free (swapped);
1022 }
1023 #else
1024 mono_image_add_stream_data (&assembly->us, p, length * 2);
1025 #endif
1026 mono_gchandle_free (gchandle);
1027 mono_image_add_stream_data (&assembly->us, "", 1);
1028 } else {
1029 idx = assembly->us.index ++;
1030 }
1031
1032 token = MONO_TOKEN_STRING | idx;
1033 mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
1034
1035 leave:
1036 HANDLE_FUNCTION_RETURN_VAL (token);
1037 }
1038
1039 static guint32
create_method_token(MonoDynamicImage * assembly,MonoMethod * method,MonoArrayHandle opt_param_types,MonoError * error)1040 create_method_token (MonoDynamicImage *assembly, MonoMethod *method, MonoArrayHandle opt_param_types, MonoError *error)
1041 {
1042 guint32 sig_token, parent;
1043
1044
1045 int nargs = mono_array_handle_length (opt_param_types);
1046 MonoMethodSignature *old = mono_method_signature (method);
1047 MonoMethodSignature *sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);
1048
1049 sig->hasthis = old->hasthis;
1050 sig->explicit_this = old->explicit_this;
1051 sig->call_convention = old->call_convention;
1052 sig->generic_param_count = old->generic_param_count;
1053 sig->param_count = old->param_count + nargs;
1054 sig->sentinelpos = old->param_count;
1055 sig->ret = old->ret;
1056
1057 for (int i = 0; i < old->param_count; i++)
1058 sig->params [i] = old->params [i];
1059
1060 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1061 for (int i = 0; i < nargs; i++) {
1062 MONO_HANDLE_ARRAY_GETREF (rt, opt_param_types, i);
1063 sig->params [old->param_count + i] = mono_reflection_type_handle_mono_type (rt, error);
1064 goto_if_nok (error, fail);
1065 }
1066
1067 parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
1068 g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
1069 parent >>= MONO_TYPEDEFORREF_BITS;
1070
1071 parent <<= MONO_MEMBERREF_PARENT_BITS;
1072 parent |= MONO_MEMBERREF_PARENT_TYPEREF;
1073
1074 sig_token = mono_dynimage_encode_method_signature (assembly, sig);
1075 guint32 token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
1076 g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
1077 return token;
1078 fail:
1079 return 0;
1080 }
1081
1082 guint32
mono_image_create_method_token(MonoDynamicImage * assembly,MonoObjectHandle obj,MonoArrayHandle opt_param_types,MonoError * error)1083 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
1084 {
1085 guint32 token = 0;
1086
1087 error_init (error);
1088
1089 MonoClass *klass = mono_handle_class (obj);
1090 if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
1091 MonoReflectionMethodHandle ref_method = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1092 MonoMethod *method = MONO_HANDLE_GETVAL (ref_method, method);
1093 g_assert (!MONO_HANDLE_IS_NULL (opt_param_types) && (mono_method_signature (method)->sentinelpos >= 0));
1094 token = create_method_token (assembly, method, opt_param_types, error);
1095 goto_if_nok (error, fail);
1096 } else if (strcmp (klass->name, "MethodBuilder") == 0) {
1097 g_assert_not_reached ();
1098 } else {
1099 g_error ("requested method token for %s\n", klass->name);
1100 }
1101
1102 mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
1103 return token;
1104 fail:
1105 g_assert (!mono_error_ok (error));
1106 return 0;
1107 }
1108
1109 /*
1110 * mono_image_create_token:
1111 * @assembly: a dynamic assembly
1112 * @obj:
1113 * @register_token: Whenever to register the token in the assembly->tokens hash.
1114 *
1115 * Get a token to insert in the IL code stream for the given MemberInfo.
1116 * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time,
1117 * the table_idx-es were recomputed, so registering the token would overwrite an existing
1118 * entry.
1119 */
1120 guint32
mono_image_create_token(MonoDynamicImage * assembly,MonoObjectHandle obj,gboolean create_open_instance,gboolean register_token,MonoError * error)1121 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
1122 gboolean create_open_instance, gboolean register_token,
1123 MonoError *error)
1124 {
1125 HANDLE_FUNCTION_ENTER ();
1126 guint32 token = 0;
1127
1128 error_init (error);
1129
1130 MonoClass *klass = mono_handle_class (obj);
1131 MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
1132 MONO_HANDLE_ASSIGN (register_obj, obj);
1133
1134 /* Check for user defined reflection objects */
1135 /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
1136 if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
1137 mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
1138 goto leave;
1139 }
1140
1141 /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
1142 int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
1143
1144 if (strcmp (klass->name, "RuntimeType") == 0) {
1145 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
1146 goto_if_nok (error, leave);
1147 MonoClass *mc = mono_class_from_mono_type (type);
1148 token = mono_metadata_token_from_dor (
1149 mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
1150 /* If it's a RuntimeType now, we could have registered a
1151 * TypeBuilder for it before, so replacing is okay. */
1152 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1153 } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
1154 strcmp (klass->name, "MonoMethod") == 0) {
1155 MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
1156 MonoMethod *method = MONO_HANDLE_GETVAL (m, method);
1157 if (method->is_inflated) {
1158 if (create_open_instance) {
1159 guint32 methodspec_token = mono_image_get_methodspec_token (assembly, method);
1160 MonoReflectionMethodHandle canonical_obj =
1161 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
1162 goto_if_nok (error, leave);
1163 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1164 token = methodspec_token;
1165 } else
1166 token = mono_image_get_inflated_method_token (assembly, method);
1167 } else if ((method->klass->image == &assembly->image) &&
1168 !mono_class_is_ginst (method->klass) &&
1169 !mono_class_is_gtd (method->klass)) {
1170 static guint32 method_table_idx = 0xffffff;
1171 if (method->klass->wastypebuilder) {
1172 /* we use the same token as the one that was assigned
1173 * to the Methodbuilder.
1174 * FIXME: do the equivalent for Fields.
1175 */
1176 token = method->token;
1177 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1178 } else {
1179 /*
1180 * Each token should have a unique index, but the indexes are
1181 * assigned by managed code, so we don't know about them. An
1182 * easy solution is to count backwards...
1183 */
1184 method_table_idx --;
1185 token = MONO_TOKEN_METHOD_DEF | method_table_idx;
1186 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1187 }
1188 } else {
1189 guint32 methodref_token = mono_image_get_methodref_token (assembly, method, create_open_instance);
1190 /* We need to register a 'canonical' object. The same
1191 * MonoMethod could have been reflected via different
1192 * classes so the MonoReflectionMethod:reftype could be
1193 * different, and the object lookup in
1194 * dynamic_image_register_token would assert assert. So
1195 * we pick the MonoReflectionMethod object that has the
1196 * reflected type as NULL (ie, take the declaring type
1197 * of the method) */
1198 MonoReflectionMethodHandle canonical_obj =
1199 mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
1200 goto_if_nok (error, leave);
1201 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1202 token = methodref_token;
1203 }
1204 /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
1205 } else if (strcmp (klass->name, "MonoField") == 0) {
1206 MonoReflectionFieldHandle f = MONO_HANDLE_CAST (MonoReflectionField, obj);
1207 MonoClassField *field = MONO_HANDLE_GETVAL (f, field);
1208 if ((field->parent->image == &assembly->image) &&
1209 !is_field_on_gtd (field) &&
1210 !is_field_on_inst (field)) {
1211 static guint32 field_table_idx = 0xffffff;
1212 field_table_idx --;
1213 token = MONO_TOKEN_FIELD_DEF | field_table_idx;
1214 g_assert (!mono_class_is_gtd (field->parent));
1215 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1216 } else {
1217 guint32 fieldref_token = mono_image_get_fieldref_token (assembly, field);
1218 /* Same as methodref: get a canonical object to
1219 * register with the token. */
1220 MonoReflectionFieldHandle canonical_obj =
1221 mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj), field->parent, field, error);
1222 goto_if_nok (error, leave);
1223 MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
1224 token = fieldref_token;
1225 }
1226 /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
1227 } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
1228 MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
1229 /* mono_image_get_array_token caches tokens by signature */
1230 guint32 array_token = mono_image_get_array_token (assembly, m, error);
1231 goto_if_nok (error, leave);
1232 token = array_token;
1233 /* ModuleBuilder:GetArrayMethod() always returns a fresh
1234 * MonoArrayMethod instance even given the same method name and
1235 * signature. But they're all interchangeable, so it's okay to
1236 * replace.
1237 */
1238 how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
1239 } else if (strcmp (klass->name, "SignatureHelper") == 0) {
1240 MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
1241 /* always returns a fresh token */
1242 guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
1243 goto_if_nok (error, leave);
1244 token = sig_token;
1245 how_collide = MONO_DYN_IMAGE_TOK_NEW;
1246 } else {
1247 g_error ("requested token for %s\n", klass->name);
1248 }
1249
1250 if (register_token)
1251 mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
1252
1253 leave:
1254 HANDLE_FUNCTION_RETURN_VAL (token);
1255 }
1256
1257
1258 #endif
1259
1260 #ifndef DISABLE_REFLECTION_EMIT
1261
1262 static gboolean
assemblybuilderaccess_can_refonlyload(guint32 access)1263 assemblybuilderaccess_can_refonlyload (guint32 access)
1264 {
1265 return (access & 0x4) != 0;
1266 }
1267
1268 static gboolean
assemblybuilderaccess_can_run(guint32 access)1269 assemblybuilderaccess_can_run (guint32 access)
1270 {
1271 return (access & MonoAssemblyBuilderAccess_Run) != 0;
1272 }
1273
1274 static gboolean
assemblybuilderaccess_can_save(guint32 access)1275 assemblybuilderaccess_can_save (guint32 access)
1276 {
1277 return (access & MonoAssemblyBuilderAccess_Save) != 0;
1278 }
1279
1280
1281 /*
1282 * mono_reflection_dynimage_basic_init:
1283 * @assembly: an assembly builder object
1284 *
1285 * Create the MonoImage that represents the assembly builder and setup some
1286 * of the helper hash table and the basic metadata streams.
1287 */
1288 void
mono_reflection_dynimage_basic_init(MonoReflectionAssemblyBuilder * assemblyb)1289 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
1290 {
1291 MonoError error;
1292 MonoDynamicAssembly *assembly;
1293 MonoDynamicImage *image;
1294 MonoDomain *domain = mono_object_domain (assemblyb);
1295
1296 if (assemblyb->dynamic_assembly)
1297 return;
1298
1299 assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
1300
1301 MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
1302
1303 assembly->assembly.ref_count = 1;
1304 assembly->assembly.dynamic = TRUE;
1305 assembly->assembly.corlib_internal = assemblyb->corlib_internal;
1306 assemblyb->assembly.assembly = (MonoAssembly*)assembly;
1307 assembly->assembly.basedir = mono_string_to_utf8_checked (assemblyb->dir, &error);
1308 if (mono_error_set_pending_exception (&error))
1309 return;
1310 if (assemblyb->culture) {
1311 assembly->assembly.aname.culture = mono_string_to_utf8_checked (assemblyb->culture, &error);
1312 if (mono_error_set_pending_exception (&error))
1313 return;
1314 } else
1315 assembly->assembly.aname.culture = g_strdup ("");
1316
1317 if (assemblyb->version) {
1318 char *vstr = mono_string_to_utf8_checked (assemblyb->version, &error);
1319 if (mono_error_set_pending_exception (&error))
1320 return;
1321 char **version = g_strsplit (vstr, ".", 4);
1322 char **parts = version;
1323 assembly->assembly.aname.major = atoi (*parts++);
1324 assembly->assembly.aname.minor = atoi (*parts++);
1325 assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
1326 assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
1327
1328 g_strfreev (version);
1329 g_free (vstr);
1330 } else {
1331 assembly->assembly.aname.major = 0;
1332 assembly->assembly.aname.minor = 0;
1333 assembly->assembly.aname.build = 0;
1334 assembly->assembly.aname.revision = 0;
1335 }
1336
1337 assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
1338 assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
1339 assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
1340 assembly->domain = domain;
1341
1342 char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
1343 if (mono_error_set_pending_exception (&error))
1344 return;
1345 image = mono_dynamic_image_create (assembly, assembly_name, g_strdup ("RefEmit_YouForgotToDefineAModule"));
1346 image->initial_image = TRUE;
1347 assembly->assembly.aname.name = image->image.name;
1348 assembly->assembly.image = &image->image;
1349 if (assemblyb->pktoken && assemblyb->pktoken->max_length) {
1350 /* -1 to correct for the trailing NULL byte */
1351 if (assemblyb->pktoken->max_length != MONO_PUBLIC_KEY_TOKEN_LENGTH - 1) {
1352 g_error ("Public key token length invalid for assembly %s: %i", assembly->assembly.aname.name, assemblyb->pktoken->max_length);
1353 }
1354 memcpy (&assembly->assembly.aname.public_key_token, mono_array_addr (assemblyb->pktoken, guint8, 0), assemblyb->pktoken->max_length);
1355 }
1356
1357 mono_domain_assemblies_lock (domain);
1358 domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly);
1359 mono_domain_assemblies_unlock (domain);
1360
1361 register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
1362
1363 MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
1364
1365 mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
1366 }
1367
1368 #endif /* !DISABLE_REFLECTION_EMIT */
1369
1370 #ifndef DISABLE_REFLECTION_EMIT
1371 static gpointer
register_assembly(MonoDomain * domain,MonoReflectionAssembly * res,MonoAssembly * assembly)1372 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
1373 {
1374 return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL);
1375 }
1376
1377 static MonoReflectionModuleBuilderHandle
register_module(MonoDomain * domain,MonoReflectionModuleBuilderHandle res,MonoDynamicImage * module)1378 register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, MonoDynamicImage *module)
1379 {
1380 return CACHE_OBJECT_HANDLE (MonoReflectionModuleBuilderHandle, module, MONO_HANDLE_CAST (MonoObject, res), NULL);
1381 }
1382
1383 static gboolean
image_module_basic_init(MonoReflectionModuleBuilderHandle moduleb,MonoError * error)1384 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1385 {
1386 error_init (error);
1387 MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
1388 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
1389 MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
1390 MONO_HANDLE_GET (ab, moduleb, assemblyb);
1391 if (!image) {
1392 /*
1393 * FIXME: we already created an image in mono_reflection_dynimage_basic_init (), but
1394 * we don't know which module it belongs to, since that is only
1395 * determined at assembly save time.
1396 */
1397 /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
1398 MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name);
1399 char *name = mono_string_handle_to_utf8 (abname, error);
1400 return_val_if_nok (error, FALSE);
1401 MonoStringHandle modfqname = MONO_HANDLE_NEW_GET (MonoString, MONO_HANDLE_CAST (MonoReflectionModule, moduleb), fqname);
1402 char *fqname = mono_string_handle_to_utf8 (modfqname, error);
1403 if (!is_ok (error)) {
1404 g_free (name);
1405 return FALSE;
1406 }
1407 MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly);
1408 image = mono_dynamic_image_create (dynamic_assembly, name, fqname);
1409
1410 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image);
1411 MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image);
1412 register_module (domain, moduleb, image);
1413
1414 /* register the module with the assembly */
1415 MonoImage *ass = dynamic_assembly->assembly.image;
1416 int module_count = ass->module_count;
1417 MonoImage **new_modules = g_new0 (MonoImage *, module_count + 1);
1418
1419 if (ass->modules)
1420 memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
1421 new_modules [module_count] = &image->image;
1422 mono_image_addref (&image->image);
1423
1424 g_free (ass->modules);
1425 ass->modules = new_modules;
1426 ass->module_count ++;
1427 }
1428 return TRUE;
1429 }
1430
1431 static gboolean
mono_image_module_basic_init(MonoReflectionModuleBuilderHandle moduleb,MonoError * error)1432 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
1433 {
1434 error_init (error);
1435 return image_module_basic_init (moduleb, error);
1436 }
1437
1438 #endif
1439
1440 static gboolean
is_corlib_type(MonoClass * klass)1441 is_corlib_type (MonoClass *klass)
1442 {
1443 return klass->image == mono_defaults.corlib;
1444 }
1445
1446 #define check_corlib_type_cached(_class, _namespace, _name) do { \
1447 static MonoClass *cached_class; \
1448 if (cached_class) \
1449 return cached_class == _class; \
1450 if (is_corlib_type (_class) && !strcmp (_name, _class->name) && !strcmp (_namespace, _class->name_space)) { \
1451 cached_class = _class; \
1452 return TRUE; \
1453 } \
1454 return FALSE; \
1455 } while (0) \
1456
1457
1458 MonoType*
mono_type_array_get_and_resolve(MonoArrayHandle array,int idx,MonoError * error)1459 mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
1460 {
1461 HANDLE_FUNCTION_ENTER();
1462 error_init (error);
1463 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1464 MONO_HANDLE_ARRAY_GETREF (t, array, idx);
1465 MonoType *result = mono_reflection_type_handle_mono_type (t, error);
1466 HANDLE_FUNCTION_RETURN_VAL (result);
1467 }
1468
1469
1470 #ifndef DISABLE_REFLECTION_EMIT
1471 static gboolean
is_sre_array(MonoClass * klass)1472 is_sre_array (MonoClass *klass)
1473 {
1474 check_corlib_type_cached (klass, "System.Reflection.Emit", "ArrayType");
1475 }
1476
1477 static gboolean
is_sre_byref(MonoClass * klass)1478 is_sre_byref (MonoClass *klass)
1479 {
1480 check_corlib_type_cached (klass, "System.Reflection.Emit", "ByRefType");
1481 }
1482
1483 static gboolean
is_sre_pointer(MonoClass * klass)1484 is_sre_pointer (MonoClass *klass)
1485 {
1486 check_corlib_type_cached (klass, "System.Reflection.Emit", "PointerType");
1487 }
1488
1489 static gboolean
is_sre_generic_instance(MonoClass * klass)1490 is_sre_generic_instance (MonoClass *klass)
1491 {
1492 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
1493 }
1494
1495 static gboolean
is_sre_type_builder(MonoClass * klass)1496 is_sre_type_builder (MonoClass *klass)
1497 {
1498 check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilder");
1499 }
1500
1501 static gboolean
is_sre_method_builder(MonoClass * klass)1502 is_sre_method_builder (MonoClass *klass)
1503 {
1504 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodBuilder");
1505 }
1506
1507 gboolean
mono_is_sre_ctor_builder(MonoClass * klass)1508 mono_is_sre_ctor_builder (MonoClass *klass)
1509 {
1510 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorBuilder");
1511 }
1512
1513 static gboolean
is_sre_field_builder(MonoClass * klass)1514 is_sre_field_builder (MonoClass *klass)
1515 {
1516 check_corlib_type_cached (klass, "System.Reflection.Emit", "FieldBuilder");
1517 }
1518
1519 static gboolean
is_sre_gparam_builder(MonoClass * klass)1520 is_sre_gparam_builder (MonoClass *klass)
1521 {
1522 check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
1523 }
1524
1525 static gboolean
is_sre_enum_builder(MonoClass * klass)1526 is_sre_enum_builder (MonoClass *klass)
1527 {
1528 check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
1529 }
1530
1531 gboolean
mono_is_sre_method_on_tb_inst(MonoClass * klass)1532 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1533 {
1534 check_corlib_type_cached (klass, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
1535 }
1536
1537 gboolean
mono_is_sre_ctor_on_tb_inst(MonoClass * klass)1538 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1539 {
1540 check_corlib_type_cached (klass, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
1541 }
1542
1543 static MonoReflectionTypeHandle
mono_reflection_type_get_underlying_system_type(MonoReflectionTypeHandle t,MonoError * error)1544 mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, MonoError *error)
1545 {
1546 static MonoMethod *method_get_underlying_system_type = NULL;
1547 HANDLE_FUNCTION_ENTER ();
1548
1549 error_init (error);
1550
1551 if (!method_get_underlying_system_type)
1552 method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
1553
1554 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1555
1556 MonoMethod *usertype_method = mono_object_handle_get_virtual_method (MONO_HANDLE_CAST (MonoObject, t), method_get_underlying_system_type, error);
1557 goto_if_nok (error, leave);
1558
1559 MONO_HANDLE_ASSIGN (rt, MONO_HANDLE_NEW (MonoReflectionType, mono_runtime_invoke_checked (usertype_method, MONO_HANDLE_RAW (t), NULL, error)));
1560
1561 leave:
1562 HANDLE_FUNCTION_RETURN_REF (MonoReflectionType, rt);
1563 }
1564
1565 MonoType*
mono_reflection_type_get_handle(MonoReflectionType * ref_raw,MonoError * error)1566 mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
1567 {
1568 HANDLE_FUNCTION_ENTER ();
1569 error_init (error);
1570 MONO_HANDLE_DCL (MonoReflectionType, ref);
1571 MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
1572 HANDLE_FUNCTION_RETURN_VAL (result);
1573 }
1574
1575 static MonoType*
reflection_instance_handle_mono_type(MonoReflectionGenericClassHandle ref_gclass,MonoError * error)1576 reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclass, MonoError *error)
1577 {
1578 HANDLE_FUNCTION_ENTER ();
1579 MonoType *result = NULL;
1580 MonoType **types = NULL;
1581
1582 MonoArrayHandle typeargs = MONO_HANDLE_NEW_GET (MonoArray, ref_gclass, type_arguments);
1583 int count = mono_array_handle_length (typeargs);
1584 types = g_new0 (MonoType*, count);
1585 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1586 for (int i = 0; i < count; ++i) {
1587 MONO_HANDLE_ARRAY_GETREF (t, typeargs, i);
1588 types [i] = mono_reflection_type_handle_mono_type (t, error);
1589 if (!types[i] || !is_ok (error)) {
1590 goto leave;
1591 }
1592 }
1593 /* Need to resolve the generic_type in order for it to create its generic context. */
1594 MonoReflectionTypeHandle ref_gtd = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_gclass, generic_type);
1595 MonoType *gtd = mono_reflection_type_handle_mono_type (ref_gtd, error);
1596 goto_if_nok (error, leave);
1597 MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
1598 if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
1599 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
1600 goto_if_nok (error, leave);
1601 }
1602 g_assert (count == 0 || mono_class_is_gtd (gtd_klass));
1603 result = mono_reflection_bind_generic_parameters (ref_gtd, count, types, error);
1604 goto_if_nok (error, leave);
1605 g_assert (result);
1606 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gclass), type, MonoType*, result);
1607 leave:
1608 g_free (types);
1609 HANDLE_FUNCTION_RETURN_VAL (result);
1610 }
1611
1612 static MonoType*
reflection_param_handle_mono_type(MonoReflectionGenericParamHandle ref_gparam,MonoError * error)1613 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
1614 {
1615 HANDLE_FUNCTION_ENTER ();
1616 error_init (error);
1617 MonoType *result = NULL;
1618
1619
1620 MonoReflectionTypeBuilderHandle ref_tbuilder = MONO_HANDLE_NEW_GET (MonoReflectionTypeBuilder, ref_gparam, tbuilder);
1621 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tbuilder, module);
1622 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
1623 MonoImage *image = &dynamic_image->image;
1624
1625 MonoGenericParamFull *param = mono_image_new0 (image, MonoGenericParamFull, 1);
1626
1627 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_gparam, name);
1628 param->info.name = mono_string_to_utf8_image (image, ref_name, error);
1629 mono_error_assert_ok (error);
1630 param->param.num = MONO_HANDLE_GETVAL (ref_gparam, index);
1631
1632 MonoReflectionMethodBuilderHandle ref_mbuilder = MONO_HANDLE_NEW_GET (MonoReflectionMethodBuilder, ref_gparam, mbuilder);
1633 if (!MONO_HANDLE_IS_NULL (ref_mbuilder)) {
1634 MonoGenericContainer *generic_container = MONO_HANDLE_GETVAL (ref_mbuilder, generic_container);
1635 if (!generic_container) {
1636 generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
1637 generic_container->is_method = TRUE;
1638 /*
1639 * Cannot set owner.method, since the MonoMethod is not created yet.
1640 * Set the image field instead, so type_in_image () works.
1641 */
1642 generic_container->is_anonymous = TRUE;
1643 generic_container->owner.image = image;
1644 MONO_HANDLE_SETVAL (ref_mbuilder, generic_container, MonoGenericContainer*, generic_container);
1645 }
1646 param->param.owner = generic_container;
1647 } else {
1648 MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_tbuilder), error);
1649 goto_if_nok (error, leave);
1650 MonoClass *owner = mono_class_from_mono_type (type);
1651 g_assert (mono_class_is_gtd (owner));
1652 param->param.owner = mono_class_get_generic_container (owner);
1653 }
1654
1655 MonoClass *pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
1656
1657 result = &pklass->byval_arg;
1658
1659 mono_class_set_ref_info (pklass, MONO_HANDLE_CAST (MonoObject, ref_gparam));
1660 mono_image_append_class_to_reflection_info_set (pklass);
1661
1662 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), type, MonoType*, result);
1663
1664 leave:
1665 HANDLE_FUNCTION_RETURN_VAL (result);
1666 }
1667
1668 static MonoType*
mono_type_array_get_and_resolve_raw(MonoArray * array_raw,int idx,MonoError * error)1669 mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
1670 {
1671 HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
1672 error_init (error);
1673 MONO_HANDLE_DCL (MonoArray, array);
1674 MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
1675 HANDLE_FUNCTION_RETURN_VAL (result);
1676 }
1677
1678 MonoType*
mono_reflection_type_handle_mono_type(MonoReflectionTypeHandle ref,MonoError * error)1679 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
1680 {
1681 HANDLE_FUNCTION_ENTER ();
1682 error_init (error);
1683
1684 MonoType* result = NULL;
1685
1686 g_assert (ref);
1687 if (MONO_HANDLE_IS_NULL (ref))
1688 goto leave;
1689 MonoType *t = MONO_HANDLE_GETVAL (ref, type);
1690 if (t) {
1691 result = t;
1692 goto leave;
1693 }
1694
1695 if (mono_reflection_is_usertype (ref)) {
1696 MONO_HANDLE_ASSIGN (ref, mono_reflection_type_get_underlying_system_type (ref, error));
1697 if (!is_ok (error) || MONO_HANDLE_IS_NULL (ref) || mono_reflection_is_usertype (ref))
1698 goto leave;
1699 t = MONO_HANDLE_GETVAL (ref, type);
1700 if (t) {
1701 result = t;
1702 goto leave;
1703 }
1704 }
1705
1706 MonoClass *klass = mono_handle_class (ref);
1707
1708 if (is_sre_array (klass)) {
1709 MonoReflectionArrayTypeHandle sre_array = MONO_HANDLE_CAST (MonoReflectionArrayType, ref);
1710 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_array, element_type);
1711 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1712 goto_if_nok (error, leave);
1713 g_assert (base);
1714 gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
1715 MonoClass *eclass = mono_class_from_mono_type (base);
1716 result = mono_image_new0 (eclass->image, MonoType, 1);
1717 if (rank == 0) {
1718 result->type = MONO_TYPE_SZARRAY;
1719 result->data.klass = eclass;
1720 } else {
1721 MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
1722 result->type = MONO_TYPE_ARRAY;
1723 result->data.array = at;
1724 at->eklass = eclass;
1725 at->rank = rank;
1726 }
1727 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1728 } else if (is_sre_byref (klass)) {
1729 MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1730 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_byref, element_type);
1731 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1732 goto_if_nok (error, leave);
1733 g_assert (base);
1734 result = &mono_class_from_mono_type (base)->this_arg;
1735 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1736 } else if (is_sre_pointer (klass)) {
1737 MonoReflectionDerivedTypeHandle sre_pointer = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
1738 MonoReflectionTypeHandle ref_element = MONO_HANDLE_NEW_GET (MonoReflectionType, sre_pointer, element_type);
1739 MonoType *base = mono_reflection_type_handle_mono_type (ref_element, error);
1740 goto_if_nok (error, leave);
1741 g_assert (base);
1742 result = &mono_ptr_class_get (base)->byval_arg;
1743 MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
1744 } else if (is_sre_generic_instance (klass)) {
1745 result = reflection_instance_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericClass, ref), error);
1746 } else if (is_sre_gparam_builder (klass)) {
1747 result = reflection_param_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionGenericParam, ref), error);
1748 } else if (is_sre_enum_builder (klass)) {
1749 MonoReflectionEnumBuilderHandle ref_ebuilder = MONO_HANDLE_CAST (MonoReflectionEnumBuilder, ref);
1750
1751 MonoReflectionTypeHandle ref_tb = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_ebuilder, tb);
1752 result = mono_reflection_type_handle_mono_type (ref_tb, error);
1753 } else if (is_sre_type_builder (klass)) {
1754 MonoReflectionTypeBuilderHandle ref_tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref);
1755
1756 /* This happens when a finished type references an unfinished one. Have to create the minimal type */
1757 reflection_setup_internal_class (ref_tb, error);
1758 mono_error_assert_ok (error);
1759 result = MONO_HANDLE_GETVAL (ref, type);
1760 } else {
1761 g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
1762 }
1763 leave:
1764 HANDLE_FUNCTION_RETURN_VAL (result);
1765 }
1766
1767 /**
1768 * LOCKING: Assumes the loader lock is held.
1769 */
1770 static MonoMethodSignature*
parameters_to_signature(MonoImage * image,MonoArrayHandle parameters,MonoError * error)1771 parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError *error) {
1772 MonoMethodSignature *sig;
1773 int count, i;
1774
1775 error_init (error);
1776
1777 count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
1778
1779 sig = (MonoMethodSignature *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * count);
1780 sig->param_count = count;
1781 sig->sentinelpos = -1; /* FIXME */
1782 for (i = 0; i < count; ++i) {
1783 sig->params [i] = mono_type_array_get_and_resolve (parameters, i, error);
1784 if (!is_ok (error)) {
1785 image_g_free (image, sig);
1786 return NULL;
1787 }
1788 }
1789 return sig;
1790 }
1791
1792 /**
1793 * LOCKING: Assumes the loader lock is held.
1794 */
1795 static MonoMethodSignature*
ctor_builder_to_signature(MonoImage * image,MonoReflectionCtorBuilderHandle ctor,MonoError * error)1796 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
1797 MonoMethodSignature *sig;
1798
1799 error_init (error);
1800
1801 sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
1802 return_val_if_nok (error, NULL);
1803 sig->hasthis = MONO_HANDLE_GETVAL (ctor, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1804 sig->ret = &mono_defaults.void_class->byval_arg;
1805 return sig;
1806 }
1807
1808 static MonoMethodSignature*
ctor_builder_to_signature_raw(MonoImage * image,MonoReflectionCtorBuilder * ctor_raw,MonoError * error)1809 ctor_builder_to_signature_raw (MonoImage *image, MonoReflectionCtorBuilder* ctor_raw, MonoError *error) {
1810 HANDLE_FUNCTION_ENTER();
1811 MONO_HANDLE_DCL (MonoReflectionCtorBuilder, ctor);
1812 MonoMethodSignature *sig = ctor_builder_to_signature (image, ctor, error);
1813 HANDLE_FUNCTION_RETURN_VAL (sig);
1814 }
1815 /**
1816 * LOCKING: Assumes the loader lock is held.
1817 */
1818 static MonoMethodSignature*
method_builder_to_signature(MonoImage * image,MonoReflectionMethodBuilderHandle method,MonoError * error)1819 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error) {
1820 MonoMethodSignature *sig;
1821
1822 error_init (error);
1823
1824 sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, method, parameters), error);
1825 return_val_if_nok (error, NULL);
1826 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1827 MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1828 if (!MONO_HANDLE_IS_NULL (rtype)) {
1829 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1830 if (!is_ok (error)) {
1831 image_g_free (image, sig);
1832 return NULL;
1833 }
1834 } else {
1835 sig->ret = &mono_defaults.void_class->byval_arg;
1836 }
1837 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, method, generic_params);
1838 sig->generic_param_count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
1839 return sig;
1840 }
1841
1842 static MonoMethodSignature*
dynamic_method_to_signature(MonoReflectionDynamicMethodHandle method,MonoError * error)1843 dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError *error) {
1844 HANDLE_FUNCTION_ENTER ();
1845 MonoMethodSignature *sig = NULL;
1846
1847 error_init (error);
1848
1849 sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
1850 goto_if_nok (error, leave);
1851 sig->hasthis = MONO_HANDLE_GETVAL (method, attrs) & METHOD_ATTRIBUTE_STATIC? 0: 1;
1852 MonoReflectionTypeHandle rtype = MONO_HANDLE_NEW_GET (MonoReflectionType, method, rtype);
1853 if (!MONO_HANDLE_IS_NULL (rtype)) {
1854 sig->ret = mono_reflection_type_handle_mono_type (rtype, error);
1855 if (!is_ok (error)) {
1856 g_free (sig);
1857 sig = NULL;
1858 goto leave;
1859 }
1860 } else {
1861 sig->ret = &mono_defaults.void_class->byval_arg;
1862 }
1863 sig->generic_param_count = 0;
1864 leave:
1865 HANDLE_FUNCTION_RETURN_VAL (sig);
1866 }
1867
1868 static void
get_prop_name_and_type(MonoObject * prop,char ** name,MonoType ** type,MonoError * error)1869 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
1870 {
1871 error_init (error);
1872 MonoClass *klass = mono_object_class (prop);
1873 if (strcmp (klass->name, "PropertyBuilder") == 0) {
1874 MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
1875 *name = mono_string_to_utf8_checked (pb->name, error);
1876 return_if_nok (error);
1877 *type = mono_reflection_type_get_handle ((MonoReflectionType*)pb->type, error);
1878 } else {
1879 MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
1880 *name = g_strdup (p->property->name);
1881 if (p->property->get)
1882 *type = mono_method_signature (p->property->get)->ret;
1883 else
1884 *type = mono_method_signature (p->property->set)->params [mono_method_signature (p->property->set)->param_count - 1];
1885 }
1886 }
1887
1888 static void
get_field_name_and_type(MonoObject * field,char ** name,MonoType ** type,MonoError * error)1889 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
1890 {
1891 error_init (error);
1892 MonoClass *klass = mono_object_class (field);
1893 if (strcmp (klass->name, "FieldBuilder") == 0) {
1894 MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
1895 *name = mono_string_to_utf8_checked (fb->name, error);
1896 return_if_nok (error);
1897 *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
1898 } else {
1899 MonoReflectionField *f = (MonoReflectionField *)field;
1900 *name = g_strdup (mono_field_get_name (f->field));
1901 *type = f->field->type;
1902 }
1903 }
1904
1905 #else /* DISABLE_REFLECTION_EMIT */
1906
1907 static gboolean
is_sre_type_builder(MonoClass * klass)1908 is_sre_type_builder (MonoClass *klass)
1909 {
1910 return FALSE;
1911 }
1912
1913 static gboolean
is_sre_generic_instance(MonoClass * klass)1914 is_sre_generic_instance (MonoClass *klass)
1915 {
1916 return FALSE;
1917 }
1918
1919 gboolean
mono_is_sre_ctor_builder(MonoClass * klass)1920 mono_is_sre_ctor_builder (MonoClass *klass)
1921 {
1922 return FALSE;
1923 }
1924
1925 gboolean
mono_is_sre_method_on_tb_inst(MonoClass * klass)1926 mono_is_sre_method_on_tb_inst (MonoClass *klass)
1927 {
1928 return FALSE;
1929 }
1930
1931 gboolean
mono_is_sre_ctor_on_tb_inst(MonoClass * klass)1932 mono_is_sre_ctor_on_tb_inst (MonoClass *klass)
1933 {
1934 return FALSE;
1935 }
1936
1937 #endif /* !DISABLE_REFLECTION_EMIT */
1938
1939
1940 static gboolean
is_sr_mono_field(MonoClass * klass)1941 is_sr_mono_field (MonoClass *klass)
1942 {
1943 check_corlib_type_cached (klass, "System.Reflection", "MonoField");
1944 }
1945
1946 gboolean
mono_is_sr_mono_property(MonoClass * klass)1947 mono_is_sr_mono_property (MonoClass *klass)
1948 {
1949 check_corlib_type_cached (klass, "System.Reflection", "MonoProperty");
1950 }
1951
1952 static gboolean
is_sr_mono_method(MonoClass * klass)1953 is_sr_mono_method (MonoClass *klass)
1954 {
1955 check_corlib_type_cached (klass, "System.Reflection", "MonoMethod");
1956 }
1957
1958 gboolean
mono_is_sr_mono_cmethod(MonoClass * klass)1959 mono_is_sr_mono_cmethod (MonoClass *klass)
1960 {
1961 check_corlib_type_cached (klass, "System.Reflection", "MonoCMethod");
1962 }
1963
1964 gboolean
mono_class_is_reflection_method_or_constructor(MonoClass * klass)1965 mono_class_is_reflection_method_or_constructor (MonoClass *klass)
1966 {
1967 return is_sr_mono_method (klass) || mono_is_sr_mono_cmethod (klass);
1968 }
1969
1970 gboolean
mono_is_sre_type_builder(MonoClass * klass)1971 mono_is_sre_type_builder (MonoClass *klass)
1972 {
1973 return is_sre_type_builder (klass);
1974 }
1975
1976 gboolean
mono_is_sre_generic_instance(MonoClass * klass)1977 mono_is_sre_generic_instance (MonoClass *klass)
1978 {
1979 return is_sre_generic_instance (klass);
1980 }
1981
1982
1983
1984 /**
1985 * encode_cattr_value:
1986 * Encode a value in a custom attribute stream of bytes.
1987 * The value to encode is either supplied as an object in argument val
1988 * (valuetypes are boxed), or as a pointer to the data in the
1989 * argument argval.
1990 * @type represents the type of the value
1991 * @buffer is the start of the buffer
1992 * @p the current position in the buffer
1993 * @buflen contains the size of the buffer and is used to return the new buffer size
1994 * if this needs to be realloced.
1995 * @retbuffer and @retp return the start and the position of the buffer
1996 * @error set on error.
1997 */
1998 static void
encode_cattr_value(MonoAssembly * assembly,char * buffer,char * p,char ** retbuffer,char ** retp,guint32 * buflen,MonoType * type,MonoObject * arg,char * argval,MonoError * error)1999 encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval, MonoError *error)
2000 {
2001 MonoTypeEnum simple_type;
2002
2003 error_init (error);
2004 if ((p-buffer) + 10 >= *buflen) {
2005 char *newbuf;
2006 *buflen *= 2;
2007 newbuf = (char *)g_realloc (buffer, *buflen);
2008 p = newbuf + (p-buffer);
2009 buffer = newbuf;
2010 }
2011 if (!argval)
2012 argval = ((char*)arg + sizeof (MonoObject));
2013 simple_type = type->type;
2014 handle_enum:
2015 switch (simple_type) {
2016 case MONO_TYPE_BOOLEAN:
2017 case MONO_TYPE_U1:
2018 case MONO_TYPE_I1:
2019 *p++ = *argval;
2020 break;
2021 case MONO_TYPE_CHAR:
2022 case MONO_TYPE_U2:
2023 case MONO_TYPE_I2:
2024 swap_with_size (p, argval, 2, 1);
2025 p += 2;
2026 break;
2027 case MONO_TYPE_U4:
2028 case MONO_TYPE_I4:
2029 case MONO_TYPE_R4:
2030 swap_with_size (p, argval, 4, 1);
2031 p += 4;
2032 break;
2033 case MONO_TYPE_R8:
2034 swap_with_size (p, argval, 8, 1);
2035 p += 8;
2036 break;
2037 case MONO_TYPE_U8:
2038 case MONO_TYPE_I8:
2039 swap_with_size (p, argval, 8, 1);
2040 p += 8;
2041 break;
2042 case MONO_TYPE_VALUETYPE:
2043 if (type->data.klass->enumtype) {
2044 simple_type = mono_class_enum_basetype (type->data.klass)->type;
2045 goto handle_enum;
2046 } else {
2047 g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
2048 }
2049 break;
2050 case MONO_TYPE_STRING: {
2051 char *str;
2052 guint32 slen;
2053 if (!arg) {
2054 *p++ = 0xFF;
2055 break;
2056 }
2057 str = mono_string_to_utf8_checked ((MonoString*)arg, error);
2058 return_if_nok (error);
2059 slen = strlen (str);
2060 if ((p-buffer) + 10 + slen >= *buflen) {
2061 char *newbuf;
2062 *buflen *= 2;
2063 *buflen += slen;
2064 newbuf = (char *)g_realloc (buffer, *buflen);
2065 p = newbuf + (p-buffer);
2066 buffer = newbuf;
2067 }
2068 mono_metadata_encode_value (slen, p, &p);
2069 memcpy (p, str, slen);
2070 p += slen;
2071 g_free (str);
2072 break;
2073 }
2074 case MONO_TYPE_CLASS: {
2075 char *str;
2076 guint32 slen;
2077 MonoType *arg_type;
2078 if (!arg) {
2079 *p++ = 0xFF;
2080 break;
2081 }
2082 handle_type:
2083 arg_type = mono_reflection_type_get_handle ((MonoReflectionType*)arg, error);
2084 return_if_nok (error);
2085
2086 str = type_get_qualified_name (arg_type, NULL);
2087 slen = strlen (str);
2088 if ((p-buffer) + 10 + slen >= *buflen) {
2089 char *newbuf;
2090 *buflen *= 2;
2091 *buflen += slen;
2092 newbuf = (char *)g_realloc (buffer, *buflen);
2093 p = newbuf + (p-buffer);
2094 buffer = newbuf;
2095 }
2096 mono_metadata_encode_value (slen, p, &p);
2097 memcpy (p, str, slen);
2098 p += slen;
2099 g_free (str);
2100 break;
2101 }
2102 case MONO_TYPE_SZARRAY: {
2103 int len, i;
2104 MonoClass *eclass, *arg_eclass;
2105
2106 if (!arg) {
2107 *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
2108 break;
2109 }
2110 len = mono_array_length ((MonoArray*)arg);
2111 *p++ = len & 0xff;
2112 *p++ = (len >> 8) & 0xff;
2113 *p++ = (len >> 16) & 0xff;
2114 *p++ = (len >> 24) & 0xff;
2115 *retp = p;
2116 *retbuffer = buffer;
2117 eclass = type->data.klass;
2118 arg_eclass = mono_object_class (arg)->element_class;
2119
2120 if (!eclass) {
2121 /* Happens when we are called from the MONO_TYPE_OBJECT case below */
2122 eclass = mono_defaults.object_class;
2123 }
2124 if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
2125 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2126 int elsize = mono_class_array_element_size (arg_eclass);
2127 for (i = 0; i < len; ++i) {
2128 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr, error);
2129 return_if_nok (error);
2130 elptr += elsize;
2131 }
2132 } else if (eclass->valuetype && arg_eclass->valuetype) {
2133 char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
2134 int elsize = mono_class_array_element_size (eclass);
2135 for (i = 0; i < len; ++i) {
2136 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr, error);
2137 return_if_nok (error);
2138 elptr += elsize;
2139 }
2140 } else {
2141 for (i = 0; i < len; ++i) {
2142 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL, error);
2143 return_if_nok (error);
2144 }
2145 }
2146 break;
2147 }
2148 case MONO_TYPE_OBJECT: {
2149 MonoClass *klass;
2150 char *str;
2151 guint32 slen;
2152
2153 /*
2154 * The parameter type is 'object' but the type of the actual
2155 * argument is not. So we have to add type information to the blob
2156 * too. This is completely undocumented in the spec.
2157 */
2158
2159 if (arg == NULL) {
2160 *p++ = MONO_TYPE_STRING; // It's same hack as MS uses
2161 *p++ = 0xFF;
2162 break;
2163 }
2164
2165 klass = mono_object_class (arg);
2166
2167 if (mono_object_isinst_checked (arg, mono_defaults.systemtype_class, error)) {
2168 *p++ = 0x50;
2169 goto handle_type;
2170 } else {
2171 return_if_nok (error);
2172 }
2173
2174 if (klass->enumtype) {
2175 *p++ = 0x55;
2176 } else if (klass == mono_defaults.string_class) {
2177 simple_type = MONO_TYPE_STRING;
2178 *p++ = 0x0E;
2179 goto handle_enum;
2180 } else if (klass->rank == 1) {
2181 *p++ = 0x1D;
2182 if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
2183 /* See Partition II, Appendix B3 */
2184 *p++ = 0x51;
2185 else
2186 *p++ = klass->element_class->byval_arg.type;
2187 encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL, error);
2188 return_if_nok (error);
2189 break;
2190 } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
2191 *p++ = simple_type = klass->byval_arg.type;
2192 goto handle_enum;
2193 } else {
2194 g_error ("unhandled type in custom attr");
2195 }
2196 str = type_get_qualified_name (mono_class_get_type(klass), NULL);
2197 slen = strlen (str);
2198 if ((p-buffer) + 10 + slen >= *buflen) {
2199 char *newbuf;
2200 *buflen *= 2;
2201 *buflen += slen;
2202 newbuf = (char *)g_realloc (buffer, *buflen);
2203 p = newbuf + (p-buffer);
2204 buffer = newbuf;
2205 }
2206 mono_metadata_encode_value (slen, p, &p);
2207 memcpy (p, str, slen);
2208 p += slen;
2209 g_free (str);
2210 simple_type = mono_class_enum_basetype (klass)->type;
2211 goto handle_enum;
2212 }
2213 default:
2214 g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
2215 }
2216 *retp = p;
2217 *retbuffer = buffer;
2218 }
2219
2220 static void
encode_field_or_prop_type(MonoType * type,char * p,char ** retp)2221 encode_field_or_prop_type (MonoType *type, char *p, char **retp)
2222 {
2223 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2224 char *str = type_get_qualified_name (type, NULL);
2225 int slen = strlen (str);
2226
2227 *p++ = 0x55;
2228 /*
2229 * This seems to be optional...
2230 * *p++ = 0x80;
2231 */
2232 mono_metadata_encode_value (slen, p, &p);
2233 memcpy (p, str, slen);
2234 p += slen;
2235 g_free (str);
2236 } else if (type->type == MONO_TYPE_OBJECT) {
2237 *p++ = 0x51;
2238 } else if (type->type == MONO_TYPE_CLASS) {
2239 /* it should be a type: encode_cattr_value () has the check */
2240 *p++ = 0x50;
2241 } else {
2242 mono_metadata_encode_value (type->type, p, &p);
2243 if (type->type == MONO_TYPE_SZARRAY)
2244 /* See the examples in Partition VI, Annex B */
2245 encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
2246 }
2247
2248 *retp = p;
2249 }
2250
2251 #ifndef DISABLE_REFLECTION_EMIT
2252 static void
encode_named_val(MonoReflectionAssembly * assembly,char * buffer,char * p,char ** retbuffer,char ** retp,guint32 * buflen,MonoType * type,char * name,MonoObject * value,MonoError * error)2253 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value, MonoError *error)
2254 {
2255 int len;
2256
2257 error_init (error);
2258
2259 /* Preallocate a large enough buffer */
2260 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
2261 char *str = type_get_qualified_name (type, NULL);
2262 len = strlen (str);
2263 g_free (str);
2264 } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
2265 char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
2266 len = strlen (str);
2267 g_free (str);
2268 } else {
2269 len = 0;
2270 }
2271 len += strlen (name);
2272
2273 if ((p-buffer) + 20 + len >= *buflen) {
2274 char *newbuf;
2275 *buflen *= 2;
2276 *buflen += len;
2277 newbuf = (char *)g_realloc (buffer, *buflen);
2278 p = newbuf + (p-buffer);
2279 buffer = newbuf;
2280 }
2281
2282 encode_field_or_prop_type (type, p, &p);
2283
2284 len = strlen (name);
2285 mono_metadata_encode_value (len, p, &p);
2286 memcpy (p, name, len);
2287 p += len;
2288 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL, error);
2289 return_if_nok (error);
2290 *retp = p;
2291 *retbuffer = buffer;
2292 }
2293
2294 /**
2295 * mono_reflection_get_custom_attrs_blob:
2296 * \param ctor custom attribute constructor
2297 * \param ctorArgs arguments o the constructor
2298 * \param properties
2299 * \param propValues
2300 * \param fields
2301 * \param fieldValues
2302 * Creates the blob of data that needs to be saved in the metadata and that represents
2303 * the custom attributed described by \p ctor, \p ctorArgs etc.
2304 * \returns a \c Byte array representing the blob of data.
2305 */
2306 MonoArray*
mono_reflection_get_custom_attrs_blob(MonoReflectionAssembly * assembly,MonoObject * ctor,MonoArray * ctorArgs,MonoArray * properties,MonoArray * propValues,MonoArray * fields,MonoArray * fieldValues)2307 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
2308 {
2309 MonoError error;
2310 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
2311 mono_error_cleanup (&error);
2312 return result;
2313 }
2314
2315 /**
2316 * mono_reflection_get_custom_attrs_blob_checked:
2317 * \param ctor custom attribute constructor
2318 * \param ctorArgs arguments o the constructor
2319 * \param properties
2320 * \param propValues
2321 * \param fields
2322 * \param fieldValues
2323 * \param error set on error
2324 * Creates the blob of data that needs to be saved in the metadata and that represents
2325 * the custom attributed described by \p ctor, \p ctorArgs etc.
2326 * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
2327 */
2328 MonoArray*
mono_reflection_get_custom_attrs_blob_checked(MonoReflectionAssembly * assembly,MonoObject * ctor,MonoArray * ctorArgs,MonoArray * properties,MonoArray * propValues,MonoArray * fields,MonoArray * fieldValues,MonoError * error)2329 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
2330 {
2331 MonoArray *result = NULL;
2332 MonoMethodSignature *sig;
2333 MonoObject *arg;
2334 char *buffer, *p;
2335 guint32 buflen, i;
2336
2337 error_init (error);
2338
2339 if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
2340 /* sig is freed later so allocate it in the heap */
2341 sig = ctor_builder_to_signature_raw (NULL, (MonoReflectionCtorBuilder*)ctor, error); /* FIXME use handles */
2342 if (!is_ok (error)) {
2343 g_free (sig);
2344 return NULL;
2345 }
2346 } else {
2347 sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
2348 }
2349
2350 g_assert (mono_array_length (ctorArgs) == sig->param_count);
2351 buflen = 256;
2352 p = buffer = (char *)g_malloc (buflen);
2353 /* write the prolog */
2354 *p++ = 1;
2355 *p++ = 0;
2356 for (i = 0; i < sig->param_count; ++i) {
2357 arg = mono_array_get (ctorArgs, MonoObject*, i);
2358 encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL, error);
2359 goto_if_nok (error, leave);
2360 }
2361 i = 0;
2362 if (properties)
2363 i += mono_array_length (properties);
2364 if (fields)
2365 i += mono_array_length (fields);
2366 *p++ = i & 0xff;
2367 *p++ = (i >> 8) & 0xff;
2368 if (properties) {
2369 MonoObject *prop;
2370 for (i = 0; i < mono_array_length (properties); ++i) {
2371 MonoType *ptype;
2372 char *pname;
2373
2374 prop = (MonoObject *)mono_array_get (properties, gpointer, i);
2375 get_prop_name_and_type (prop, &pname, &ptype, error);
2376 goto_if_nok (error, leave);
2377 *p++ = 0x54; /* PROPERTY signature */
2378 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i), error);
2379 g_free (pname);
2380 goto_if_nok (error, leave);
2381 }
2382 }
2383
2384 if (fields) {
2385 MonoObject *field;
2386 for (i = 0; i < mono_array_length (fields); ++i) {
2387 MonoType *ftype;
2388 char *fname;
2389
2390 field = (MonoObject *)mono_array_get (fields, gpointer, i);
2391 get_field_name_and_type (field, &fname, &ftype, error);
2392 goto_if_nok (error, leave);
2393 *p++ = 0x53; /* FIELD signature */
2394 encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i), error);
2395 g_free (fname);
2396 goto_if_nok (error, leave);
2397 }
2398 }
2399
2400 g_assert (p - buffer <= buflen);
2401 buflen = p - buffer;
2402 result = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, buflen, error);
2403 goto_if_nok (error, leave);
2404 p = mono_array_addr (result, char, 0);
2405 memcpy (p, buffer, buflen);
2406 leave:
2407 g_free (buffer);
2408 if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
2409 g_free (sig);
2410 return result;
2411 }
2412
2413 static gboolean
reflection_setup_class_hierarchy(GHashTable * unparented,MonoError * error)2414 reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
2415 {
2416 error_init (error);
2417
2418 mono_loader_lock ();
2419
2420 MonoType *parent_type;
2421 MonoType *child_type;
2422 GHashTableIter iter;
2423
2424 g_hash_table_iter_init (&iter, unparented);
2425
2426 while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
2427 MonoClass *child_class = mono_class_from_mono_type (child_type);
2428 if (parent_type != NULL) {
2429 MonoClass *parent_class = mono_class_from_mono_type (parent_type);
2430 child_class->parent = NULL;
2431 /* fool mono_class_setup_parent */
2432 child_class->supertypes = NULL;
2433 mono_class_setup_parent (child_class, parent_class);
2434 } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
2435 const char *old_n = child_class->name;
2436 /* trick to get relative numbering right when compiling corlib */
2437 child_class->name = "BuildingObject";
2438 mono_class_setup_parent (child_class, mono_defaults.object_class);
2439 child_class->name = old_n;
2440 }
2441 mono_class_setup_mono_type (child_class);
2442 mono_class_setup_supertypes (child_class);
2443 }
2444
2445 mono_loader_unlock ();
2446 return is_ok (error);
2447 }
2448
2449 static gboolean
reflection_setup_internal_class_internal(MonoReflectionTypeBuilderHandle ref_tb,MonoError * error)2450 reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2451 {
2452 HANDLE_FUNCTION_ENTER ();
2453 error_init (error);
2454
2455 mono_loader_lock ();
2456
2457 gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
2458 if (entering_state != MonoTypeBuilderNew) {
2459 g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
2460 goto leave;
2461 }
2462
2463 MONO_HANDLE_SETVAL (ref_tb, state, MonoTypeBuilderState, MonoTypeBuilderEntered);
2464 MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2465 GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
2466
2467 // If this type is already setup, exit. We'll fix the parenting later
2468 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2469 if (type)
2470 goto leave;
2471
2472 MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
2473 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
2474
2475 MonoStringHandle ref_name = MONO_HANDLE_NEW_GET (MonoString, ref_tb, name);
2476 MonoStringHandle ref_nspace = MONO_HANDLE_NEW_GET (MonoString, ref_tb, nspace);
2477
2478 guint32 table_idx = MONO_HANDLE_GETVAL (ref_tb, table_idx);
2479 /*
2480 * The size calculation here warrants some explaining.
2481 * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
2482 * meaning we need to alloc enough space to morth a def into a gtd.
2483 */
2484 MonoClass *klass = (MonoClass *)mono_image_alloc0 (&dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
2485 klass->class_kind = MONO_CLASS_DEF;
2486
2487 klass->image = &dynamic_image->image;
2488
2489 klass->inited = 1; /* we lie to the runtime */
2490 klass->name = mono_string_to_utf8_image (klass->image, ref_name, error);
2491 goto_if_nok (error, leave);
2492 klass->name_space = mono_string_to_utf8_image (klass->image, ref_nspace, error);
2493 goto_if_nok (error, leave);
2494 klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
2495 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
2496
2497 MONO_PROFILER_RAISE (class_loading, (klass));
2498
2499 klass->element_class = klass;
2500
2501 g_assert (!mono_class_has_ref_info (klass));
2502 mono_class_set_ref_info (klass, MONO_HANDLE_CAST (MonoObject, ref_tb));
2503
2504 MonoReflectionTypeHandle ref_nesting_type = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, nesting_type);
2505 /* Put into cache so mono_class_get_checked () will find it.
2506 Skip nested types as those should not be available on the global scope. */
2507 if (MONO_HANDLE_IS_NULL (ref_nesting_type))
2508 mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, table_idx);
2509
2510 /*
2511 We must register all types as we cannot rely on the name_cache hashtable since we find the class
2512 by performing a mono_class_get which does the full resolution.
2513
2514 Working around this semantics would require us to write a lot of code for no clear advantage.
2515 */
2516 mono_image_append_class_to_reflection_info_set (klass);
2517
2518 mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
2519
2520 if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
2521 (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
2522 (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
2523 klass->instance_size = sizeof (MonoObject);
2524 klass->size_inited = 1;
2525 mono_class_setup_vtable_general (klass, NULL, 0, NULL);
2526 }
2527
2528 mono_class_setup_mono_type (klass);
2529
2530 /*
2531 * FIXME: handle interfaces.
2532 */
2533 MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
2534 MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
2535 MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
2536
2537 reflection_init_generic_class (ref_tb, error);
2538 goto_if_nok (error, leave);
2539
2540 // Do here so that the search inside of the parent can see the above type that's been set.
2541 MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
2542 MonoType *parent_type = NULL;
2543 if (!MONO_HANDLE_IS_NULL (ref_parent)) {
2544 MonoClass *parent_klass = mono_handle_class (ref_parent);
2545 gboolean recursive_init = TRUE;
2546
2547 if (is_sre_type_builder (parent_klass)) {
2548 MonoTypeBuilderState parent_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
2549
2550 if (parent_state != MonoTypeBuilderNew) {
2551 // Initialize types reachable from parent recursively
2552 // We'll fix the type hierarchy later
2553 recursive_init = FALSE;
2554 }
2555 }
2556
2557 if (recursive_init) {
2558 // If we haven't encountered a cycle, force the creation of ref_parent's type
2559 mono_reflection_type_handle_mono_type (ref_parent, error);
2560 goto_if_nok (error, leave);
2561 }
2562
2563 parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
2564
2565 // If we failed to create the parent, fail the child
2566 if (!parent_type)
2567 goto leave;
2568 }
2569
2570 // Push the child type and parent type to process later
2571 // Note: parent_type may be null.
2572 g_assert (!g_hash_table_lookup (unparented_classes, &klass->byval_arg));
2573 g_hash_table_insert (unparented_classes, &klass->byval_arg, parent_type);
2574
2575 if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
2576 if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
2577 goto leave;
2578
2579 MonoType *nesting_type = mono_reflection_type_handle_mono_type (ref_nesting_type, error);
2580 goto_if_nok (error, leave);
2581 klass->nested_in = mono_class_from_mono_type (nesting_type);
2582 }
2583
2584 /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
2585
2586 MONO_PROFILER_RAISE (class_loaded, (klass));
2587
2588 leave:
2589 mono_loader_unlock ();
2590 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2591 }
2592
2593 /**
2594 * reflection_init_generic_class:
2595 * @tb: a TypeBuilder object
2596 * @error: set on error
2597 *
2598 * Creates the generic class after all generic parameters have been added.
2599 * On success returns TRUE, on failure returns FALSE and sets @error.
2600 *
2601 * This assumes that reflection_setup_internal_class has already set up
2602 * ref_tb
2603 */
2604 static gboolean
reflection_init_generic_class(MonoReflectionTypeBuilderHandle ref_tb,MonoError * error)2605 reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
2606 {
2607 HANDLE_FUNCTION_ENTER ();
2608
2609 error_init (error);
2610
2611 MonoTypeBuilderState ref_state = MONO_HANDLE_GETVAL (ref_tb, state);
2612 g_assert (ref_state == MonoTypeBuilderFinished);
2613
2614 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
2615 MonoClass *klass = mono_class_from_mono_type (type);
2616
2617 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
2618 int count = MONO_HANDLE_IS_NULL (generic_params) ? 0 : mono_array_handle_length (generic_params);
2619
2620 if (count == 0)
2621 goto leave;
2622
2623 if (mono_class_try_get_generic_container (klass) != NULL)
2624 goto leave; /* already setup */
2625
2626 MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2627
2628 generic_container->owner.klass = klass;
2629 generic_container->type_argc = count;
2630 generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
2631
2632 klass->class_kind = MONO_CLASS_GTD;
2633 mono_class_set_generic_container (klass, generic_container);
2634
2635
2636 MonoReflectionGenericParamHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionGenericParam, NULL);
2637 for (int i = 0; i < count; i++) {
2638 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
2639 MonoType *param_type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, ref_gparam), error);
2640 goto_if_nok (error, leave);
2641 MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
2642 generic_container->type_params [i] = *param;
2643 /*Make sure we are a diferent type instance */
2644 generic_container->type_params [i].param.owner = generic_container;
2645 generic_container->type_params [i].info.pklass = NULL;
2646 generic_container->type_params [i].info.flags = MONO_HANDLE_GETVAL (ref_gparam, attrs);
2647
2648 g_assert (generic_container->type_params [i].param.owner);
2649 }
2650
2651 generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
2652 MonoGenericContext* context = &generic_container->context;
2653 MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
2654 canonical_inst->type = MONO_TYPE_GENERICINST;
2655 canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
2656
2657 leave:
2658 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2659 }
2660
2661 static MonoMarshalSpec*
mono_marshal_spec_from_builder(MonoImage * image,MonoAssembly * assembly,MonoReflectionMarshal * minfo,MonoError * error)2662 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
2663 MonoReflectionMarshal *minfo, MonoError *error)
2664 {
2665 MonoMarshalSpec *res;
2666
2667 error_init (error);
2668
2669 res = image_g_new0 (image, MonoMarshalSpec, 1);
2670 res->native = (MonoMarshalNative)minfo->type;
2671
2672 switch (minfo->type) {
2673 case MONO_NATIVE_LPARRAY:
2674 res->data.array_data.elem_type = (MonoMarshalNative)minfo->eltype;
2675 if (minfo->has_size) {
2676 res->data.array_data.param_num = minfo->param_num;
2677 res->data.array_data.num_elem = minfo->count;
2678 res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
2679 }
2680 else {
2681 res->data.array_data.param_num = -1;
2682 res->data.array_data.num_elem = -1;
2683 res->data.array_data.elem_mult = -1;
2684 }
2685 break;
2686
2687 case MONO_NATIVE_BYVALTSTR:
2688 case MONO_NATIVE_BYVALARRAY:
2689 res->data.array_data.num_elem = minfo->count;
2690 break;
2691
2692 case MONO_NATIVE_CUSTOM:
2693 if (minfo->marshaltyperef) {
2694 MonoType *marshaltyperef = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
2695 if (!is_ok (error)) {
2696 image_g_free (image, res);
2697 return NULL;
2698 }
2699 res->data.custom_data.custom_name =
2700 type_get_fully_qualified_name (marshaltyperef);
2701 }
2702 if (minfo->mcookie) {
2703 res->data.custom_data.cookie = mono_string_to_utf8_checked (minfo->mcookie, error);
2704 if (!is_ok (error)) {
2705 image_g_free (image, res);
2706 return NULL;
2707 }
2708 }
2709 break;
2710
2711 default:
2712 break;
2713 }
2714
2715 return res;
2716 }
2717 #endif /* !DISABLE_REFLECTION_EMIT */
2718
2719 MonoReflectionMarshalAsAttributeHandle
mono_reflection_marshal_as_attribute_from_marshal_spec(MonoDomain * domain,MonoClass * klass,MonoMarshalSpec * spec,MonoError * error)2720 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
2721 MonoMarshalSpec *spec, MonoError *error)
2722 {
2723 error_init (error);
2724
2725 MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
2726 goto_if_nok (error, fail);
2727 guint32 utype = spec->native;
2728 MONO_HANDLE_SETVAL (minfo, utype, guint32, utype);
2729
2730 switch (utype) {
2731 case MONO_NATIVE_LPARRAY:
2732 MONO_HANDLE_SETVAL (minfo, array_subtype, guint32, spec->data.array_data.elem_type);
2733 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2734 if (spec->data.array_data.param_num != -1)
2735 MONO_HANDLE_SETVAL (minfo, size_param_index, gint16, spec->data.array_data.param_num);
2736 break;
2737
2738 case MONO_NATIVE_BYVALTSTR:
2739 case MONO_NATIVE_BYVALARRAY:
2740 MONO_HANDLE_SETVAL (minfo, size_const, gint32, spec->data.array_data.num_elem);
2741 break;
2742
2743 case MONO_NATIVE_CUSTOM:
2744 if (spec->data.custom_data.custom_name) {
2745 MonoType *mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, klass->image, error);
2746 goto_if_nok (error, fail);
2747
2748 if (mtype) {
2749 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, mtype, error);
2750 goto_if_nok (error, fail);
2751
2752 MONO_HANDLE_SET (minfo, marshal_type_ref, rt);
2753 }
2754
2755 MonoStringHandle custom_name = mono_string_new_handle (domain, spec->data.custom_data.custom_name, error);
2756 goto_if_nok (error, fail);
2757 MONO_HANDLE_SET (minfo, marshal_type, custom_name);
2758 }
2759 if (spec->data.custom_data.cookie) {
2760 MonoStringHandle cookie = mono_string_new_handle (domain, spec->data.custom_data.cookie, error);
2761 goto_if_nok (error, fail);
2762 MONO_HANDLE_SET (minfo, marshal_cookie, cookie);
2763 }
2764 break;
2765
2766 default:
2767 break;
2768 }
2769
2770 return minfo;
2771 fail:
2772 return MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
2773 }
2774
2775 #ifndef DISABLE_REFLECTION_EMIT
2776 static MonoMethod*
reflection_methodbuilder_to_mono_method(MonoClass * klass,ReflectionMethodBuilder * rmb,MonoMethodSignature * sig,MonoError * error)2777 reflection_methodbuilder_to_mono_method (MonoClass *klass,
2778 ReflectionMethodBuilder *rmb,
2779 MonoMethodSignature *sig,
2780 MonoError *error)
2781 {
2782 MonoMethod *m;
2783 MonoMethodWrapper *wrapperm;
2784 MonoMarshalSpec **specs;
2785 MonoReflectionMethodAux *method_aux;
2786 MonoImage *image;
2787 gboolean dynamic;
2788 int i;
2789
2790 error_init (error);
2791 /*
2792 * Methods created using a MethodBuilder should have their memory allocated
2793 * inside the image mempool, while dynamic methods should have their memory
2794 * malloc'd.
2795 */
2796 dynamic = rmb->refs != NULL;
2797 image = dynamic ? NULL : klass->image;
2798
2799 if (!dynamic)
2800 g_assert (!mono_class_is_ginst (klass));
2801
2802 mono_loader_lock ();
2803
2804 if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2805 (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2806 m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
2807 else
2808 m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
2809
2810 wrapperm = (MonoMethodWrapper*)m;
2811
2812 m->dynamic = dynamic;
2813 m->slot = -1;
2814 m->flags = rmb->attrs;
2815 m->iflags = rmb->iattrs;
2816 m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
2817 m->klass = klass;
2818 m->signature = sig;
2819 m->sre_method = TRUE;
2820 m->skip_visibility = rmb->skip_visibility;
2821 if (rmb->table_idx)
2822 m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
2823
2824 if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
2825 if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
2826 m->string_ctor = 1;
2827
2828 m->signature->pinvoke = 1;
2829 } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
2830 m->signature->pinvoke = 1;
2831
2832 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2833
2834 method_aux->dllentry = rmb->dllentry ? string_to_utf8_image_raw (image, rmb->dllentry, error) : image_strdup (image, m->name);
2835 mono_error_assert_ok (error);
2836 method_aux->dll = string_to_utf8_image_raw (image, rmb->dll, error);
2837 mono_error_assert_ok (error);
2838
2839 ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
2840
2841 if (image_is_dynamic (klass->image))
2842 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
2843
2844 mono_loader_unlock ();
2845
2846 return m;
2847 } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
2848 !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2849 MonoMethodHeader *header;
2850 guint32 code_size;
2851 gint32 max_stack, i;
2852 gint32 num_locals = 0;
2853 gint32 num_clauses = 0;
2854 guint8 *code;
2855
2856 if (rmb->ilgen) {
2857 code = mono_array_addr (rmb->ilgen->code, guint8, 0);
2858 code_size = rmb->ilgen->code_len;
2859 max_stack = rmb->ilgen->max_stack;
2860 num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
2861 if (rmb->ilgen->ex_handlers)
2862 num_clauses = mono_reflection_method_count_clauses (rmb->ilgen);
2863 } else {
2864 if (rmb->code) {
2865 code = mono_array_addr (rmb->code, guint8, 0);
2866 code_size = mono_array_length (rmb->code);
2867 /* we probably need to run a verifier on the code... */
2868 max_stack = 8;
2869 }
2870 else {
2871 code = NULL;
2872 code_size = 0;
2873 max_stack = 8;
2874 }
2875 }
2876
2877 header = (MonoMethodHeader *)mono_image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
2878 header->code_size = code_size;
2879 header->code = (const unsigned char *)image_g_malloc (image, code_size);
2880 memcpy ((char*)header->code, code, code_size);
2881 header->max_stack = max_stack;
2882 header->init_locals = rmb->init_locals;
2883 header->num_locals = num_locals;
2884
2885 for (i = 0; i < num_locals; ++i) {
2886 MonoReflectionLocalBuilder *lb =
2887 mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
2888
2889 header->locals [i] = image_g_new0 (image, MonoType, 1);
2890 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)lb->type, error);
2891 mono_error_assert_ok (error);
2892 memcpy (header->locals [i], type, MONO_SIZEOF_TYPE);
2893 }
2894
2895 header->num_clauses = num_clauses;
2896 if (num_clauses) {
2897 header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
2898 rmb->ilgen, num_clauses, error);
2899 mono_error_assert_ok (error);
2900 }
2901
2902 wrapperm->header = header;
2903 MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
2904 dm->assembly = klass->image->assembly;
2905 }
2906
2907 if (rmb->generic_params) {
2908 int count = mono_array_length (rmb->generic_params);
2909 MonoGenericContainer *container;
2910
2911 container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
2912 container->is_method = TRUE;
2913 container->is_anonymous = FALSE;
2914 container->type_argc = count;
2915 container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
2916 container->owner.method = m;
2917
2918 m->is_generic = TRUE;
2919 mono_method_set_generic_container (m, container);
2920
2921 for (i = 0; i < count; i++) {
2922 MonoReflectionGenericParam *gp =
2923 mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
2924 MonoType *gp_type = mono_reflection_type_get_handle ((MonoReflectionType*)gp, error);
2925 mono_error_assert_ok (error);
2926 MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
2927 container->type_params [i] = *param;
2928 container->type_params [i].param.owner = container;
2929
2930 gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
2931
2932 MonoClass *gklass = mono_class_from_mono_type (gp_type);
2933 gklass->wastypebuilder = TRUE;
2934 }
2935
2936 /*
2937 * The method signature might have pointers to generic parameters that belong to other methods.
2938 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
2939 * generic parameters.
2940 */
2941 for (i = 0; i < m->signature->param_count; ++i) {
2942 MonoType *t = m->signature->params [i];
2943 if (t->type == MONO_TYPE_MVAR) {
2944 MonoGenericParam *gparam = t->data.generic_param;
2945 if (gparam->num < count) {
2946 m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
2947 m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
2948 }
2949
2950 }
2951 }
2952
2953 if (mono_class_is_gtd (klass)) {
2954 container->parent = mono_class_get_generic_container (klass);
2955 container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
2956 }
2957 container->context.method_inst = mono_get_shared_generic_inst (container);
2958 }
2959
2960 if (rmb->refs) {
2961 MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
2962 int i;
2963 void **data;
2964
2965 m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
2966
2967 mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
2968 data [0] = GUINT_TO_POINTER (rmb->nrefs);
2969 for (i = 0; i < rmb->nrefs; ++i)
2970 data [i + 1] = rmb->refs [i];
2971 }
2972
2973 method_aux = NULL;
2974
2975 /* Parameter info */
2976 if (rmb->pinfo) {
2977 if (!method_aux)
2978 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
2979 method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
2980 for (i = 0; i <= m->signature->param_count; ++i) {
2981 MonoReflectionParamBuilder *pb;
2982 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
2983 if ((i > 0) && (pb->attrs)) {
2984 /* Make a copy since it might point to a shared type structure */
2985 m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
2986 m->signature->params [i - 1]->attrs = pb->attrs;
2987 }
2988
2989 if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
2990 MonoDynamicImage *assembly;
2991 guint32 idx, len;
2992 MonoTypeEnum def_type;
2993 char *p;
2994 const char *p2;
2995
2996 if (!method_aux->param_defaults) {
2997 method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
2998 method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
2999 }
3000 assembly = (MonoDynamicImage*)klass->image;
3001 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &def_type);
3002 /* Copy the data from the blob since it might get realloc-ed */
3003 p = assembly->blob.data + idx;
3004 len = mono_metadata_decode_blob_size (p, &p2);
3005 len += p2 - p;
3006 method_aux->param_defaults [i] = (uint8_t *)image_g_malloc (image, len);
3007 method_aux->param_default_types [i] = def_type;
3008 memcpy ((gpointer)method_aux->param_defaults [i], p, len);
3009 }
3010
3011 if (pb->name) {
3012 method_aux->param_names [i] = string_to_utf8_image_raw (image, pb->name, error);
3013 mono_error_assert_ok (error);
3014 }
3015 if (pb->cattrs) {
3016 if (!method_aux->param_cattr)
3017 method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
3018 method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
3019 }
3020 }
3021 }
3022 }
3023
3024 /* Parameter marshalling */
3025 specs = NULL;
3026 if (rmb->pinfo)
3027 for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
3028 MonoReflectionParamBuilder *pb;
3029 if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
3030 if (pb->marshal_info) {
3031 if (specs == NULL)
3032 specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
3033 specs [pb->position] =
3034 mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info, error);
3035 if (!is_ok (error)) {
3036 mono_loader_unlock ();
3037 image_g_free (image, specs);
3038 /* FIXME: if image is NULL, this leaks all the other stuff we alloc'd in this function */
3039 return NULL;
3040 }
3041 }
3042 }
3043 }
3044 if (specs != NULL) {
3045 if (!method_aux)
3046 method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
3047 method_aux->param_marshall = specs;
3048 }
3049
3050 if (image_is_dynamic (klass->image) && method_aux)
3051 g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
3052
3053 mono_loader_unlock ();
3054
3055 return m;
3056 }
3057
3058 static MonoMethod*
ctorbuilder_to_mono_method(MonoClass * klass,MonoReflectionCtorBuilder * mb,MonoError * error)3059 ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, MonoError *error)
3060 {
3061 ReflectionMethodBuilder rmb;
3062 MonoMethodSignature *sig;
3063
3064 mono_loader_lock ();
3065
3066 if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
3067 return NULL;
3068
3069 g_assert (klass->image != NULL);
3070 sig = ctor_builder_to_signature_raw (klass->image, mb, error); /* FIXME use handles */
3071 mono_loader_unlock ();
3072 return_val_if_nok (error, NULL);
3073
3074 mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3075 return_val_if_nok (error, NULL);
3076 mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
3077
3078 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
3079 /* ilgen is no longer needed */
3080 mb->ilgen = NULL;
3081 }
3082
3083 return mb->mhandle;
3084 }
3085
3086 static MonoMethod*
methodbuilder_to_mono_method(MonoClass * klass,MonoReflectionMethodBuilderHandle ref_mb,MonoError * error)3087 methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandle ref_mb, MonoError *error)
3088 {
3089 ReflectionMethodBuilder rmb;
3090 MonoMethodSignature *sig;
3091
3092 error_init (error);
3093
3094 mono_loader_lock ();
3095
3096 MonoReflectionMethodBuilder *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME use handles */
3097 if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
3098 return NULL;
3099
3100 g_assert (klass->image != NULL);
3101 sig = method_builder_to_signature (klass->image, ref_mb, error);
3102 mono_loader_unlock ();
3103 return_val_if_nok (error, NULL);
3104
3105 MonoMethod *method = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3106 return_val_if_nok (error, NULL);
3107 MONO_HANDLE_SETVAL (ref_mb, mhandle, MonoMethod*, method);
3108 mono_save_custom_attrs (klass->image, method, mb->cattrs);
3109
3110 if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save)
3111 /* ilgen is no longer needed */
3112 mb->ilgen = NULL;
3113 return method;
3114 }
3115
3116 static MonoMethod*
methodbuilder_to_mono_method_raw(MonoClass * klass,MonoReflectionMethodBuilder * mb_raw,MonoError * error)3117 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
3118 {
3119 HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
3120 error_init (error);
3121 MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
3122 MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
3123 HANDLE_FUNCTION_RETURN_VAL (result);
3124 }
3125
3126 #endif
3127
3128 #ifndef DISABLE_REFLECTION_EMIT
3129
3130 /**
3131 * fix_partial_generic_class:
3132 * @klass: a generic instantiation MonoClass
3133 * @error: set on error
3134 *
3135 * Assumes that the generic container of @klass has its vtable
3136 * initialized, and updates the parent class, interfaces, methods and
3137 * fields of @klass by inflating the types using the generic context.
3138 *
3139 * On success returns TRUE, on failure returns FALSE and sets @error.
3140 *
3141 */
3142 static gboolean
fix_partial_generic_class(MonoClass * klass,MonoError * error)3143 fix_partial_generic_class (MonoClass *klass, MonoError *error)
3144 {
3145 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3146 int i;
3147
3148 error_init (error);
3149
3150 if (klass->wastypebuilder)
3151 return TRUE;
3152
3153 if (klass->parent != gklass->parent) {
3154 MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
3155 if (mono_error_ok (error)) {
3156 MonoClass *parent = mono_class_from_mono_type (parent_type);
3157 mono_metadata_free_type (parent_type);
3158 if (parent != klass->parent) {
3159 /*fool mono_class_setup_parent*/
3160 klass->supertypes = NULL;
3161 mono_class_setup_parent (klass, parent);
3162 }
3163 } else {
3164 if (gklass->wastypebuilder)
3165 klass->wastypebuilder = TRUE;
3166 return FALSE;
3167 }
3168 }
3169
3170 if (!mono_class_get_generic_class (klass)->need_sync)
3171 return TRUE;
3172
3173 int mcount = mono_class_get_method_count (klass);
3174 int gmcount = mono_class_get_method_count (gklass);
3175 if (mcount != gmcount) {
3176 mono_class_set_method_count (klass, gmcount);
3177 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
3178
3179 for (i = 0; i < gmcount; i++) {
3180 klass->methods [i] = mono_class_inflate_generic_method_full_checked (
3181 gklass->methods [i], klass, mono_class_get_context (klass), error);
3182 mono_error_assert_ok (error);
3183 }
3184 }
3185
3186 if (klass->interface_count && klass->interface_count != gklass->interface_count) {
3187 klass->interface_count = gklass->interface_count;
3188 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
3189 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3190
3191 for (i = 0; i < gklass->interface_count; ++i) {
3192 MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), error);
3193 return_val_if_nok (error, FALSE);
3194
3195 klass->interfaces [i] = mono_class_from_mono_type (iface_type);
3196 mono_metadata_free_type (iface_type);
3197
3198 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3199 return FALSE;
3200 }
3201 klass->interfaces_inited = 1;
3202 }
3203
3204 int fcount = mono_class_get_field_count (klass);
3205 int gfcount = mono_class_get_field_count (gklass);
3206 if (fcount != gfcount) {
3207 mono_class_set_field_count (klass, gfcount);
3208 klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
3209
3210 for (i = 0; i < gfcount; i++) {
3211 klass->fields [i] = gklass->fields [i];
3212 klass->fields [i].parent = klass;
3213 klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
3214 return_val_if_nok (error, FALSE);
3215 }
3216 }
3217
3218 /*We can only finish with this klass once it's parent has as well*/
3219 if (gklass->wastypebuilder)
3220 klass->wastypebuilder = TRUE;
3221 return TRUE;
3222 }
3223
3224 /**
3225 * ensure_generic_class_runtime_vtable:
3226 * @klass a generic class
3227 * @error set on error
3228 *
3229 * Ensures that the generic container of @klass has a vtable and
3230 * returns TRUE on success. On error returns FALSE and sets @error.
3231 */
3232 static gboolean
ensure_generic_class_runtime_vtable(MonoClass * klass,MonoError * error)3233 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
3234 {
3235 MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
3236
3237 error_init (error);
3238
3239 if (!ensure_runtime_vtable (gklass, error))
3240 return FALSE;
3241
3242 return fix_partial_generic_class (klass, error);
3243 }
3244
3245 /**
3246 * ensure_runtime_vtable:
3247 * @klass the class
3248 * @error set on error
3249 *
3250 * Ensures that @klass has a vtable and returns TRUE on success. On
3251 * error returns FALSE and sets @error.
3252 */
3253 static gboolean
ensure_runtime_vtable(MonoClass * klass,MonoError * error)3254 ensure_runtime_vtable (MonoClass *klass, MonoError *error)
3255 {
3256 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3257 int i, num, j;
3258
3259 error_init (error);
3260
3261 if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
3262 return TRUE;
3263 if (klass->parent)
3264 if (!ensure_runtime_vtable (klass->parent, error))
3265 return FALSE;
3266
3267 if (tb) {
3268 num = tb->ctors? mono_array_length (tb->ctors): 0;
3269 num += tb->num_methods;
3270 mono_class_set_method_count (klass, num);
3271 klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
3272 num = tb->ctors? mono_array_length (tb->ctors): 0;
3273 for (i = 0; i < num; ++i) {
3274 MonoMethod *ctor = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), error);
3275 if (!ctor)
3276 return FALSE;
3277 klass->methods [i] = ctor;
3278 }
3279 num = tb->num_methods;
3280 j = i;
3281 for (i = 0; i < num; ++i) {
3282 MonoMethod *meth = methodbuilder_to_mono_method_raw (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), error); /* FIXME use handles */
3283 if (!meth)
3284 return FALSE;
3285 klass->methods [j++] = meth;
3286 }
3287
3288 if (tb->interfaces) {
3289 klass->interface_count = mono_array_length (tb->interfaces);
3290 klass->interfaces = (MonoClass **)mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
3291 for (i = 0; i < klass->interface_count; ++i) {
3292 MonoType *iface = mono_type_array_get_and_resolve_raw (tb->interfaces, i, error); /* FIXME use handles */
3293 return_val_if_nok (error, FALSE);
3294 klass->interfaces [i] = mono_class_from_mono_type (iface);
3295 if (!ensure_runtime_vtable (klass->interfaces [i], error))
3296 return FALSE;
3297 }
3298 klass->interfaces_inited = 1;
3299 }
3300 } else if (mono_class_is_ginst (klass)){
3301 if (!ensure_generic_class_runtime_vtable (klass, error)) {
3302 mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
3303 return FALSE;
3304 }
3305 }
3306
3307 if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
3308 int slot_num = 0;
3309 int mcount = mono_class_get_method_count (klass);
3310 for (i = 0; i < mcount; ++i) {
3311 MonoMethod *im = klass->methods [i];
3312 if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
3313 im->slot = slot_num++;
3314 }
3315
3316 klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
3317 mono_class_setup_interface_offsets (klass);
3318 mono_class_setup_interface_id (klass);
3319 }
3320
3321 /*
3322 * The generic vtable is needed even if image->run is not set since some
3323 * runtime code like ves_icall_Type_GetMethodsByName depends on
3324 * method->slot being defined.
3325 */
3326
3327 /*
3328 * tb->methods could not be freed since it is used for determining
3329 * overrides during dynamic vtable construction.
3330 */
3331
3332 return TRUE;
3333 }
3334
3335 static MonoMethod*
mono_reflection_method_get_handle(MonoObject * method,MonoError * error)3336 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
3337 {
3338 error_init (error);
3339 MonoClass *klass = mono_object_class (method);
3340 if (is_sr_mono_method (klass)) {
3341 MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
3342 return sr_method->method;
3343 }
3344 if (is_sre_method_builder (klass)) {
3345 MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
3346 return mb->mhandle;
3347 }
3348 if (mono_is_sre_method_on_tb_inst (klass)) {
3349 MonoClass *handle_class;
3350
3351 MonoMethod *result = mono_reflection_resolve_object (NULL, method, &handle_class, NULL, error);
3352 return_val_if_nok (error, NULL);
3353
3354 return result;
3355 }
3356
3357 g_error ("Can't handle methods of type %s:%s", klass->name_space, klass->name);
3358 return NULL;
3359 }
3360
3361 void
mono_reflection_get_dynamic_overrides(MonoClass * klass,MonoMethod *** overrides,int * num_overrides,MonoError * error)3362 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
3363 {
3364 MonoReflectionTypeBuilder *tb;
3365 int i, j, onum;
3366 MonoReflectionMethod *m;
3367
3368 error_init (error);
3369 *overrides = NULL;
3370 *num_overrides = 0;
3371
3372 g_assert (image_is_dynamic (klass->image));
3373
3374 if (!mono_class_has_ref_info (klass))
3375 return;
3376
3377 tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3378 g_assert (strcmp (mono_object_class (tb)->name, "TypeBuilder") == 0);
3379
3380 onum = 0;
3381 if (tb->methods) {
3382 for (i = 0; i < tb->num_methods; ++i) {
3383 MonoReflectionMethodBuilder *mb =
3384 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3385 if (mb->override_methods)
3386 onum += mono_array_length (mb->override_methods);
3387 }
3388 }
3389
3390 if (onum) {
3391 *overrides = g_new0 (MonoMethod*, onum * 2);
3392
3393 onum = 0;
3394 for (i = 0; i < tb->num_methods; ++i) {
3395 MonoReflectionMethodBuilder *mb =
3396 mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
3397 if (mb->override_methods) {
3398 for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
3399 m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
3400
3401 (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m, error);
3402 return_if_nok (error);
3403 (*overrides) [onum * 2 + 1] = mb->mhandle;
3404
3405 g_assert (mb->mhandle);
3406
3407 onum ++;
3408 }
3409 }
3410 }
3411 }
3412
3413 *num_overrides = onum;
3414 }
3415
3416 /* This initializes the same data as mono_class_setup_fields () */
3417 static void
typebuilder_setup_fields(MonoClass * klass,MonoError * error)3418 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
3419 {
3420 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3421 MonoReflectionFieldBuilder *fb;
3422 MonoClassField *field;
3423 MonoFieldDefaultValue *def_values;
3424 MonoImage *image = klass->image;
3425 const char *p, *p2;
3426 int i, instance_size, packing_size = 0;
3427 guint32 len, idx;
3428
3429 if (klass->parent) {
3430 if (!klass->parent->size_inited)
3431 mono_class_init (klass->parent);
3432 instance_size = klass->parent->instance_size;
3433 } else {
3434 instance_size = sizeof (MonoObject);
3435 }
3436
3437 int fcount = tb->num_fields;
3438 mono_class_set_field_count (klass, fcount);
3439
3440 error_init (error);
3441
3442 if (tb->class_size) {
3443 packing_size = tb->packing_size;
3444 instance_size += tb->class_size;
3445 }
3446
3447 klass->fields = image_g_new0 (image, MonoClassField, fcount);
3448 def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
3449 mono_class_set_field_def_values (klass, def_values);
3450 /*
3451 This is, guess what, a hack.
3452 The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
3453 On the static path no field class is resolved, only types are built. This is the right thing to do
3454 but we suck.
3455 Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
3456 */
3457 klass->size_inited = 1;
3458
3459 for (i = 0; i < fcount; ++i) {
3460 MonoArray *rva_data;
3461 fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
3462 field = &klass->fields [i];
3463 field->parent = klass;
3464 field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
3465 if (!mono_error_ok (error))
3466 return;
3467 if (fb->attrs) {
3468 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3469 return_if_nok (error);
3470 field->type = mono_metadata_type_dup (klass->image, type);
3471 field->type->attrs = fb->attrs;
3472 } else {
3473 field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
3474 return_if_nok (error);
3475 }
3476
3477 if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
3478 mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
3479 continue;
3480 }
3481
3482 if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
3483 char *base = mono_array_addr (rva_data, char, 0);
3484 size_t size = mono_array_length (rva_data);
3485 char *data = (char *)mono_image_alloc (klass->image, size);
3486 memcpy (data, base, size);
3487 def_values [i].data = data;
3488 }
3489 if (fb->offset != -1)
3490 field->offset = fb->offset;
3491 fb->handle = field;
3492 mono_save_custom_attrs (klass->image, field, fb->cattrs);
3493
3494 if (fb->def_value) {
3495 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3496 field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
3497 idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
3498 /* Copy the data from the blob since it might get realloc-ed */
3499 p = assembly->blob.data + idx;
3500 len = mono_metadata_decode_blob_size (p, &p2);
3501 len += p2 - p;
3502 def_values [i].data = (const char *)mono_image_alloc (image, len);
3503 memcpy ((gpointer)def_values [i].data, p, len);
3504 }
3505 }
3506
3507 if (!mono_class_has_failure (klass))
3508 mono_class_layout_fields (klass, instance_size, packing_size, tb->class_size, TRUE);
3509 }
3510
3511 static void
typebuilder_setup_properties(MonoClass * klass,MonoError * error)3512 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
3513 {
3514 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3515 MonoReflectionPropertyBuilder *pb;
3516 MonoImage *image = klass->image;
3517 MonoProperty *properties;
3518 MonoClassPropertyInfo *info;
3519 int i;
3520
3521 error_init (error);
3522
3523 info = mono_class_get_property_info (klass);
3524 if (!info) {
3525 info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo));
3526 mono_class_set_property_info (klass, info);
3527 }
3528
3529 info->count = tb->properties ? mono_array_length (tb->properties) : 0;
3530 info->first = 0;
3531
3532 properties = image_g_new0 (image, MonoProperty, info->count);
3533 info->properties = properties;
3534 for (i = 0; i < info->count; ++i) {
3535 pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
3536 properties [i].parent = klass;
3537 properties [i].attrs = pb->attrs;
3538 properties [i].name = string_to_utf8_image_raw (image, pb->name, error); /* FIXME use handles */
3539 if (!mono_error_ok (error))
3540 return;
3541 if (pb->get_method)
3542 properties [i].get = pb->get_method->mhandle;
3543 if (pb->set_method)
3544 properties [i].set = pb->set_method->mhandle;
3545
3546 mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
3547 if (pb->def_value) {
3548 guint32 len, idx;
3549 const char *p, *p2;
3550 MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
3551 if (!info->def_values)
3552 info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count);
3553 properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
3554 idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->def_values [i].def_type);
3555 /* Copy the data from the blob since it might get realloc-ed */
3556 p = assembly->blob.data + idx;
3557 len = mono_metadata_decode_blob_size (p, &p2);
3558 len += p2 - p;
3559 info->def_values [i].data = (const char *)mono_image_alloc (image, len);
3560 memcpy ((gpointer)info->def_values [i].data, p, len);
3561 }
3562 }
3563 }
3564
3565 static void
typebuilder_setup_events(MonoClass * klass,MonoError * error)3566 typebuilder_setup_events (MonoClass *klass, MonoError *error)
3567 {
3568 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
3569 MonoReflectionEventBuilder *eb;
3570 MonoImage *image = klass->image;
3571 MonoEvent *events;
3572 MonoClassEventInfo *info;
3573 int i;
3574
3575 error_init (error);
3576
3577 info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
3578 mono_class_set_event_info (klass, info);
3579
3580 info->count = tb->events ? mono_array_length (tb->events) : 0;
3581 info->first = 0;
3582
3583 events = image_g_new0 (image, MonoEvent, info->count);
3584 info->events = events;
3585 for (i = 0; i < info->count; ++i) {
3586 eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
3587 events [i].parent = klass;
3588 events [i].attrs = eb->attrs;
3589 events [i].name = string_to_utf8_image_raw (image, eb->name, error); /* FIXME use handles */
3590 if (!mono_error_ok (error))
3591 return;
3592 if (eb->add_method)
3593 events [i].add = eb->add_method->mhandle;
3594 if (eb->remove_method)
3595 events [i].remove = eb->remove_method->mhandle;
3596 if (eb->raise_method)
3597 events [i].raise = eb->raise_method->mhandle;
3598
3599 #ifndef MONO_SMALL_CONFIG
3600 if (eb->other_methods) {
3601 int j;
3602 events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
3603 for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
3604 MonoReflectionMethodBuilder *mb =
3605 mono_array_get (eb->other_methods,
3606 MonoReflectionMethodBuilder*, j);
3607 events [i].other [j] = mb->mhandle;
3608 }
3609 }
3610 #endif
3611 mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
3612 }
3613 }
3614
3615 struct remove_instantiations_user_data
3616 {
3617 MonoClass *klass;
3618 MonoError *error;
3619 };
3620
3621 static gboolean
remove_instantiations_of_and_ensure_contents(gpointer key,gpointer value,gpointer user_data)3622 remove_instantiations_of_and_ensure_contents (gpointer key,
3623 gpointer value,
3624 gpointer user_data)
3625 {
3626 struct remove_instantiations_user_data *data = (struct remove_instantiations_user_data*)user_data;
3627 MonoType *type = (MonoType*)key;
3628 MonoClass *klass = data->klass;
3629 gboolean already_failed = !is_ok (data->error);
3630 MonoError lerror;
3631 MonoError *error = already_failed ? &lerror : data->error;
3632
3633 if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
3634 MonoClass *inst_klass = mono_class_from_mono_type (type);
3635 //Ensure it's safe to use it.
3636 if (!fix_partial_generic_class (inst_klass, error)) {
3637 mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
3638 // Marked the class with failure, but since some other instantiation already failed,
3639 // just report that one, and swallow the error from this one.
3640 if (already_failed)
3641 mono_error_cleanup (error);
3642 }
3643 return TRUE;
3644 } else
3645 return FALSE;
3646 }
3647
3648 /**
3649 * reflection_setup_internal_class:
3650 * @tb: a TypeBuilder object
3651 * @error: set on error
3652 *
3653 * Creates a MonoClass that represents the TypeBuilder.
3654 * This is a trick that lets us simplify a lot of reflection code
3655 * (and will allow us to support Build and Run assemblies easier).
3656 *
3657 * Returns TRUE on success. On failure, returns FALSE and sets @error.
3658 */
3659 static gboolean
reflection_setup_internal_class(MonoReflectionTypeBuilderHandle ref_tb,MonoError * error)3660 reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3661 {
3662 MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
3663 GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
3664
3665 if (unparented_classes) {
3666 return reflection_setup_internal_class_internal (ref_tb, error);
3667 } else {
3668 // If we're not being called recursively
3669 unparented_classes = g_hash_table_new (NULL, NULL);
3670 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
3671
3672 gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
3673 mono_error_assert_ok (error);
3674
3675 // Fix the relationship between the created classes and their parents
3676 reflection_setup_class_hierarchy (unparented_classes, error);
3677 mono_error_assert_ok (error);
3678
3679 g_hash_table_destroy (unparented_classes);
3680 MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
3681
3682 return ret_val;
3683 }
3684 }
3685
3686
3687 MonoReflectionTypeHandle
ves_icall_TypeBuilder_create_runtime_class(MonoReflectionTypeBuilderHandle ref_tb,MonoError * error)3688 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
3689 {
3690 error_init (error);
3691
3692 reflection_setup_internal_class (ref_tb, error);
3693 mono_error_assert_ok (error);
3694
3695 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
3696 MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
3697 MonoClass *klass = mono_class_from_mono_type (type);
3698
3699 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
3700 mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
3701
3702 /*
3703 * we need to lock the domain because the lock will be taken inside
3704 * So, we need to keep the locking order correct.
3705 */
3706 mono_loader_lock ();
3707 mono_domain_lock (domain);
3708 if (klass->wastypebuilder) {
3709 mono_domain_unlock (domain);
3710 mono_loader_unlock ();
3711
3712 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
3713 }
3714 /*
3715 * Fields to set in klass:
3716 * the various flags: delegate/unicode/contextbound etc.
3717 */
3718 mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
3719 klass->has_cctor = 1;
3720
3721 mono_class_setup_parent (klass, klass->parent);
3722 /* fool mono_class_setup_supertypes */
3723 klass->supertypes = NULL;
3724 mono_class_setup_supertypes (klass);
3725 mono_class_setup_mono_type (klass);
3726
3727 /* enums are done right away */
3728 if (!klass->enumtype)
3729 if (!ensure_runtime_vtable (klass, error))
3730 goto failure;
3731
3732 MonoArrayHandle nested_types = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, subtypes);
3733 if (!MONO_HANDLE_IS_NULL (nested_types)) {
3734 GList *nested = NULL;
3735 int num_nested = mono_array_handle_length (nested_types);
3736 MonoReflectionTypeHandle nested_tb = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3737 for (int i = 0; i < num_nested; ++i) {
3738 MONO_HANDLE_ARRAY_GETREF (nested_tb, nested_types, i);
3739
3740 if (MONO_HANDLE_GETVAL (nested_tb, type) == NULL) {
3741 reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, nested_tb), error);
3742 mono_error_assert_ok (error);
3743 }
3744
3745 MonoType *subtype = mono_reflection_type_handle_mono_type (nested_tb, error);
3746 goto_if_nok (error, failure);
3747 nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype));
3748 }
3749 mono_class_set_nested_classes_property (klass, nested);
3750 }
3751
3752 klass->nested_classes_inited = TRUE;
3753
3754 typebuilder_setup_fields (klass, error);
3755 goto_if_nok (error, failure);
3756 typebuilder_setup_properties (klass, error);
3757 goto_if_nok (error, failure);
3758
3759 typebuilder_setup_events (klass, error);
3760 goto_if_nok (error, failure);
3761
3762 klass->wastypebuilder = TRUE;
3763
3764 MonoArrayHandle generic_params = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, generic_params);
3765 if (!MONO_HANDLE_IS_NULL (generic_params)) {
3766 int num_params = mono_array_handle_length (generic_params);
3767 MonoReflectionTypeHandle ref_gparam = MONO_HANDLE_NEW (MonoReflectionType, NULL);
3768 for (int i = 0; i < num_params; i++) {
3769 MONO_HANDLE_ARRAY_GETREF (ref_gparam, generic_params, i);
3770 MonoType *param_type = mono_reflection_type_handle_mono_type (ref_gparam, error);
3771 goto_if_nok (error, failure);
3772 MonoClass *gklass = mono_class_from_mono_type (param_type);
3773
3774 gklass->wastypebuilder = TRUE;
3775 }
3776 }
3777
3778 /*
3779 * If we are a generic TypeBuilder, there might be instantiations in the type cache
3780 * which have type System.Reflection.MonoGenericClass, but after the type is created,
3781 * we want to return normal System.MonoType objects, so clear these out from the cache.
3782 *
3783 * Together with this we must ensure the contents of all instances to match the created type.
3784 */
3785 if (domain->type_hash && mono_class_is_gtd (klass)) {
3786 struct remove_instantiations_user_data data;
3787 data.klass = klass;
3788 data.error = error;
3789 mono_error_assert_ok (error);
3790 mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
3791 goto_if_nok (error, failure);
3792 }
3793
3794 mono_domain_unlock (domain);
3795 mono_loader_unlock ();
3796
3797 if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
3798 mono_class_set_type_load_failure (klass, "Not a valid enumeration");
3799 mono_error_set_type_load_class (error, klass, "Not a valid enumeration");
3800 goto failure_unlocked;
3801 }
3802
3803 MonoReflectionTypeHandle res = mono_type_get_object_handle (domain, &klass->byval_arg, error);
3804 goto_if_nok (error, failure_unlocked);
3805
3806 return res;
3807
3808 failure:
3809 mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
3810 klass->wastypebuilder = TRUE;
3811 mono_domain_unlock (domain);
3812 mono_loader_unlock ();
3813 failure_unlocked:
3814 return NULL;
3815 }
3816
3817 typedef struct {
3818 MonoMethod *handle;
3819 MonoDomain *domain;
3820 } DynamicMethodReleaseData;
3821
3822 /*
3823 * The runtime automatically clean up those after finalization.
3824 */
3825 static MonoReferenceQueue *dynamic_method_queue;
3826
3827 static void
free_dynamic_method(void * dynamic_method)3828 free_dynamic_method (void *dynamic_method)
3829 {
3830 DynamicMethodReleaseData *data = (DynamicMethodReleaseData *)dynamic_method;
3831 MonoDomain *domain = data->domain;
3832 MonoMethod *method = data->handle;
3833 guint32 dis_link;
3834
3835 mono_domain_lock (domain);
3836 dis_link = (guint32)(size_t)g_hash_table_lookup (domain->method_to_dyn_method, method);
3837 g_hash_table_remove (domain->method_to_dyn_method, method);
3838 mono_domain_unlock (domain);
3839 g_assert (dis_link);
3840 mono_gchandle_free (dis_link);
3841
3842 mono_runtime_free_method (domain, method);
3843 g_free (data);
3844 }
3845
3846 static gboolean
reflection_create_dynamic_method(MonoReflectionDynamicMethodHandle ref_mb,MonoError * error)3847 reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, MonoError *error)
3848 {
3849 MonoReferenceQueue *queue;
3850 MonoMethod *handle;
3851 DynamicMethodReleaseData *release_data;
3852 ReflectionMethodBuilder rmb;
3853 MonoMethodSignature *sig;
3854 MonoClass *klass;
3855 MonoDomain *domain;
3856 GSList *l;
3857 int i;
3858
3859 error_init (error);
3860
3861 if (mono_runtime_is_shutting_down ()) {
3862 mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
3863 return FALSE;
3864 }
3865
3866 if (!(queue = dynamic_method_queue)) {
3867 mono_loader_lock ();
3868 if (!(queue = dynamic_method_queue))
3869 queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
3870 mono_loader_unlock ();
3871 }
3872
3873 sig = dynamic_method_to_signature (ref_mb, error);
3874 return_val_if_nok (error, FALSE);
3875
3876 MonoReflectionDynamicMethod *mb = MONO_HANDLE_RAW (ref_mb); /* FIXME convert reflection_create_dynamic_method to use handles */
3877 reflection_methodbuilder_from_dynamic_method (&rmb, mb);
3878
3879 /*
3880 * Resolve references.
3881 */
3882 /*
3883 * Every second entry in the refs array is reserved for storing handle_class,
3884 * which is needed by the ldtoken implementation in the JIT.
3885 */
3886 rmb.nrefs = mb->nrefs;
3887 rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
3888 for (i = 0; i < mb->nrefs; i += 2) {
3889 MonoClass *handle_class;
3890 gpointer ref;
3891 MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
3892
3893 if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
3894 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
3895 /*
3896 * The referenced DynamicMethod should already be created by the managed
3897 * code, except in the case of circular references. In that case, we store
3898 * method in the refs array, and fix it up later when the referenced
3899 * DynamicMethod is created.
3900 */
3901 if (method->mhandle) {
3902 ref = method->mhandle;
3903 } else {
3904 /* FIXME: GC object stored in unmanaged memory */
3905 ref = method;
3906
3907 /* FIXME: GC object stored in unmanaged memory */
3908 method->referenced_by = g_slist_append (method->referenced_by, mb);
3909 }
3910 handle_class = mono_defaults.methodhandle_class;
3911 } else {
3912 MonoException *ex = NULL;
3913 ref = mono_reflection_resolve_object (mb->module->image, obj, &handle_class, NULL, error);
3914 if (!is_ok (error)) {
3915 g_free (rmb.refs);
3916 return FALSE;
3917 }
3918 if (!ref)
3919 ex = mono_get_exception_type_load (NULL, NULL);
3920 else if (mono_security_core_clr_enabled ())
3921 ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
3922
3923 if (ex) {
3924 g_free (rmb.refs);
3925 mono_error_set_exception_instance (error, ex);
3926 return FALSE;
3927 }
3928 }
3929
3930 rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
3931 rmb.refs [i + 1] = handle_class;
3932 }
3933
3934 MonoAssembly *ass = NULL;
3935 if (mb->owner) {
3936 MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
3937 if (!is_ok (error)) {
3938 g_free (rmb.refs);
3939 return FALSE;
3940 }
3941 klass = mono_class_from_mono_type (owner_type);
3942 ass = klass->image->assembly;
3943 } else {
3944 klass = mono_defaults.object_class;
3945 ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
3946 }
3947
3948 mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
3949 ((MonoDynamicMethod*)handle)->assembly = ass;
3950 g_free (rmb.refs);
3951 return_val_if_nok (error, FALSE);
3952
3953 release_data = g_new (DynamicMethodReleaseData, 1);
3954 release_data->handle = handle;
3955 release_data->domain = mono_object_get_domain ((MonoObject*)mb);
3956 if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
3957 g_free (release_data);
3958
3959 /* Fix up refs entries pointing at us */
3960 for (l = mb->referenced_by; l; l = l->next) {
3961 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
3962 MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
3963 gpointer *data;
3964
3965 g_assert (method->mhandle);
3966
3967 data = (gpointer*)wrapper->method_data;
3968 for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
3969 if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
3970 data [i + 1] = mb->mhandle;
3971 }
3972 }
3973 g_slist_free (mb->referenced_by);
3974
3975 /* ilgen is no longer needed */
3976 mb->ilgen = NULL;
3977
3978 domain = mono_domain_get ();
3979 mono_domain_lock (domain);
3980 if (!domain->method_to_dyn_method)
3981 domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
3982 g_hash_table_insert (domain->method_to_dyn_method, handle, (gpointer)(size_t)mono_gchandle_new_weakref ((MonoObject *)mb, TRUE));
3983 mono_domain_unlock (domain);
3984
3985 return TRUE;
3986 }
3987
3988 void
ves_icall_DynamicMethod_create_dynamic_method(MonoReflectionDynamicMethodHandle mb,MonoError * error)3989 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
3990 {
3991 (void) reflection_create_dynamic_method (mb, error);
3992 }
3993
3994 #endif /* DISABLE_REFLECTION_EMIT */
3995
3996 MonoMethodSignature *
mono_reflection_lookup_signature(MonoImage * image,MonoMethod * method,guint32 token,MonoError * error)3997 mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
3998 {
3999 MonoMethodSignature *sig;
4000 g_assert (image_is_dynamic (image));
4001
4002 error_init (error);
4003
4004 sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
4005 if (sig)
4006 return sig;
4007
4008 return mono_method_signature_checked (method, error);
4009 }
4010
4011 #ifndef DISABLE_REFLECTION_EMIT
4012
4013 /*
4014 * ensure_complete_type:
4015 *
4016 * Ensure that KLASS is completed if it is a dynamic type, or references
4017 * dynamic types.
4018 */
4019 static void
ensure_complete_type(MonoClass * klass,MonoError * error)4020 ensure_complete_type (MonoClass *klass, MonoError *error)
4021 {
4022 error_init (error);
4023
4024 if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
4025 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
4026
4027 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4028 return_if_nok (error);
4029
4030 // Asserting here could break a lot of code
4031 //g_assert (klass->wastypebuilder);
4032 }
4033
4034 if (mono_class_is_ginst (klass)) {
4035 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
4036 int i;
4037
4038 for (i = 0; i < inst->type_argc; ++i) {
4039 ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]), error);
4040 return_if_nok (error);
4041 }
4042 }
4043 }
4044
4045 gpointer
mono_reflection_resolve_object(MonoImage * image,MonoObject * obj,MonoClass ** handle_class,MonoGenericContext * context,MonoError * error)4046 mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
4047 {
4048 MonoClass *oklass = obj->vtable->klass;
4049 gpointer result = NULL;
4050
4051 error_init (error);
4052
4053 if (strcmp (oklass->name, "String") == 0) {
4054 result = mono_string_intern_checked ((MonoString*)obj, error);
4055 return_val_if_nok (error, NULL);
4056 *handle_class = mono_defaults.string_class;
4057 g_assert (result);
4058 } else if (strcmp (oklass->name, "RuntimeType") == 0) {
4059 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj, error);
4060 return_val_if_nok (error, NULL);
4061 MonoClass *mc = mono_class_from_mono_type (type);
4062 if (!mono_class_init (mc)) {
4063 mono_error_set_for_class_failure (error, mc);
4064 return NULL;
4065 }
4066
4067 if (context) {
4068 MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, error);
4069 return_val_if_nok (error, NULL);
4070
4071 result = mono_class_from_mono_type (inflated);
4072 mono_metadata_free_type (inflated);
4073 } else {
4074 result = mono_class_from_mono_type (type);
4075 }
4076 *handle_class = mono_defaults.typehandle_class;
4077 g_assert (result);
4078 } else if (strcmp (oklass->name, "MonoMethod") == 0 ||
4079 strcmp (oklass->name, "MonoCMethod") == 0) {
4080 result = ((MonoReflectionMethod*)obj)->method;
4081 if (context) {
4082 result = mono_class_inflate_generic_method_checked ((MonoMethod *)result, context, error);
4083 mono_error_assert_ok (error);
4084 }
4085 *handle_class = mono_defaults.methodhandle_class;
4086 g_assert (result);
4087 } else if (strcmp (oklass->name, "MonoField") == 0) {
4088 MonoClassField *field = ((MonoReflectionField*)obj)->field;
4089
4090 ensure_complete_type (field->parent, error);
4091 return_val_if_nok (error, NULL);
4092
4093 if (context) {
4094 MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, error);
4095 return_val_if_nok (error, NULL);
4096
4097 MonoClass *klass = mono_class_from_mono_type (inflated);
4098 MonoClassField *inflated_field;
4099 gpointer iter = NULL;
4100 mono_metadata_free_type (inflated);
4101 while ((inflated_field = mono_class_get_fields (klass, &iter))) {
4102 if (!strcmp (field->name, inflated_field->name))
4103 break;
4104 }
4105 g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
4106 result = inflated_field;
4107 } else {
4108 result = field;
4109 }
4110 *handle_class = mono_defaults.fieldhandle_class;
4111 g_assert (result);
4112 } else if (strcmp (oklass->name, "TypeBuilder") == 0) {
4113 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
4114 MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)tb, error);
4115 return_val_if_nok (error, NULL);
4116 MonoClass *klass;
4117
4118 klass = type->data.klass;
4119 if (klass->wastypebuilder) {
4120 /* Already created */
4121 result = klass;
4122 }
4123 else {
4124 mono_domain_try_type_resolve_checked (mono_domain_get (), NULL, (MonoObject*)tb, error);
4125 return_val_if_nok (error, NULL);
4126 result = type->data.klass;
4127 g_assert (result);
4128 }
4129 *handle_class = mono_defaults.typehandle_class;
4130 } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
4131 MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
4132 MonoMethodSignature *sig;
4133 int nargs, i;
4134
4135 if (helper->arguments)
4136 nargs = mono_array_length (helper->arguments);
4137 else
4138 nargs = 0;
4139
4140 sig = mono_metadata_signature_alloc (image, nargs);
4141 sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
4142 sig->hasthis = helper->call_conv & 32 ? 1 : 0;
4143
4144 if (helper->unmanaged_call_conv) { /* unmanaged */
4145 sig->call_convention = helper->unmanaged_call_conv - 1;
4146 sig->pinvoke = TRUE;
4147 } else if (helper->call_conv & 0x02) {
4148 sig->call_convention = MONO_CALL_VARARG;
4149 } else {
4150 sig->call_convention = MONO_CALL_DEFAULT;
4151 }
4152
4153 sig->param_count = nargs;
4154 /* TODO: Copy type ? */
4155 sig->ret = helper->return_type->type;
4156 for (i = 0; i < nargs; ++i) {
4157 sig->params [i] = mono_type_array_get_and_resolve_raw (helper->arguments, i, error); /* FIXME use handles */
4158 if (!is_ok (error)) {
4159 image_g_free (image, sig);
4160 return NULL;
4161 }
4162 }
4163
4164 result = sig;
4165 *handle_class = NULL;
4166 } else if (strcmp (oklass->name, "DynamicMethod") == 0) {
4167 MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
4168 /* Already created by the managed code */
4169 g_assert (method->mhandle);
4170 result = method->mhandle;
4171 *handle_class = mono_defaults.methodhandle_class;
4172 } else if (strcmp (oklass->name, "MonoArrayMethod") == 0) {
4173 MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
4174 MonoType *mtype;
4175 MonoClass *klass;
4176 MonoMethod *method;
4177 gpointer iter;
4178 char *name;
4179
4180 mtype = mono_reflection_type_get_handle (m->parent, error);
4181 return_val_if_nok (error, NULL);
4182 klass = mono_class_from_mono_type (mtype);
4183
4184 /* Find the method */
4185
4186 name = mono_string_to_utf8_checked (m->name, error);
4187 return_val_if_nok (error, NULL);
4188 iter = NULL;
4189 while ((method = mono_class_get_methods (klass, &iter))) {
4190 if (!strcmp (method->name, name))
4191 break;
4192 }
4193 g_free (name);
4194
4195 // FIXME:
4196 g_assert (method);
4197 // FIXME: Check parameters/return value etc. match
4198
4199 result = method;
4200 *handle_class = mono_defaults.methodhandle_class;
4201 } else if (is_sre_method_builder (oklass) ||
4202 mono_is_sre_ctor_builder (oklass) ||
4203 is_sre_field_builder (oklass) ||
4204 is_sre_gparam_builder (oklass) ||
4205 is_sre_generic_instance (oklass) ||
4206 is_sre_array (oklass) ||
4207 is_sre_byref (oklass) ||
4208 is_sre_pointer (oklass) ||
4209 !strcmp (oklass->name, "FieldOnTypeBuilderInst") ||
4210 !strcmp (oklass->name, "MethodOnTypeBuilderInst") ||
4211 !strcmp (oklass->name, "ConstructorOnTypeBuilderInst")) {
4212 static MonoMethod *resolve_method;
4213 if (!resolve_method) {
4214 MonoMethod *m = mono_class_get_method_from_name_flags (mono_class_get_module_builder_class (), "RuntimeResolve", 1, 0);
4215 g_assert (m);
4216 mono_memory_barrier ();
4217 resolve_method = m;
4218 }
4219 void *args [16];
4220 args [0] = obj;
4221 obj = mono_runtime_invoke_checked (resolve_method, NULL, args, error);
4222 mono_error_assert_ok (error);
4223 g_assert (obj);
4224 return mono_reflection_resolve_object (image, obj, handle_class, context, error);
4225 } else {
4226 g_print ("%s\n", obj->vtable->klass->name);
4227 g_assert_not_reached ();
4228 }
4229 return result;
4230 }
4231
4232 #else /* DISABLE_REFLECTION_EMIT */
4233
4234 MonoArray*
mono_reflection_get_custom_attrs_blob(MonoReflectionAssembly * assembly,MonoObject * ctor,MonoArray * ctorArgs,MonoArray * properties,MonoArray * propValues,MonoArray * fields,MonoArray * fieldValues)4235 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4236 {
4237 g_assert_not_reached ();
4238 return NULL;
4239 }
4240
4241 void
mono_reflection_dynimage_basic_init(MonoReflectionAssemblyBuilder * assemblyb)4242 mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4243 {
4244 g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
4245 }
4246
4247 static gboolean
mono_image_module_basic_init(MonoReflectionModuleBuilderHandle moduleb,MonoError * error)4248 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4249 {
4250 g_assert_not_reached ();
4251 return FALSE;
4252 }
4253
4254 guint32
mono_image_insert_string(MonoReflectionModuleBuilderHandle module,MonoStringHandle str,MonoError * error)4255 mono_image_insert_string (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4256 {
4257 g_assert_not_reached ();
4258 return 0;
4259 }
4260
4261 guint32
mono_image_create_method_token(MonoDynamicImage * assembly,MonoObjectHandle obj,MonoArrayHandle opt_param_types,MonoError * error)4262 mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj, MonoArrayHandle opt_param_types, MonoError *error)
4263 {
4264 g_assert_not_reached ();
4265 return 0;
4266 }
4267
4268 guint32
mono_image_create_token(MonoDynamicImage * assembly,MonoObjectHandle obj,gboolean create_open_instance,gboolean register_token,MonoError * error)4269 mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
4270 gboolean create_open_instance, gboolean register_token, MonoError *error)
4271 {
4272 g_assert_not_reached ();
4273 return 0;
4274 }
4275
4276 void
mono_reflection_get_dynamic_overrides(MonoClass * klass,MonoMethod *** overrides,int * num_overrides,MonoError * error)4277 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
4278 {
4279 error_init (error);
4280 *overrides = NULL;
4281 *num_overrides = 0;
4282 }
4283
4284 MonoReflectionTypeHandle
ves_icall_TypeBuilder_create_runtime_class(MonoReflectionTypeBuilderHandle tb,MonoError * error)4285 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, MonoError *error)
4286 {
4287 g_assert_not_reached ();
4288 return NULL;
4289 }
4290
4291 void
ves_icall_DynamicMethod_create_dynamic_method(MonoReflectionDynamicMethodHandle mb,MonoError * error)4292 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
4293 {
4294 error_init (error);
4295 }
4296
4297 MonoType*
mono_reflection_type_get_handle(MonoReflectionType * ref,MonoError * error)4298 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
4299 {
4300 error_init (error);
4301 if (!ref)
4302 return NULL;
4303 return ref->type;
4304 }
4305
4306 MonoType*
mono_reflection_type_handle_mono_type(MonoReflectionTypeHandle ref,MonoError * error)4307 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
4308 {
4309 error_init (error);
4310 if (MONO_HANDLE_IS_NULL (ref))
4311 return NULL;
4312 return MONO_HANDLE_GETVAL (ref, type);
4313 }
4314
4315
4316 #endif /* DISABLE_REFLECTION_EMIT */
4317
4318 void
mono_sre_generic_param_table_entry_free(GenericParamTableEntry * entry)4319 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
4320 {
4321 MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
4322 g_free (entry);
4323 }
4324
4325 gint32
ves_icall_ModuleBuilder_getToken(MonoReflectionModuleBuilderHandle mb,MonoObjectHandle obj,gboolean create_open_instance,MonoError * error)4326 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
4327 {
4328 error_init (error);
4329 if (MONO_HANDLE_IS_NULL (obj)) {
4330 mono_error_set_argument_null (error, "obj", "");
4331 return 0;
4332 }
4333 return mono_image_create_token (MONO_HANDLE_GETVAL (mb, dynamic_image), obj, create_open_instance, TRUE, error);
4334 }
4335
4336 gint32
ves_icall_ModuleBuilder_getMethodToken(MonoReflectionModuleBuilderHandle mb,MonoReflectionMethodHandle method,MonoArrayHandle opt_param_types,MonoError * error)4337 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
4338 MonoReflectionMethodHandle method,
4339 MonoArrayHandle opt_param_types,
4340 MonoError *error)
4341 {
4342 error_init (error);
4343 if (MONO_HANDLE_IS_NULL (method)) {
4344 mono_error_set_argument_null (error, "method", "");
4345 return 0;
4346 }
4347
4348 return mono_image_create_method_token (MONO_HANDLE_GETVAL (mb, dynamic_image), MONO_HANDLE_CAST (MonoObject, method), opt_param_types, error);
4349 }
4350
4351 void
ves_icall_ModuleBuilder_WriteToFile(MonoReflectionModuleBuilder * mb,HANDLE file)4352 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
4353 {
4354 MonoError error;
4355 mono_image_create_pefile (mb, file, &error);
4356 mono_error_set_pending_exception (&error);
4357 }
4358
4359 void
ves_icall_ModuleBuilder_build_metadata(MonoReflectionModuleBuilder * mb)4360 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
4361 {
4362 MonoError error;
4363 mono_image_build_metadata (mb, &error);
4364 mono_error_set_pending_exception (&error);
4365 }
4366
4367 void
ves_icall_ModuleBuilder_RegisterToken(MonoReflectionModuleBuilderHandle mb,MonoObjectHandle obj,guint32 token,MonoError * error)4368 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
4369 {
4370 error_init (error);
4371 /* This function may be called by ModuleBuilder.FixupTokens to update
4372 * an existing token, so replace is okay here. */
4373 mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
4374 }
4375
4376 MonoObjectHandle
ves_icall_ModuleBuilder_GetRegisteredToken(MonoReflectionModuleBuilderHandle mb,guint32 token,MonoError * error)4377 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
4378 {
4379 error_init (error);
4380 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4381 return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
4382 }
4383
4384 #ifndef DISABLE_REFLECTION_EMIT
4385 MonoArray*
ves_icall_CustomAttributeBuilder_GetBlob(MonoReflectionAssembly * assembly,MonoObject * ctor,MonoArray * ctorArgs,MonoArray * properties,MonoArray * propValues,MonoArray * fields,MonoArray * fieldValues)4386 ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
4387 {
4388 MonoError error;
4389 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
4390 mono_error_set_pending_exception (&error);
4391 return result;
4392 }
4393 #endif
4394
4395 void
ves_icall_AssemblyBuilder_basic_init(MonoReflectionAssemblyBuilder * assemblyb)4396 ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
4397 {
4398 mono_reflection_dynimage_basic_init (assemblyb);
4399 }
4400
4401 void
ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes(MonoReflectionAssemblyBuilderHandle assemblyb,MonoError * error)4402 ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
4403 {
4404 MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
4405
4406 MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
4407 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
4408 g_assert (assembly);
4409
4410 mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
4411 }
4412
4413 void
ves_icall_EnumBuilder_setup_enum_type(MonoReflectionTypeHandle enumtype,MonoReflectionTypeHandle t,MonoError * error)4414 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
4415 MonoReflectionTypeHandle t,
4416 MonoError *error)
4417 {
4418 error_init (error);
4419 MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
4420 }
4421
4422 void
ves_icall_ModuleBuilder_basic_init(MonoReflectionModuleBuilderHandle moduleb,MonoError * error)4423 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
4424 {
4425 error_init (error);
4426 mono_image_module_basic_init (moduleb, error);
4427 }
4428
4429 guint32
ves_icall_ModuleBuilder_getUSIndex(MonoReflectionModuleBuilderHandle module,MonoStringHandle str,MonoError * error)4430 ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, MonoStringHandle str, MonoError *error)
4431 {
4432 return mono_image_insert_string (module, str, error);
4433 }
4434
4435 void
ves_icall_ModuleBuilder_set_wrappers_type(MonoReflectionModuleBuilderHandle moduleb,MonoReflectionTypeHandle ref_type,MonoError * error)4436 ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
4437 {
4438 error_init (error);
4439 MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
4440 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4441
4442 g_assert (type);
4443 image->wrappers_type = mono_class_from_mono_type (type);
4444 }
4445