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