1 /*************************************************************************/
2 /*  gd_mono_field.cpp                                                    */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "gd_mono_field.h"
32 
33 #include <mono/metadata/attrdefs.h>
34 
35 #include "gd_mono_cache.h"
36 #include "gd_mono_class.h"
37 #include "gd_mono_marshal.h"
38 #include "gd_mono_utils.h"
39 
set_value_raw(MonoObject * p_object,void * p_ptr)40 void GDMonoField::set_value_raw(MonoObject *p_object, void *p_ptr) {
41 	mono_field_set_value(p_object, mono_field, &p_ptr);
42 }
43 
set_value_from_variant(MonoObject * p_object,const Variant & p_value)44 void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_value) {
45 #define SET_FROM_STRUCT(m_type)                                                               \
46 	{                                                                                         \
47 		GDMonoMarshal::M_##m_type from = MARSHALLED_OUT(m_type, p_value.operator ::m_type()); \
48 		mono_field_set_value(p_object, mono_field, &from);                                    \
49 	}
50 
51 #define SET_FROM_ARRAY(m_type)                                                                   \
52 	{                                                                                            \
53 		MonoArray *managed = GDMonoMarshal::m_type##_to_mono_array(p_value.operator ::m_type()); \
54 		mono_field_set_value(p_object, mono_field, managed);                                     \
55 	}
56 
57 	switch (type.type_encoding) {
58 		case MONO_TYPE_BOOLEAN: {
59 			MonoBoolean val = p_value.operator bool();
60 			mono_field_set_value(p_object, mono_field, &val);
61 		} break;
62 
63 		case MONO_TYPE_CHAR: {
64 			int16_t val = p_value.operator unsigned short();
65 			mono_field_set_value(p_object, mono_field, &val);
66 		} break;
67 
68 		case MONO_TYPE_I1: {
69 			int8_t val = p_value.operator signed char();
70 			mono_field_set_value(p_object, mono_field, &val);
71 		} break;
72 		case MONO_TYPE_I2: {
73 			int16_t val = p_value.operator signed short();
74 			mono_field_set_value(p_object, mono_field, &val);
75 		} break;
76 		case MONO_TYPE_I4: {
77 			int32_t val = p_value.operator signed int();
78 			mono_field_set_value(p_object, mono_field, &val);
79 		} break;
80 		case MONO_TYPE_I8: {
81 			int64_t val = p_value.operator int64_t();
82 			mono_field_set_value(p_object, mono_field, &val);
83 		} break;
84 
85 		case MONO_TYPE_U1: {
86 			uint8_t val = p_value.operator unsigned char();
87 			mono_field_set_value(p_object, mono_field, &val);
88 		} break;
89 		case MONO_TYPE_U2: {
90 			uint16_t val = p_value.operator unsigned short();
91 			mono_field_set_value(p_object, mono_field, &val);
92 		} break;
93 		case MONO_TYPE_U4: {
94 			uint32_t val = p_value.operator unsigned int();
95 			mono_field_set_value(p_object, mono_field, &val);
96 		} break;
97 		case MONO_TYPE_U8: {
98 			uint64_t val = p_value.operator uint64_t();
99 			mono_field_set_value(p_object, mono_field, &val);
100 		} break;
101 
102 		case MONO_TYPE_R4: {
103 			float val = p_value.operator float();
104 			mono_field_set_value(p_object, mono_field, &val);
105 		} break;
106 
107 		case MONO_TYPE_R8: {
108 			double val = p_value.operator double();
109 			mono_field_set_value(p_object, mono_field, &val);
110 		} break;
111 
112 		case MONO_TYPE_STRING: {
113 			if (p_value.get_type() == Variant::NIL) {
114 				// Otherwise, Variant -> String would return the string "Null"
115 				MonoString *mono_string = NULL;
116 				mono_field_set_value(p_object, mono_field, mono_string);
117 			} else {
118 				MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
119 				mono_field_set_value(p_object, mono_field, mono_string);
120 			}
121 		} break;
122 
123 		case MONO_TYPE_VALUETYPE: {
124 			GDMonoClass *tclass = type.type_class;
125 
126 			if (tclass == CACHED_CLASS(Vector2)) {
127 				SET_FROM_STRUCT(Vector2);
128 				break;
129 			}
130 
131 			if (tclass == CACHED_CLASS(Rect2)) {
132 				SET_FROM_STRUCT(Rect2);
133 				break;
134 			}
135 
136 			if (tclass == CACHED_CLASS(Transform2D)) {
137 				SET_FROM_STRUCT(Transform2D);
138 				break;
139 			}
140 
141 			if (tclass == CACHED_CLASS(Vector3)) {
142 				SET_FROM_STRUCT(Vector3);
143 				break;
144 			}
145 
146 			if (tclass == CACHED_CLASS(Basis)) {
147 				SET_FROM_STRUCT(Basis);
148 				break;
149 			}
150 
151 			if (tclass == CACHED_CLASS(Quat)) {
152 				SET_FROM_STRUCT(Quat);
153 				break;
154 			}
155 
156 			if (tclass == CACHED_CLASS(Transform)) {
157 				SET_FROM_STRUCT(Transform);
158 				break;
159 			}
160 
161 			if (tclass == CACHED_CLASS(AABB)) {
162 				SET_FROM_STRUCT(AABB);
163 				break;
164 			}
165 
166 			if (tclass == CACHED_CLASS(Color)) {
167 				SET_FROM_STRUCT(Color);
168 				break;
169 			}
170 
171 			if (tclass == CACHED_CLASS(Plane)) {
172 				SET_FROM_STRUCT(Plane);
173 				break;
174 			}
175 
176 			if (mono_class_is_enum(tclass->get_mono_ptr())) {
177 				MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr());
178 				switch (mono_type_get_type(enum_basetype)) {
179 					case MONO_TYPE_BOOLEAN: {
180 						MonoBoolean val = p_value.operator bool();
181 						mono_field_set_value(p_object, mono_field, &val);
182 						break;
183 					}
184 					case MONO_TYPE_CHAR: {
185 						uint16_t val = p_value.operator unsigned short();
186 						mono_field_set_value(p_object, mono_field, &val);
187 						break;
188 					}
189 					case MONO_TYPE_I1: {
190 						int8_t val = p_value.operator signed char();
191 						mono_field_set_value(p_object, mono_field, &val);
192 						break;
193 					}
194 					case MONO_TYPE_I2: {
195 						int16_t val = p_value.operator signed short();
196 						mono_field_set_value(p_object, mono_field, &val);
197 						break;
198 					}
199 					case MONO_TYPE_I4: {
200 						int32_t val = p_value.operator signed int();
201 						mono_field_set_value(p_object, mono_field, &val);
202 						break;
203 					}
204 					case MONO_TYPE_I8: {
205 						int64_t val = p_value.operator int64_t();
206 						mono_field_set_value(p_object, mono_field, &val);
207 						break;
208 					}
209 					case MONO_TYPE_U1: {
210 						uint8_t val = p_value.operator unsigned char();
211 						mono_field_set_value(p_object, mono_field, &val);
212 						break;
213 					}
214 					case MONO_TYPE_U2: {
215 						uint16_t val = p_value.operator unsigned short();
216 						mono_field_set_value(p_object, mono_field, &val);
217 						break;
218 					}
219 					case MONO_TYPE_U4: {
220 						uint32_t val = p_value.operator unsigned int();
221 						mono_field_set_value(p_object, mono_field, &val);
222 						break;
223 					}
224 					case MONO_TYPE_U8: {
225 						uint64_t val = p_value.operator uint64_t();
226 						mono_field_set_value(p_object, mono_field, &val);
227 						break;
228 					}
229 					default: {
230 						ERR_FAIL_MSG("Attempted to convert Variant to a managed enum value of unmarshallable base type.");
231 					}
232 				}
233 
234 				break;
235 			}
236 
237 			ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + tclass->get_name() + "'.");
238 		} break;
239 
240 		case MONO_TYPE_ARRAY:
241 		case MONO_TYPE_SZARRAY: {
242 			MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type());
243 
244 			if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
245 				SET_FROM_ARRAY(Array);
246 				break;
247 			}
248 
249 			if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
250 				SET_FROM_ARRAY(PoolByteArray);
251 				break;
252 			}
253 
254 			if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
255 				SET_FROM_ARRAY(PoolIntArray);
256 				break;
257 			}
258 
259 			if (array_type->eklass == REAL_T_MONOCLASS) {
260 				SET_FROM_ARRAY(PoolRealArray);
261 				break;
262 			}
263 
264 			if (array_type->eklass == CACHED_CLASS_RAW(String)) {
265 				SET_FROM_ARRAY(PoolStringArray);
266 				break;
267 			}
268 
269 			if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
270 				SET_FROM_ARRAY(PoolVector2Array);
271 				break;
272 			}
273 
274 			if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
275 				SET_FROM_ARRAY(PoolVector3Array);
276 				break;
277 			}
278 
279 			if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
280 				SET_FROM_ARRAY(PoolColorArray);
281 				break;
282 			}
283 
284 			GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
285 			if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
286 				MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
287 				mono_field_set_value(p_object, mono_field, managed);
288 				break;
289 			}
290 
291 			ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
292 		} break;
293 
294 		case MONO_TYPE_CLASS: {
295 			GDMonoClass *type_class = type.type_class;
296 
297 			// GodotObject
298 			if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
299 				MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
300 				mono_field_set_value(p_object, mono_field, managed);
301 				break;
302 			}
303 
304 			if (CACHED_CLASS(NodePath) == type_class) {
305 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
306 				mono_field_set_value(p_object, mono_field, managed);
307 				break;
308 			}
309 
310 			if (CACHED_CLASS(RID) == type_class) {
311 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
312 				mono_field_set_value(p_object, mono_field, managed);
313 				break;
314 			}
315 
316 			// Godot.Collections.Dictionary or IDictionary
317 			if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) {
318 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
319 				mono_field_set_value(p_object, mono_field, managed);
320 				break;
321 			}
322 
323 			// Godot.Collections.Array or ICollection or IEnumerable
324 			if (CACHED_CLASS(Array) == type_class ||
325 					type_class == CACHED_CLASS(System_Collections_ICollection) ||
326 					type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
327 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
328 				mono_field_set_value(p_object, mono_field, managed);
329 				break;
330 			}
331 
332 			ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
333 		} break;
334 
335 		case MONO_TYPE_OBJECT: {
336 			// Variant
337 			switch (p_value.get_type()) {
338 				case Variant::BOOL: {
339 					MonoBoolean val = p_value.operator bool();
340 					mono_field_set_value(p_object, mono_field, &val);
341 				} break;
342 				case Variant::INT: {
343 					int32_t val = p_value.operator signed int();
344 					mono_field_set_value(p_object, mono_field, &val);
345 				} break;
346 				case Variant::REAL: {
347 #ifdef REAL_T_IS_DOUBLE
348 					double val = p_value.operator double();
349 					mono_field_set_value(p_object, mono_field, &val);
350 #else
351 					float val = p_value.operator float();
352 					mono_field_set_value(p_object, mono_field, &val);
353 #endif
354 				} break;
355 				case Variant::STRING: {
356 					MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
357 					mono_field_set_value(p_object, mono_field, mono_string);
358 				} break;
359 				case Variant::VECTOR2: {
360 					SET_FROM_STRUCT(Vector2);
361 				} break;
362 				case Variant::RECT2: {
363 					SET_FROM_STRUCT(Rect2);
364 				} break;
365 				case Variant::VECTOR3: {
366 					SET_FROM_STRUCT(Vector3);
367 				} break;
368 				case Variant::TRANSFORM2D: {
369 					SET_FROM_STRUCT(Transform2D);
370 				} break;
371 				case Variant::PLANE: {
372 					SET_FROM_STRUCT(Plane);
373 				} break;
374 				case Variant::QUAT: {
375 					SET_FROM_STRUCT(Quat);
376 				} break;
377 				case Variant::AABB: {
378 					SET_FROM_STRUCT(AABB);
379 				} break;
380 				case Variant::BASIS: {
381 					SET_FROM_STRUCT(Basis);
382 				} break;
383 				case Variant::TRANSFORM: {
384 					SET_FROM_STRUCT(Transform);
385 				} break;
386 				case Variant::COLOR: {
387 					SET_FROM_STRUCT(Color);
388 				} break;
389 				case Variant::NODE_PATH: {
390 					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
391 					mono_field_set_value(p_object, mono_field, managed);
392 				} break;
393 				case Variant::_RID: {
394 					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
395 					mono_field_set_value(p_object, mono_field, managed);
396 				} break;
397 				case Variant::OBJECT: {
398 					MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
399 					mono_field_set_value(p_object, mono_field, managed);
400 					break;
401 				}
402 				case Variant::DICTIONARY: {
403 					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
404 					mono_field_set_value(p_object, mono_field, managed);
405 				} break;
406 				case Variant::ARRAY: {
407 					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
408 					mono_field_set_value(p_object, mono_field, managed);
409 				} break;
410 				case Variant::POOL_BYTE_ARRAY: {
411 					SET_FROM_ARRAY(PoolByteArray);
412 				} break;
413 				case Variant::POOL_INT_ARRAY: {
414 					SET_FROM_ARRAY(PoolIntArray);
415 				} break;
416 				case Variant::POOL_REAL_ARRAY: {
417 					SET_FROM_ARRAY(PoolRealArray);
418 				} break;
419 				case Variant::POOL_STRING_ARRAY: {
420 					SET_FROM_ARRAY(PoolStringArray);
421 				} break;
422 				case Variant::POOL_VECTOR2_ARRAY: {
423 					SET_FROM_ARRAY(PoolVector2Array);
424 				} break;
425 				case Variant::POOL_VECTOR3_ARRAY: {
426 					SET_FROM_ARRAY(PoolVector3Array);
427 				} break;
428 				case Variant::POOL_COLOR_ARRAY: {
429 					SET_FROM_ARRAY(PoolColorArray);
430 				} break;
431 				default: break;
432 			}
433 		} break;
434 
435 		case MONO_TYPE_GENERICINST: {
436 			MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type());
437 
438 			// Godot.Collections.Dictionary<TKey, TValue>
439 			if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
440 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
441 				mono_field_set_value(p_object, mono_field, managed);
442 				break;
443 			}
444 
445 			// Godot.Collections.Array<T>
446 			if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
447 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
448 				mono_field_set_value(p_object, mono_field, managed);
449 				break;
450 			}
451 
452 			// System.Collections.Generic.Dictionary<TKey, TValue>
453 			if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
454 				MonoReflectionType *key_reftype = nullptr;
455 				MonoReflectionType *value_reftype = nullptr;
456 				GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
457 				MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(),
458 						type.type_class, key_reftype, value_reftype);
459 				mono_field_set_value(p_object, mono_field, managed);
460 				break;
461 			}
462 
463 			// System.Collections.Generic.List<T>
464 			if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
465 				MonoReflectionType *elem_reftype = nullptr;
466 				GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
467 				MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(),
468 						type.type_class, elem_reftype);
469 				mono_field_set_value(p_object, mono_field, managed);
470 				break;
471 			}
472 
473 			// IDictionary<TKey, TValue>
474 			if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
475 				MonoReflectionType *key_reftype;
476 				MonoReflectionType *value_reftype;
477 				GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
478 				GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
479 
480 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class);
481 				mono_field_set_value(p_object, mono_field, managed);
482 				break;
483 			}
484 
485 			// ICollection<T> or IEnumerable<T>
486 			if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
487 				MonoReflectionType *elem_reftype;
488 				GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
489 				GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
490 
491 				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class);
492 				mono_field_set_value(p_object, mono_field, managed);
493 				break;
494 			}
495 		} break;
496 
497 		default: {
498 			ERR_PRINTS("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + ".");
499 		} break;
500 	}
501 
502 #undef SET_FROM_ARRAY_AND_BREAK
503 #undef SET_FROM_STRUCT_AND_BREAK
504 }
505 
get_value(MonoObject * p_object)506 MonoObject *GDMonoField::get_value(MonoObject *p_object) {
507 	return mono_field_get_value_object(mono_domain_get(), mono_field, p_object);
508 }
509 
get_bool_value(MonoObject * p_object)510 bool GDMonoField::get_bool_value(MonoObject *p_object) {
511 	return (bool)GDMonoMarshal::unbox<MonoBoolean>(get_value(p_object));
512 }
513 
get_int_value(MonoObject * p_object)514 int GDMonoField::get_int_value(MonoObject *p_object) {
515 	return GDMonoMarshal::unbox<int32_t>(get_value(p_object));
516 }
517 
get_string_value(MonoObject * p_object)518 String GDMonoField::get_string_value(MonoObject *p_object) {
519 	MonoObject *val = get_value(p_object);
520 	return GDMonoMarshal::mono_string_to_godot((MonoString *)val);
521 }
522 
has_attribute(GDMonoClass * p_attr_class)523 bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) {
524 	ERR_FAIL_NULL_V(p_attr_class, false);
525 
526 	if (!attrs_fetched)
527 		fetch_attributes();
528 
529 	if (!attributes)
530 		return false;
531 
532 	return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
533 }
534 
get_attribute(GDMonoClass * p_attr_class)535 MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) {
536 	ERR_FAIL_NULL_V(p_attr_class, NULL);
537 
538 	if (!attrs_fetched)
539 		fetch_attributes();
540 
541 	if (!attributes)
542 		return NULL;
543 
544 	return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
545 }
546 
fetch_attributes()547 void GDMonoField::fetch_attributes() {
548 	ERR_FAIL_COND(attributes != NULL);
549 	attributes = mono_custom_attrs_from_field(owner->get_mono_ptr(), mono_field);
550 	attrs_fetched = true;
551 }
552 
is_static()553 bool GDMonoField::is_static() {
554 	return mono_field_get_flags(mono_field) & MONO_FIELD_ATTR_STATIC;
555 }
556 
get_visibility()557 IMonoClassMember::Visibility GDMonoField::get_visibility() {
558 	switch (mono_field_get_flags(mono_field) & MONO_FIELD_ATTR_FIELD_ACCESS_MASK) {
559 		case MONO_FIELD_ATTR_PRIVATE:
560 			return IMonoClassMember::PRIVATE;
561 		case MONO_FIELD_ATTR_FAM_AND_ASSEM:
562 			return IMonoClassMember::PROTECTED_AND_INTERNAL;
563 		case MONO_FIELD_ATTR_ASSEMBLY:
564 			return IMonoClassMember::INTERNAL;
565 		case MONO_FIELD_ATTR_FAMILY:
566 			return IMonoClassMember::PROTECTED;
567 		case MONO_FIELD_ATTR_PUBLIC:
568 			return IMonoClassMember::PUBLIC;
569 		default:
570 			ERR_FAIL_V(IMonoClassMember::PRIVATE);
571 	}
572 }
573 
GDMonoField(MonoClassField * p_mono_field,GDMonoClass * p_owner)574 GDMonoField::GDMonoField(MonoClassField *p_mono_field, GDMonoClass *p_owner) {
575 	owner = p_owner;
576 	mono_field = p_mono_field;
577 	name = mono_field_get_name(mono_field);
578 	MonoType *field_type = mono_field_get_type(mono_field);
579 	type.type_encoding = mono_type_get_type(field_type);
580 	MonoClass *field_type_class = mono_class_from_mono_type(field_type);
581 	type.type_class = GDMono::get_singleton()->get_class(field_type_class);
582 
583 	attrs_fetched = false;
584 	attributes = NULL;
585 }
586 
~GDMonoField()587 GDMonoField::~GDMonoField() {
588 	if (attributes) {
589 		mono_custom_attrs_free(attributes);
590 	}
591 }
592