PageRenderTime 72ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 2ms

/mono/metadata/icall.c

https://bitbucket.org/danipen/mono
C | 8423 lines | 6671 code | 1380 blank | 372 comment | 1506 complexity | c832cf30aabe58006a1dd66b6c1be0bc MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * icall.c:
  3. *
  4. * Authors:
  5. * Dietmar Maurer (dietmar@ximian.com)
  6. * Paolo Molaro (lupus@ximian.com)
  7. * Patrik Torstensson (patrik.torstensson@labs2.com)
  8. *
  9. * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  10. * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  11. * Copyright 2011-2012 Xamarin Inc (http://www.xamarin.com).
  12. */
  13. #include <config.h>
  14. #include <glib.h>
  15. #include <stdarg.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #ifdef HAVE_ALLOCA_H
  19. #include <alloca.h>
  20. #endif
  21. #ifdef HAVE_SYS_TIME_H
  22. #include <sys/time.h>
  23. #endif
  24. #ifdef HAVE_UNISTD_H
  25. #include <unistd.h>
  26. #endif
  27. #if defined (HOST_WIN32)
  28. #include <stdlib.h>
  29. #endif
  30. #if defined (HAVE_WCHAR_H)
  31. #include <wchar.h>
  32. #endif
  33. #include "mono/utils/mono-membar.h"
  34. #include <mono/metadata/object.h>
  35. #include <mono/metadata/threads.h>
  36. #include <mono/metadata/threads-types.h>
  37. #include <mono/metadata/threadpool.h>
  38. #include <mono/metadata/monitor.h>
  39. #include <mono/metadata/reflection.h>
  40. #include <mono/metadata/assembly.h>
  41. #include <mono/metadata/tabledefs.h>
  42. #include <mono/metadata/exception.h>
  43. #include <mono/metadata/file-io.h>
  44. #include <mono/metadata/console-io.h>
  45. #include <mono/metadata/socket-io.h>
  46. #include <mono/metadata/mono-endian.h>
  47. #include <mono/metadata/tokentype.h>
  48. #include <mono/metadata/domain-internals.h>
  49. #include <mono/metadata/metadata-internals.h>
  50. #include <mono/metadata/class-internals.h>
  51. #include <mono/metadata/marshal.h>
  52. #include <mono/metadata/gc-internal.h>
  53. #include <mono/metadata/mono-gc.h>
  54. #include <mono/metadata/rand.h>
  55. #include <mono/metadata/sysmath.h>
  56. #include <mono/metadata/string-icalls.h>
  57. #include <mono/metadata/debug-helpers.h>
  58. #include <mono/metadata/process.h>
  59. #include <mono/metadata/environment.h>
  60. #include <mono/metadata/profiler-private.h>
  61. #include <mono/metadata/locales.h>
  62. #include <mono/metadata/filewatcher.h>
  63. #include <mono/metadata/char-conversions.h>
  64. #include <mono/metadata/security.h>
  65. #include <mono/metadata/mono-config.h>
  66. #include <mono/metadata/cil-coff.h>
  67. #include <mono/metadata/number-formatter.h>
  68. #include <mono/metadata/security-manager.h>
  69. #include <mono/metadata/security-core-clr.h>
  70. #include <mono/metadata/mono-perfcounters.h>
  71. #include <mono/metadata/mono-debug.h>
  72. #include <mono/metadata/mono-ptr-array.h>
  73. #include <mono/metadata/verify-internals.h>
  74. #include <mono/io-layer/io-layer.h>
  75. #include <mono/utils/strtod.h>
  76. #include <mono/utils/monobitset.h>
  77. #include <mono/utils/mono-time.h>
  78. #include <mono/utils/mono-proclib.h>
  79. #include <mono/utils/mono-string.h>
  80. #include <mono/utils/mono-error-internals.h>
  81. #include <mono/utils/mono-mmap.h>
  82. #include <mono/utils/mono-io-portability.h>
  83. #include <mono/utils/mono-digest.h>
  84. #if defined (HOST_WIN32)
  85. #include <windows.h>
  86. #include <shlobj.h>
  87. #endif
  88. #include "decimal.h"
  89. extern MonoString* ves_icall_System_Environment_GetOSVersionString (void) MONO_INTERNAL;
  90. ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
  91. static MonoArray*
  92. type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
  93. static inline MonoBoolean
  94. is_generic_parameter (MonoType *type)
  95. {
  96. return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
  97. }
  98. static void
  99. mono_class_init_or_throw (MonoClass *klass)
  100. {
  101. if (!mono_class_init (klass))
  102. mono_raise_exception (mono_class_get_exception_for_failure (klass));
  103. }
  104. /*
  105. * We expect a pointer to a char, not a string
  106. */
  107. ICALL_EXPORT gboolean
  108. mono_double_ParseImpl (char *ptr, double *result)
  109. {
  110. gchar *endptr = NULL;
  111. *result = 0.0;
  112. MONO_ARCH_SAVE_REGS;
  113. #ifdef __arm__
  114. if (*ptr)
  115. *result = strtod (ptr, &endptr);
  116. #else
  117. if (*ptr){
  118. /* mono_strtod () is not thread-safe */
  119. EnterCriticalSection (&mono_strtod_mutex);
  120. *result = mono_strtod (ptr, &endptr);
  121. LeaveCriticalSection (&mono_strtod_mutex);
  122. }
  123. #endif
  124. if (!*ptr || (endptr && *endptr))
  125. return FALSE;
  126. return TRUE;
  127. }
  128. ICALL_EXPORT MonoObject *
  129. ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
  130. {
  131. MonoClass *ac;
  132. MonoArray *ao;
  133. gint32 esize;
  134. gpointer *ea;
  135. MONO_ARCH_SAVE_REGS;
  136. ao = (MonoArray *)this;
  137. ac = (MonoClass *)ao->obj.vtable->klass;
  138. esize = mono_array_element_size (ac);
  139. ea = (gpointer*)((char*)ao->vector + (pos * esize));
  140. if (ac->element_class->valuetype)
  141. return mono_value_box (this->vtable->domain, ac->element_class, ea);
  142. else
  143. return *ea;
  144. }
  145. ICALL_EXPORT MonoObject *
  146. ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
  147. {
  148. MonoClass *ac, *ic;
  149. MonoArray *ao, *io;
  150. gint32 i, pos, *ind;
  151. MONO_ARCH_SAVE_REGS;
  152. MONO_CHECK_ARG_NULL (idxs);
  153. io = (MonoArray *)idxs;
  154. ic = (MonoClass *)io->obj.vtable->klass;
  155. ao = (MonoArray *)this;
  156. ac = (MonoClass *)ao->obj.vtable->klass;
  157. g_assert (ic->rank == 1);
  158. if (io->bounds != NULL || io->max_length != ac->rank)
  159. mono_raise_exception (mono_get_exception_argument (NULL, NULL));
  160. ind = (gint32 *)io->vector;
  161. if (ao->bounds == NULL) {
  162. if (*ind < 0 || *ind >= ao->max_length)
  163. mono_raise_exception (mono_get_exception_index_out_of_range ());
  164. return ves_icall_System_Array_GetValueImpl (this, *ind);
  165. }
  166. for (i = 0; i < ac->rank; i++)
  167. if ((ind [i] < ao->bounds [i].lower_bound) ||
  168. (ind [i] >= (mono_array_lower_bound_t)ao->bounds [i].length + ao->bounds [i].lower_bound))
  169. mono_raise_exception (mono_get_exception_index_out_of_range ());
  170. pos = ind [0] - ao->bounds [0].lower_bound;
  171. for (i = 1; i < ac->rank; i++)
  172. pos = pos*ao->bounds [i].length + ind [i] -
  173. ao->bounds [i].lower_bound;
  174. return ves_icall_System_Array_GetValueImpl (this, pos);
  175. }
  176. ICALL_EXPORT void
  177. ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
  178. {
  179. MonoClass *ac, *vc, *ec;
  180. gint32 esize, vsize;
  181. gpointer *ea, *va;
  182. int et, vt;
  183. guint64 u64 = 0;
  184. gint64 i64 = 0;
  185. gdouble r64 = 0;
  186. MONO_ARCH_SAVE_REGS;
  187. if (value)
  188. vc = value->vtable->klass;
  189. else
  190. vc = NULL;
  191. ac = this->obj.vtable->klass;
  192. ec = ac->element_class;
  193. esize = mono_array_element_size (ac);
  194. ea = (gpointer*)((char*)this->vector + (pos * esize));
  195. va = (gpointer*)((char*)value + sizeof (MonoObject));
  196. if (mono_class_is_nullable (ec)) {
  197. mono_nullable_init ((guint8*)ea, value, ec);
  198. return;
  199. }
  200. if (!value) {
  201. mono_gc_bzero (ea, esize);
  202. return;
  203. }
  204. #define NO_WIDENING_CONVERSION G_STMT_START{\
  205. mono_raise_exception (mono_get_exception_argument ( \
  206. "value", "not a widening conversion")); \
  207. }G_STMT_END
  208. #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
  209. if (esize < vsize + (extra)) \
  210. mono_raise_exception (mono_get_exception_argument ( \
  211. "value", "not a widening conversion")); \
  212. }G_STMT_END
  213. #define INVALID_CAST G_STMT_START{ \
  214. mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
  215. mono_raise_exception (mono_get_exception_invalid_cast ()); \
  216. }G_STMT_END
  217. /* Check element (destination) type. */
  218. switch (ec->byval_arg.type) {
  219. case MONO_TYPE_STRING:
  220. switch (vc->byval_arg.type) {
  221. case MONO_TYPE_STRING:
  222. break;
  223. default:
  224. INVALID_CAST;
  225. }
  226. break;
  227. case MONO_TYPE_BOOLEAN:
  228. switch (vc->byval_arg.type) {
  229. case MONO_TYPE_BOOLEAN:
  230. break;
  231. case MONO_TYPE_CHAR:
  232. case MONO_TYPE_U1:
  233. case MONO_TYPE_U2:
  234. case MONO_TYPE_U4:
  235. case MONO_TYPE_U8:
  236. case MONO_TYPE_I1:
  237. case MONO_TYPE_I2:
  238. case MONO_TYPE_I4:
  239. case MONO_TYPE_I8:
  240. case MONO_TYPE_R4:
  241. case MONO_TYPE_R8:
  242. NO_WIDENING_CONVERSION;
  243. default:
  244. INVALID_CAST;
  245. }
  246. break;
  247. }
  248. if (!ec->valuetype) {
  249. if (!mono_object_isinst (value, ec))
  250. INVALID_CAST;
  251. mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
  252. return;
  253. }
  254. if (mono_object_isinst (value, ec)) {
  255. if (ec->has_references)
  256. mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
  257. else
  258. mono_gc_memmove (ea, (char *)value + sizeof (MonoObject), esize);
  259. return;
  260. }
  261. if (!vc->valuetype)
  262. INVALID_CAST;
  263. vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
  264. et = ec->byval_arg.type;
  265. if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
  266. et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
  267. vt = vc->byval_arg.type;
  268. if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
  269. vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
  270. #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
  271. switch (vt) { \
  272. case MONO_TYPE_U1: \
  273. case MONO_TYPE_U2: \
  274. case MONO_TYPE_U4: \
  275. case MONO_TYPE_U8: \
  276. case MONO_TYPE_CHAR: \
  277. CHECK_WIDENING_CONVERSION(0); \
  278. *(etype *) ea = (etype) u64; \
  279. return; \
  280. /* You can't assign a signed value to an unsigned array. */ \
  281. case MONO_TYPE_I1: \
  282. case MONO_TYPE_I2: \
  283. case MONO_TYPE_I4: \
  284. case MONO_TYPE_I8: \
  285. /* You can't assign a floating point number to an integer array. */ \
  286. case MONO_TYPE_R4: \
  287. case MONO_TYPE_R8: \
  288. NO_WIDENING_CONVERSION; \
  289. } \
  290. }G_STMT_END
  291. #define ASSIGN_SIGNED(etype) G_STMT_START{\
  292. switch (vt) { \
  293. case MONO_TYPE_I1: \
  294. case MONO_TYPE_I2: \
  295. case MONO_TYPE_I4: \
  296. case MONO_TYPE_I8: \
  297. CHECK_WIDENING_CONVERSION(0); \
  298. *(etype *) ea = (etype) i64; \
  299. return; \
  300. /* You can assign an unsigned value to a signed array if the array's */ \
  301. /* element size is larger than the value size. */ \
  302. case MONO_TYPE_U1: \
  303. case MONO_TYPE_U2: \
  304. case MONO_TYPE_U4: \
  305. case MONO_TYPE_U8: \
  306. case MONO_TYPE_CHAR: \
  307. CHECK_WIDENING_CONVERSION(1); \
  308. *(etype *) ea = (etype) u64; \
  309. return; \
  310. /* You can't assign a floating point number to an integer array. */ \
  311. case MONO_TYPE_R4: \
  312. case MONO_TYPE_R8: \
  313. NO_WIDENING_CONVERSION; \
  314. } \
  315. }G_STMT_END
  316. #define ASSIGN_REAL(etype) G_STMT_START{\
  317. switch (vt) { \
  318. case MONO_TYPE_R4: \
  319. case MONO_TYPE_R8: \
  320. CHECK_WIDENING_CONVERSION(0); \
  321. *(etype *) ea = (etype) r64; \
  322. return; \
  323. /* All integer values fit into a floating point array, so we don't */ \
  324. /* need to CHECK_WIDENING_CONVERSION here. */ \
  325. case MONO_TYPE_I1: \
  326. case MONO_TYPE_I2: \
  327. case MONO_TYPE_I4: \
  328. case MONO_TYPE_I8: \
  329. *(etype *) ea = (etype) i64; \
  330. return; \
  331. case MONO_TYPE_U1: \
  332. case MONO_TYPE_U2: \
  333. case MONO_TYPE_U4: \
  334. case MONO_TYPE_U8: \
  335. case MONO_TYPE_CHAR: \
  336. *(etype *) ea = (etype) u64; \
  337. return; \
  338. } \
  339. }G_STMT_END
  340. switch (vt) {
  341. case MONO_TYPE_U1:
  342. u64 = *(guint8 *) va;
  343. break;
  344. case MONO_TYPE_U2:
  345. u64 = *(guint16 *) va;
  346. break;
  347. case MONO_TYPE_U4:
  348. u64 = *(guint32 *) va;
  349. break;
  350. case MONO_TYPE_U8:
  351. u64 = *(guint64 *) va;
  352. break;
  353. case MONO_TYPE_I1:
  354. i64 = *(gint8 *) va;
  355. break;
  356. case MONO_TYPE_I2:
  357. i64 = *(gint16 *) va;
  358. break;
  359. case MONO_TYPE_I4:
  360. i64 = *(gint32 *) va;
  361. break;
  362. case MONO_TYPE_I8:
  363. i64 = *(gint64 *) va;
  364. break;
  365. case MONO_TYPE_R4:
  366. r64 = *(gfloat *) va;
  367. break;
  368. case MONO_TYPE_R8:
  369. r64 = *(gdouble *) va;
  370. break;
  371. case MONO_TYPE_CHAR:
  372. u64 = *(guint16 *) va;
  373. break;
  374. case MONO_TYPE_BOOLEAN:
  375. /* Boolean is only compatible with itself. */
  376. switch (et) {
  377. case MONO_TYPE_CHAR:
  378. case MONO_TYPE_U1:
  379. case MONO_TYPE_U2:
  380. case MONO_TYPE_U4:
  381. case MONO_TYPE_U8:
  382. case MONO_TYPE_I1:
  383. case MONO_TYPE_I2:
  384. case MONO_TYPE_I4:
  385. case MONO_TYPE_I8:
  386. case MONO_TYPE_R4:
  387. case MONO_TYPE_R8:
  388. NO_WIDENING_CONVERSION;
  389. default:
  390. INVALID_CAST;
  391. }
  392. break;
  393. }
  394. /* If we can't do a direct copy, let's try a widening conversion. */
  395. switch (et) {
  396. case MONO_TYPE_CHAR:
  397. ASSIGN_UNSIGNED (guint16);
  398. case MONO_TYPE_U1:
  399. ASSIGN_UNSIGNED (guint8);
  400. case MONO_TYPE_U2:
  401. ASSIGN_UNSIGNED (guint16);
  402. case MONO_TYPE_U4:
  403. ASSIGN_UNSIGNED (guint32);
  404. case MONO_TYPE_U8:
  405. ASSIGN_UNSIGNED (guint64);
  406. case MONO_TYPE_I1:
  407. ASSIGN_SIGNED (gint8);
  408. case MONO_TYPE_I2:
  409. ASSIGN_SIGNED (gint16);
  410. case MONO_TYPE_I4:
  411. ASSIGN_SIGNED (gint32);
  412. case MONO_TYPE_I8:
  413. ASSIGN_SIGNED (gint64);
  414. case MONO_TYPE_R4:
  415. ASSIGN_REAL (gfloat);
  416. case MONO_TYPE_R8:
  417. ASSIGN_REAL (gdouble);
  418. }
  419. INVALID_CAST;
  420. /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
  421. return;
  422. #undef INVALID_CAST
  423. #undef NO_WIDENING_CONVERSION
  424. #undef CHECK_WIDENING_CONVERSION
  425. #undef ASSIGN_UNSIGNED
  426. #undef ASSIGN_SIGNED
  427. #undef ASSIGN_REAL
  428. }
  429. ICALL_EXPORT void
  430. ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
  431. MonoArray *idxs)
  432. {
  433. MonoClass *ac, *ic;
  434. gint32 i, pos, *ind;
  435. MONO_ARCH_SAVE_REGS;
  436. MONO_CHECK_ARG_NULL (idxs);
  437. ic = idxs->obj.vtable->klass;
  438. ac = this->obj.vtable->klass;
  439. g_assert (ic->rank == 1);
  440. if (idxs->bounds != NULL || idxs->max_length != ac->rank)
  441. mono_raise_exception (mono_get_exception_argument (NULL, NULL));
  442. ind = (gint32 *)idxs->vector;
  443. if (this->bounds == NULL) {
  444. if (*ind < 0 || *ind >= this->max_length)
  445. mono_raise_exception (mono_get_exception_index_out_of_range ());
  446. ves_icall_System_Array_SetValueImpl (this, value, *ind);
  447. return;
  448. }
  449. for (i = 0; i < ac->rank; i++)
  450. if ((ind [i] < this->bounds [i].lower_bound) ||
  451. (ind [i] >= (mono_array_lower_bound_t)this->bounds [i].length + this->bounds [i].lower_bound))
  452. mono_raise_exception (mono_get_exception_index_out_of_range ());
  453. pos = ind [0] - this->bounds [0].lower_bound;
  454. for (i = 1; i < ac->rank; i++)
  455. pos = pos * this->bounds [i].length + ind [i] -
  456. this->bounds [i].lower_bound;
  457. ves_icall_System_Array_SetValueImpl (this, value, pos);
  458. }
  459. ICALL_EXPORT MonoArray *
  460. ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
  461. {
  462. MonoClass *aklass, *klass;
  463. MonoArray *array;
  464. uintptr_t *sizes, i;
  465. gboolean bounded = FALSE;
  466. MONO_ARCH_SAVE_REGS;
  467. MONO_CHECK_ARG_NULL (type);
  468. MONO_CHECK_ARG_NULL (lengths);
  469. MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
  470. if (bounds)
  471. MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
  472. for (i = 0; i < mono_array_length (lengths); i++)
  473. if (mono_array_get (lengths, gint32, i) < 0)
  474. mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
  475. klass = mono_class_from_mono_type (type->type);
  476. mono_class_init_or_throw (klass);
  477. if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
  478. /* vectors are not the same as one dimensional arrays with no-zero bounds */
  479. bounded = TRUE;
  480. else
  481. bounded = FALSE;
  482. aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
  483. sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
  484. for (i = 0; i < aklass->rank; ++i) {
  485. sizes [i] = mono_array_get (lengths, guint32, i);
  486. if (bounds)
  487. sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
  488. else
  489. sizes [i + aklass->rank] = 0;
  490. }
  491. array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank);
  492. return array;
  493. }
  494. ICALL_EXPORT MonoArray *
  495. ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
  496. {
  497. MonoClass *aklass, *klass;
  498. MonoArray *array;
  499. uintptr_t *sizes, i;
  500. gboolean bounded = FALSE;
  501. MONO_ARCH_SAVE_REGS;
  502. MONO_CHECK_ARG_NULL (type);
  503. MONO_CHECK_ARG_NULL (lengths);
  504. MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
  505. if (bounds)
  506. MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
  507. for (i = 0; i < mono_array_length (lengths); i++)
  508. if ((mono_array_get (lengths, gint64, i) < 0) ||
  509. (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX))
  510. mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
  511. klass = mono_class_from_mono_type (type->type);
  512. mono_class_init_or_throw (klass);
  513. if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
  514. /* vectors are not the same as one dimensional arrays with no-zero bounds */
  515. bounded = TRUE;
  516. else
  517. bounded = FALSE;
  518. aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
  519. sizes = alloca (aklass->rank * sizeof(intptr_t) * 2);
  520. for (i = 0; i < aklass->rank; ++i) {
  521. sizes [i] = mono_array_get (lengths, guint64, i);
  522. if (bounds)
  523. sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
  524. else
  525. sizes [i + aklass->rank] = 0;
  526. }
  527. array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank);
  528. return array;
  529. }
  530. ICALL_EXPORT gint32
  531. ves_icall_System_Array_GetRank (MonoObject *this)
  532. {
  533. MONO_ARCH_SAVE_REGS;
  534. return this->vtable->klass->rank;
  535. }
  536. ICALL_EXPORT gint32
  537. ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
  538. {
  539. gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
  540. uintptr_t length;
  541. MONO_ARCH_SAVE_REGS;
  542. if ((dimension < 0) || (dimension >= rank))
  543. mono_raise_exception (mono_get_exception_index_out_of_range ());
  544. if (this->bounds == NULL)
  545. length = this->max_length;
  546. else
  547. length = this->bounds [dimension].length;
  548. #ifdef MONO_BIG_ARRAYS
  549. if (length > G_MAXINT32)
  550. mono_raise_exception (mono_get_exception_overflow ());
  551. #endif
  552. return length;
  553. }
  554. ICALL_EXPORT gint64
  555. ves_icall_System_Array_GetLongLength (MonoArray *this, gint32 dimension)
  556. {
  557. gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
  558. MONO_ARCH_SAVE_REGS;
  559. if ((dimension < 0) || (dimension >= rank))
  560. mono_raise_exception (mono_get_exception_index_out_of_range ());
  561. if (this->bounds == NULL)
  562. return this->max_length;
  563. return this->bounds [dimension].length;
  564. }
  565. ICALL_EXPORT gint32
  566. ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
  567. {
  568. gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
  569. MONO_ARCH_SAVE_REGS;
  570. if ((dimension < 0) || (dimension >= rank))
  571. mono_raise_exception (mono_get_exception_index_out_of_range ());
  572. if (this->bounds == NULL)
  573. return 0;
  574. return this->bounds [dimension].lower_bound;
  575. }
  576. ICALL_EXPORT void
  577. ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
  578. {
  579. int sz = mono_array_element_size (mono_object_class (arr));
  580. mono_gc_bzero (mono_array_addr_with_size (arr, sz, idx), length * sz);
  581. }
  582. ICALL_EXPORT gboolean
  583. ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
  584. {
  585. int element_size;
  586. void * dest_addr;
  587. void * source_addr;
  588. MonoClass *src_class;
  589. MonoClass *dest_class;
  590. MONO_ARCH_SAVE_REGS;
  591. if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
  592. return FALSE;
  593. if (source->bounds || dest->bounds)
  594. return FALSE;
  595. /* there's no integer overflow since mono_array_length returns an unsigned integer */
  596. if ((dest_idx + length > mono_array_length (dest)) ||
  597. (source_idx + length > mono_array_length (source)))
  598. return FALSE;
  599. src_class = source->obj.vtable->klass->element_class;
  600. dest_class = dest->obj.vtable->klass->element_class;
  601. /*
  602. * Handle common cases.
  603. */
  604. /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
  605. if (src_class == mono_defaults.object_class && dest_class->valuetype) {
  606. // FIXME: This is racy
  607. return FALSE;
  608. /*
  609. int i;
  610. int has_refs = dest_class->has_references;
  611. for (i = source_idx; i < source_idx + length; ++i) {
  612. MonoObject *elem = mono_array_get (source, MonoObject*, i);
  613. if (elem && !mono_object_isinst (elem, dest_class))
  614. return FALSE;
  615. }
  616. element_size = mono_array_element_size (dest->obj.vtable->klass);
  617. memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
  618. for (i = 0; i < length; ++i) {
  619. MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
  620. void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
  621. if (!elem)
  622. continue;
  623. if (has_refs)
  624. mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
  625. else
  626. memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
  627. }
  628. return TRUE;
  629. */
  630. }
  631. /* Check if we're copying a char[] <==> (u)short[] */
  632. if (src_class != dest_class) {
  633. if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
  634. return FALSE;
  635. if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
  636. ;
  637. /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
  638. else if (mono_class_is_subclass_of (dest_class, src_class, FALSE)) {
  639. // FIXME: This is racy
  640. return FALSE;
  641. /*
  642. int i;
  643. for (i = source_idx; i < source_idx + length; ++i) {
  644. MonoObject *elem = mono_array_get (source, MonoObject*, i);
  645. if (elem && !mono_object_isinst (elem, dest_class))
  646. return FALSE;
  647. }
  648. */
  649. } else
  650. return FALSE;
  651. }
  652. if (dest_class->valuetype) {
  653. element_size = mono_array_element_size (source->obj.vtable->klass);
  654. source_addr = mono_array_addr_with_size (source, element_size, source_idx);
  655. if (dest_class->has_references) {
  656. mono_value_copy_array (dest, dest_idx, source_addr, length);
  657. } else {
  658. dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
  659. mono_gc_memmove (dest_addr, source_addr, element_size * length);
  660. }
  661. } else {
  662. mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
  663. }
  664. return TRUE;
  665. }
  666. ICALL_EXPORT void
  667. ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
  668. {
  669. MonoClass *ac;
  670. MonoArray *ao;
  671. gint32 esize;
  672. gpointer *ea;
  673. MONO_ARCH_SAVE_REGS;
  674. ao = (MonoArray *)this;
  675. ac = (MonoClass *)ao->obj.vtable->klass;
  676. esize = mono_array_element_size (ac);
  677. ea = (gpointer*)((char*)ao->vector + (pos * esize));
  678. mono_gc_memmove (value, ea, esize);
  679. }
  680. ICALL_EXPORT void
  681. ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
  682. {
  683. MonoClass *ac, *ec;
  684. MonoArray *ao;
  685. gint32 esize;
  686. gpointer *ea;
  687. MONO_ARCH_SAVE_REGS;
  688. ao = (MonoArray *)this;
  689. ac = (MonoClass *)ao->obj.vtable->klass;
  690. ec = ac->element_class;
  691. esize = mono_array_element_size (ac);
  692. ea = (gpointer*)((char*)ao->vector + (pos * esize));
  693. if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
  694. g_assert (esize == sizeof (gpointer));
  695. mono_gc_wbarrier_generic_store (ea, *(gpointer*)value);
  696. } else {
  697. g_assert (ec->inited);
  698. g_assert (esize == mono_class_value_size (ec, NULL));
  699. if (ec->has_references)
  700. mono_gc_wbarrier_value_copy (ea, value, 1, ec);
  701. else
  702. mono_gc_memmove (ea, value, esize);
  703. }
  704. }
  705. ICALL_EXPORT void
  706. ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
  707. {
  708. MonoClass *klass = array->obj.vtable->klass;
  709. guint32 size = mono_array_element_size (klass);
  710. MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
  711. int align;
  712. const char *field_data;
  713. if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
  714. MonoException *exc = mono_get_exception_argument("array",
  715. "Cannot initialize array of non-primitive type.");
  716. mono_raise_exception (exc);
  717. }
  718. if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
  719. MonoException *exc = mono_get_exception_argument("field_handle",
  720. "Field doesn't have an RVA");
  721. mono_raise_exception (exc);
  722. }
  723. size *= array->max_length;
  724. field_data = mono_field_get_data (field_handle);
  725. if (size > mono_type_size (field_handle->type, &align)) {
  726. MonoException *exc = mono_get_exception_argument("field_handle",
  727. "Field not large enough to fill array");
  728. mono_raise_exception (exc);
  729. }
  730. #if G_BYTE_ORDER != G_LITTLE_ENDIAN
  731. #define SWAP(n) {\
  732. guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
  733. guint ## n *src = (guint ## n *) field_data; \
  734. guint ## n *end = (guint ## n *)((char*)src + size); \
  735. \
  736. for (; src < end; data++, src++) { \
  737. *data = read ## n (src); \
  738. } \
  739. }
  740. /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
  741. switch (type->type) {
  742. case MONO_TYPE_CHAR:
  743. case MONO_TYPE_I2:
  744. case MONO_TYPE_U2:
  745. SWAP (16);
  746. break;
  747. case MONO_TYPE_I4:
  748. case MONO_TYPE_U4:
  749. case MONO_TYPE_R4:
  750. SWAP (32);
  751. break;
  752. case MONO_TYPE_I8:
  753. case MONO_TYPE_U8:
  754. case MONO_TYPE_R8:
  755. SWAP (64);
  756. break;
  757. default:
  758. memcpy (mono_array_addr (array, char, 0), field_data, size);
  759. break;
  760. }
  761. #else
  762. memcpy (mono_array_addr (array, char, 0), field_data, size);
  763. #ifdef ARM_FPU_FPA
  764. if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
  765. gint i;
  766. double tmp;
  767. double *data = (double*)mono_array_addr (array, double, 0);
  768. for (i = 0; i < size; i++, data++) {
  769. readr8 (data, &tmp);
  770. *data = tmp;
  771. }
  772. }
  773. #endif
  774. #endif
  775. }
  776. ICALL_EXPORT gint
  777. ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
  778. {
  779. MONO_ARCH_SAVE_REGS;
  780. return offsetof (MonoString, chars);
  781. }
  782. ICALL_EXPORT MonoObject *
  783. ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
  784. {
  785. MONO_ARCH_SAVE_REGS;
  786. if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
  787. return obj;
  788. else
  789. return mono_object_clone (obj);
  790. }
  791. ICALL_EXPORT void
  792. ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
  793. {
  794. MonoClass *klass;
  795. MonoVTable *vtable;
  796. MONO_CHECK_ARG_NULL (handle);
  797. klass = mono_class_from_mono_type (handle);
  798. MONO_CHECK_ARG (handle, klass);
  799. vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
  800. /* This will call the type constructor */
  801. mono_runtime_class_init (vtable);
  802. }
  803. ICALL_EXPORT void
  804. ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
  805. {
  806. MONO_ARCH_SAVE_REGS;
  807. mono_image_check_for_module_cctor (image);
  808. if (image->has_module_cctor) {
  809. MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
  810. /*It's fine to raise the exception here*/
  811. mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass, TRUE));
  812. }
  813. }
  814. ICALL_EXPORT MonoBoolean
  815. ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
  816. {
  817. guint8 *stack_addr;
  818. guint8 *current;
  819. size_t stack_size;
  820. /* later make this configurable and per-arch */
  821. int min_size = 4096 * 4 * sizeof (void*);
  822. mono_thread_get_stack_bounds (&stack_addr, &stack_size);
  823. /* if we have no info we are optimistic and assume there is enough room */
  824. if (!stack_addr)
  825. return TRUE;
  826. current = (guint8 *)&stack_addr;
  827. if (current > stack_addr) {
  828. if ((current - stack_addr) < min_size)
  829. return FALSE;
  830. } else {
  831. if (current - (stack_addr - stack_size) < min_size)
  832. return FALSE;
  833. }
  834. return TRUE;
  835. }
  836. ICALL_EXPORT MonoObject *
  837. ves_icall_System_Object_MemberwiseClone (MonoObject *this)
  838. {
  839. MONO_ARCH_SAVE_REGS;
  840. return mono_object_clone (this);
  841. }
  842. ICALL_EXPORT gint32
  843. ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
  844. {
  845. MonoClass *klass;
  846. MonoObject **values = NULL;
  847. MonoObject *o;
  848. int count = 0;
  849. gint32 result = 0;
  850. MonoClassField* field;
  851. gpointer iter;
  852. MONO_ARCH_SAVE_REGS;
  853. klass = mono_object_class (this);
  854. if (mono_class_num_fields (klass) == 0)
  855. return mono_object_hash (this);
  856. /*
  857. * Compute the starting value of the hashcode for fields of primitive
  858. * types, and return the remaining fields in an array to the managed side.
  859. * This way, we can avoid costly reflection operations in managed code.
  860. */
  861. iter = NULL;
  862. while ((field = mono_class_get_fields (klass, &iter))) {
  863. if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
  864. continue;
  865. if (mono_field_is_deleted (field))
  866. continue;
  867. /* FIXME: Add more types */
  868. switch (field->type->type) {
  869. case MONO_TYPE_I4:
  870. result ^= *(gint32*)((guint8*)this + field->offset);
  871. break;
  872. case MONO_TYPE_STRING: {
  873. MonoString *s;
  874. s = *(MonoString**)((guint8*)this + field->offset);
  875. if (s != NULL)
  876. result ^= mono_string_hash (s);
  877. break;
  878. }
  879. default:
  880. if (!values)
  881. values = g_newa (MonoObject*, mono_class_num_fields (klass));
  882. o = mono_field_get_value_object (mono_object_domain (this), field, this);
  883. values [count++] = o;
  884. }
  885. }
  886. if (values) {
  887. int i;
  888. mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
  889. for (i = 0; i < count; ++i)
  890. mono_array_setref (*fields, i, values [i]);
  891. } else {
  892. *fields = NULL;
  893. }
  894. return result;
  895. }
  896. ICALL_EXPORT MonoBoolean
  897. ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
  898. {
  899. MonoClass *klass;
  900. MonoObject **values = NULL;
  901. MonoObject *o;
  902. MonoClassField* field;
  903. gpointer iter;
  904. int count = 0;
  905. MONO_ARCH_SAVE_REGS;
  906. MONO_CHECK_ARG_NULL (that);
  907. if (this->vtable != that->vtable)
  908. return FALSE;
  909. klass = mono_object_class (this);
  910. if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
  911. return (*(gint32*)((guint8*)this + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
  912. /*
  913. * Do the comparison for fields of primitive type and return a result if
  914. * possible. Otherwise, return the remaining fields in an array to the
  915. * managed side. This way, we can avoid costly reflection operations in
  916. * managed code.
  917. */
  918. *fields = NULL;
  919. iter = NULL;
  920. while ((field = mono_class_get_fields (klass, &iter))) {
  921. if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
  922. continue;
  923. if (mono_field_is_deleted (field))
  924. continue;
  925. /* FIXME: Add more types */
  926. switch (field->type->type) {
  927. case MONO_TYPE_U1:
  928. case MONO_TYPE_I1:
  929. case MONO_TYPE_BOOLEAN:
  930. if (*((guint8*)this + field->offset) != *((guint8*)that + field->offset))
  931. return FALSE;
  932. break;
  933. case MONO_TYPE_U2:
  934. case MONO_TYPE_I2:
  935. case MONO_TYPE_CHAR:
  936. if (*(gint16*)((guint8*)this + field->offset) != *(gint16*)((guint8*)that + field->offset))
  937. return FALSE;
  938. break;
  939. case MONO_TYPE_U4:
  940. case MONO_TYPE_I4:
  941. if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
  942. return FALSE;
  943. break;
  944. case MONO_TYPE_U8:
  945. case MONO_TYPE_I8:
  946. if (*(gint64*)((guint8*)this + field->offset) != *(gint64*)((guint8*)that + field->offset))
  947. return FALSE;
  948. break;
  949. case MONO_TYPE_R4:
  950. if (*(float*)((guint8*)this + field->offset) != *(float*)((guint8*)that + field->offset))
  951. return FALSE;
  952. break;
  953. case MONO_TYPE_R8:
  954. if (*(double*)((guint8*)this + field->offset) != *(double*)((guint8*)that + field->offset))
  955. return FALSE;
  956. break;
  957. case MONO_TYPE_STRING: {
  958. MonoString *s1, *s2;
  959. guint32 s1len, s2len;
  960. s1 = *(MonoString**)((guint8*)this + field->offset);
  961. s2 = *(MonoString**)((guint8*)that + field->offset);
  962. if (s1 == s2)
  963. break;
  964. if ((s1 == NULL) || (s2 == NULL))
  965. return FALSE;
  966. s1len = mono_string_length (s1);
  967. s2len = mono_string_length (s2);
  968. if (s1len != s2len)
  969. return FALSE;
  970. if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
  971. return FALSE;
  972. break;
  973. }
  974. default:
  975. if (!values)
  976. values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
  977. o = mono_field_get_value_object (mono_object_domain (this), field, this);
  978. values [count++] = o;
  979. o = mono_field_get_value_object (mono_object_domain (this), field, that);
  980. values [count++] = o;
  981. }
  982. if (klass->enumtype)
  983. /* enums only have one non-static field */
  984. break;
  985. }
  986. if (values) {
  987. int i;
  988. mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
  989. for (i = 0; i < count; ++i)
  990. mono_array_setref (*fields, i, values [i]);
  991. return FALSE;
  992. } else {
  993. return TRUE;
  994. }
  995. }
  996. ICALL_EXPORT MonoReflectionType *
  997. ves_icall_System_Object_GetType (MonoObject *obj)
  998. {
  999. MONO_ARCH_SAVE_REGS;
  1000. #ifndef DISABLE_REMOTING
  1001. if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
  1002. return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
  1003. else
  1004. #endif
  1005. return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
  1006. }
  1007. ICALL_EXPORT void
  1008. mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
  1009. {
  1010. MONO_ARCH_SAVE_REGS;
  1011. mtype->type = &obj->vtable->klass->byval_arg;
  1012. g_assert (mtype->type->type);
  1013. }
  1014. ICALL_EXPORT gint32
  1015. ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
  1016. {
  1017. MONO_ARCH_SAVE_REGS;
  1018. MONO_CHECK_ARG_NULL (obj);
  1019. return mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE);
  1020. }
  1021. ICALL_EXPORT gint32
  1022. ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
  1023. MonoReflectionMethod *method,
  1024. MonoArray *opt_param_types)
  1025. {
  1026. MONO_ARCH_SAVE_REGS;
  1027. MONO_CHECK_ARG_NULL (method);
  1028. return mono_image_create_method_token (
  1029. mb->dynamic_image, (MonoObject *) method, opt_param_types);
  1030. }
  1031. ICALL_EXPORT void
  1032. ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
  1033. {
  1034. MONO_ARCH_SAVE_REGS;
  1035. mono_image_create_pefile (mb, file);
  1036. }
  1037. ICALL_EXPORT void
  1038. ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
  1039. {
  1040. MONO_ARCH_SAVE_REGS;
  1041. mono_image_build_metadata (mb);
  1042. }
  1043. ICALL_EXPORT void
  1044. ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
  1045. {
  1046. MONO_ARCH_SAVE_REGS;
  1047. mono_image_register_token (mb->dynamic_image, token, obj);
  1048. }
  1049. static gboolean
  1050. get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
  1051. {
  1052. MonoMethod **dest = data;
  1053. /* skip unmanaged frames */
  1054. if (!managed)
  1055. return FALSE;
  1056. if (m == *dest) {
  1057. *dest = NULL;
  1058. return FALSE;
  1059. }
  1060. if (!(*dest)) {
  1061. *dest = m;
  1062. return TRUE;
  1063. }
  1064. return FALSE;
  1065. }
  1066. static gboolean
  1067. get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
  1068. {
  1069. MonoMethod **dest = data;
  1070. /* skip unmanaged frames */
  1071. if (!managed)
  1072. return FALSE;
  1073. if (!(*dest)) {
  1074. if (!strcmp (m->klass->name_space, "System.Reflection"))
  1075. return FALSE;
  1076. *dest = m;
  1077. return TRUE;
  1078. }
  1079. return FALSE;
  1080. }
  1081. static gboolean
  1082. get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
  1083. {
  1084. MonoMethod **dest = data;
  1085. /* skip unmanaged frames */
  1086. if (!managed)
  1087. return FALSE;
  1088. if (m->wrapper_type != MONO_WRAPPER_NONE)
  1089. return FALSE;
  1090. if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
  1091. return FALSE;
  1092. if (m == *dest) {
  1093. *dest = NULL;
  1094. return FALSE;
  1095. }
  1096. if (!(*dest)) {
  1097. *dest = m;
  1098. return TRUE;
  1099. }
  1100. return FALSE;
  1101. }
  1102. static MonoReflectionType *
  1103. type_from_name (const char *str, MonoBoolean ignoreCase)
  1104. {
  1105. MonoType *type = NULL;
  1106. MonoAssembly *assembly = NULL;
  1107. MonoTypeNameParse info;
  1108. char *temp_str = g_strdup (str);
  1109. gboolean type_resolve = FALSE;
  1110. MONO_ARCH_SAVE_REGS;
  1111. /* mono_reflection_parse_type() mangles the string */
  1112. if (!mono_reflection_parse_type (temp_str, &info)) {
  1113. mono_reflection_free_type_info (&info);
  1114. g_free (temp_str);
  1115. return NULL;
  1116. }
  1117. if (info.assembly.name) {
  1118. assembly = mono_assembly_load (&info.assembly, NULL, NULL);
  1119. } else {
  1120. MonoMethod *m = mono_method_get_last_managed ();
  1121. MonoMethod *dest = m;
  1122. mono_stack_walk_no_il (get_caller_no_reflection, &dest);
  1123. if (!dest)
  1124. dest = m;
  1125. /*
  1126. * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
  1127. * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
  1128. * to crash. This only seems to happen in some strange remoting
  1129. * scenarios and I was unable to figure out what's happening there.
  1130. * Dec 10, 2005 - Martin.
  1131. */
  1132. if (dest) {
  1133. assembly = dest->klass->image->assembly;
  1134. type_resolve = TRUE;
  1135. } else {
  1136. g_warning (G_STRLOC);
  1137. }
  1138. }
  1139. if (assembly) {
  1140. /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
  1141. type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
  1142. }
  1143. if (!info.assembly.name && !type) /* try mscorlib */
  1144. type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
  1145. if (assembly && !type && type_resolve) {
  1146. type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
  1147. type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
  1148. }
  1149. mono_reflection_free_type_info (&info);
  1150. g_free (temp_str);
  1151. if (!type)
  1152. return NULL;
  1153. return mono_type_get_object (mono_domain_get (), type);
  1154. }
  1155. #ifdef UNUSED
  1156. MonoReflectionType *
  1157. mono_type_get (const char *str)
  1158. {
  1159. char *copy = g_strdup (str);
  1160. MonoReflectionType *type = type_from_name (copy, FALSE);
  1161. g_free (copy);
  1162. return type;
  1163. }
  1164. #endif
  1165. ICALL_EXPORT MonoReflectionType*
  1166. ves_icall_type_from_name (MonoString *name,
  1167. MonoBoolean throwOnError,
  1168. MonoBoolean ignoreCase)
  1169. {
  1170. char *str = mono_string_to_utf8 (name);
  1171. MonoReflectionType *type;
  1172. type = type_from_name (str, ignoreCase);
  1173. g_free (str);
  1174. if (type == NULL){
  1175. MonoException *e = NULL;
  1176. if (throwOnError)
  1177. e = mono_get_exception_type_load (name, NULL);
  1178. mono_loader_clear_error ();
  1179. if (e != NULL)
  1180. mono_raise_exception (e);
  1181. }
  1182. return type;
  1183. }
  1184. ICALL_EXPORT MonoReflectionType*
  1185. ves_icall_type_from_handle (MonoType *handle)
  1186. {
  1187. MonoDomain *domain = mono_domain_get ();
  1188. MONO_ARCH_SAVE_REGS;
  1189. return mono_type_get_object (domain, handle);
  1190. }
  1191. ICALL_EXPORT MonoBoolean
  1192. ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
  1193. {
  1194. MONO_ARCH_SAVE_REGS;
  1195. if (c && type->type && c->type)
  1196. return mono_metadata_type_equal (type->type, c->type);
  1197. else
  1198. return (type == c) ? TRUE : FALSE;
  1199. }
  1200. /* System.TypeCode */
  1201. typedef enum {
  1202. TYPECODE_EMPTY,
  1203. TYPECODE_OBJECT,
  1204. TYPECODE_DBNULL,
  1205. TYPECODE_BOOLEAN,
  1206. TYPECODE_CHAR,
  1207. TYPECODE_SBYTE,
  1208. TYPECODE_BYTE,
  1209. TYPECODE_INT16,
  1210. TYPECODE_UINT16,
  1211. TYPECODE_INT32,
  1212. TYPECODE_UINT32,
  1213. TYPECODE_INT64,
  1214. TYPECODE_UINT64,
  1215. TYPECODE_SINGLE,
  1216. TYPECODE_DOUBLE,
  1217. TYPECODE_DECIMAL,
  1218. TYPECODE_DATETIME,
  1219. TYPECODE_STRING = 18
  1220. } TypeCode;
  1221. ICALL_EXPORT guint32
  1222. ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
  1223. {
  1224. int t = type->type->type;
  1225. MONO_ARCH_SAVE_REGS;
  1226. if (type->type->byref)
  1227. return TYPECODE_OBJECT;
  1228. handle_enum:
  1229. switch (t) {
  1230. case MONO_TYPE_VOID:
  1231. return TYPECODE_OBJECT;
  1232. case MONO_TYPE_BOOLEAN:
  1233. return TYPECODE_BOOLEAN;
  1234. case MONO_TYPE_U1:
  1235. return TYPECODE_BYTE;
  1236. case MONO_TYPE_I1:
  1237. return TYPECODE_SBYTE;
  1238. case MONO_TYPE_U2:
  1239. return TYPECODE_UINT16;
  1240. case MONO_TYPE_I2:
  1241. return TYPECODE_INT16;
  1242. case MONO_TYPE_CHAR:
  1243. return TYPECODE_CHAR;
  1244. case MONO_TYPE_PTR:
  1245. case MONO_TYPE_U:
  1246. case MONO_TYPE_I:
  1247. return TYPECODE_OBJECT;
  1248. case MONO_TYPE_U4:
  1249. return TYPECODE_UINT32;
  1250. case MONO_TYPE_I4:
  1251. return TYPECODE_INT32;
  1252. case MONO_TYPE_U8:
  1253. return TYPECODE_UINT64;
  1254. case MONO_TYPE_I8:
  1255. return TYPECODE_INT64;
  1256. case MONO_TYPE_R4:
  1257. return TYPECODE_SINGLE;
  1258. case MONO_TYPE_R8:
  1259. return TYPECODE_DOUBLE;
  1260. case MONO_TYPE_VALUETYPE: {
  1261. MonoClass *klass = type->type->data.klass;
  1262. if (klass->enumtype) {
  1263. t = mono_class_enum_basetype (klass)->type;
  1264. goto handle_enum;
  1265. } else if (mono_is_corlib_image (klass->image)) {
  1266. if (strcmp (klass->name_space, "System") == 0) {
  1267. if (strcmp (klass->name, "Decimal") == 0)
  1268. return TYPECODE_DECIMAL;
  1269. else if (strcmp (klass->name, "DateTime") == 0)
  1270. return TYPECODE_DATETIME;
  1271. }
  1272. }
  1273. return TYPECODE_OBJECT;
  1274. }
  1275. case MONO_TYPE_STRING:
  1276. return TYPECODE_STRING;
  1277. case MONO_TYPE_SZARRAY:
  1278. case MONO_TYPE_ARRAY:
  1279. case MONO_TYPE_OBJECT:
  1280. case MONO_TYPE_VAR:
  1281. case MONO_TYPE_MVAR:
  1282. case MONO_TYPE_TYPEDBYREF:
  1283. return TYPECODE_OBJECT;
  1284. case MONO_TYPE_CLASS:
  1285. {
  1286. MonoClass *klass = type->type->data.klass;
  1287. if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
  1288. if (strcmp (klass->name, "DBNull") == 0)
  1289. return TYPECODE_DBNULL;
  1290. }
  1291. }
  1292. return TYPECODE_OBJECT;
  1293. case MONO_TYPE_GENERICINST:
  1294. return TYPECODE_OBJECT;
  1295. default:
  1296. g_error ("type 0x%02x not handled in GetTypeCode()", t);
  1297. }
  1298. return 0;
  1299. }
  1300. ICALL_EXPORT guint32
  1301. ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
  1302. {
  1303. MonoDomain *domain;
  1304. MonoClass *klass;
  1305. MonoClass *klassc;
  1306. MONO_ARCH_SAVE_REGS;
  1307. g_assert (type != NULL);
  1308. domain = ((MonoObject *)type)->vtable->domain;
  1309. if (!c) /* FIXME: dont know what do do here */
  1310. return 0;
  1311. klass = mono_class_from_mono_type (type->type);
  1312. klassc = mono_class_from_mono_type (c->type);
  1313. /* Interface check requires a more complex setup so we
  1314. * only do for them. Otherwise we simply avoid mono_class_init.
  1315. */
  1316. if (check_interfaces) {
  1317. mono_class_init_or_throw (klass);
  1318. mono_class_init_or_throw (klassc);
  1319. } else if (!klass->supertypes || !klassc->supertypes) {
  1320. mono_loader_lock ();
  1321. mono_class_setup_supertypes (klass);
  1322. mono_class_setup_supertypes (klassc);
  1323. mono_loader_unlock ();
  1324. }
  1325. if (type->type->byref)
  1326. return klassc == mono_defaults.object_class;
  1327. return mono_class_is_subclass_of (klass, klassc, check_interfaces);
  1328. }
  1329. static gboolean
  1330. mono_type_is_primitive (MonoType *type)
  1331. {
  1332. return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
  1333. type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
  1334. }
  1335. static MonoType*
  1336. mono_type_get_underlying_type_ignore_byref (MonoType *type)
  1337. {
  1338. if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
  1339. return mono_class_enum_basetype (type->data.klass);
  1340. if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
  1341. return mono_class_enum_basetype (type->data.generic_class->container_class);
  1342. return type;
  1343. }
  1344. ICALL_EXPORT guint32
  1345. ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
  1346. {
  1347. MonoDomain *domain;
  1348. MonoClass *klass;
  1349. MonoClass *klassc;
  1350. MONO_ARCH_SAVE_REGS;
  1351. g_assert (type != NULL);
  1352. domain = ((MonoObject *)type)->vtable->domain;
  1353. klass = mono_class_from_mono_type (type->type);
  1354. klassc = mono_class_from_mono_type (c->type);
  1355. mono_class_init_or_throw (klass);
  1356. mono_class_init_or_throw (klassc);
  1357. if (type->type->byref ^ c->type->byref)
  1358. return FALSE;
  1359. if (type->type->byref) {
  1360. MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
  1361. MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
  1362. klass = mono_class_from_mono_type (t);
  1363. klassc = mono_class_from_mono_type (ot);
  1364. if (mono_type_is_primitive (t)) {
  1365. return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
  1366. } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
  1367. return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
  1368. } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
  1369. return t->type == ot->type;
  1370. } else {
  1371. if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
  1372. return FALSE;
  1373. if (klass->valuetype)
  1374. return klass == klassc;
  1375. return klass->valuetype == klassc->valuetype;
  1376. }
  1377. }
  1378. return mono_class_is_assignable_from (klass, klassc);
  1379. }
  1380. ICALL_EXPORT guint32
  1381. ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
  1382. {
  1383. MonoClass *klass = mono_class_from_mono_type (type->type);
  1384. mono_class_init_or_throw (klass);
  1385. return mono_object_isinst (obj, klass) != NULL;
  1386. }
  1387. ICALL_EXPORT guint32
  1388. ves_icall_get_attributes (MonoReflectionType *type)
  1389. {
  1390. MonoClass *klass = mono_class_from_mono_type (type->type);
  1391. return klass->flags;
  1392. }
  1393. ICALL_EXPORT MonoReflectionMarshalAsAttribute*
  1394. ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
  1395. {
  1396. MonoClass *klass = field->field->parent;
  1397. MonoMarshalType *info;
  1398. int i;
  1399. if (klass->generic_container ||
  1400. (klass->generic_class && klass->generic_class->context.class_inst->is_open))
  1401. return NULL;
  1402. info = mono_marshal_load_type_info (klass);
  1403. for (i = 0; i < info->num_fields; ++i) {
  1404. if (info->fields [i].field == field->field) {
  1405. if (!info->fields [i].mspec)
  1406. return NULL;
  1407. else
  1408. return mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
  1409. }
  1410. }
  1411. return NULL;
  1412. }
  1413. ICALL_EXPORT MonoReflectionField*
  1414. ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
  1415. {
  1416. gboolean found = FALSE;
  1417. MonoClass *klass;
  1418. MonoClass *k;
  1419. g_assert (handle);
  1420. if (!type) {
  1421. klass = handle->parent;
  1422. } else {
  1423. klass = mono_class_from_mono_type (type);
  1424. /* Check that the field belongs to the class */
  1425. for (k = klass; k; k = k->parent) {
  1426. if (k == handle->parent) {
  1427. found = TRUE;
  1428. break;
  1429. }
  1430. }
  1431. if (!found)
  1432. /* The managed code will throw the exception */
  1433. return NULL;
  1434. }
  1435. return mono_field_get_object (mono_domain_get (), klass, handle);
  1436. }
  1437. ICALL_EXPORT MonoArray*
  1438. ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
  1439. {
  1440. MonoError error;
  1441. MonoType *type = mono_field_get_type_checked (field->field, &error);
  1442. if (!mono_error_ok (&error))
  1443. mono_error_raise_exception (&error);
  1444. return type_array_from_modifiers (field->field->parent->image, type, optional);
  1445. }
  1446. ICALL_EXPORT int
  1447. vell_icall_get_method_attributes (MonoMethod *method)
  1448. {
  1449. return method->flags;
  1450. }
  1451. ICALL_EXPORT void
  1452. ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
  1453. {
  1454. MonoError error;
  1455. MonoDomain *domain = mono_domain_get ();
  1456. MonoMethodSignature* sig;
  1457. MONO_ARCH_SAVE_REGS;
  1458. sig = mono_method_signature_checked (method, &error);
  1459. if (!mono_error_ok (&error))
  1460. mono_error_raise_exception (&error);
  1461. MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &method->klass->byval_arg));
  1462. MONO_STRUCT_SETREF (info, ret, mono_type_get_object (domain, sig->ret));
  1463. info->attrs = method->flags;
  1464. info->implattrs = method->iflags;
  1465. if (sig->call_convention == MONO_CALL_DEFAULT)
  1466. info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
  1467. else {
  1468. if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
  1469. info->callconv = 2;
  1470. else
  1471. info->callconv = 1;
  1472. }
  1473. info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
  1474. }
  1475. ICALL_EXPORT MonoArray*
  1476. ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
  1477. {
  1478. MonoDomain *domain = mono_domain_get ();
  1479. return mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL);
  1480. }
  1481. ICALL_EXPORT MonoReflectionMarshalAsAttribute*
  1482. ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
  1483. {
  1484. MonoDomain *domain = mono_domain_get ();
  1485. MonoReflectionMarshalAsAttribute* res = NULL;
  1486. MonoMarshalSpec **mspecs;
  1487. int i;
  1488. mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
  1489. mono_method_get_marshal_info (method, mspecs);
  1490. if (mspecs [0])
  1491. res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0]);
  1492. for (i = mono_method_signature (method)->param_count; i >= 0; i--)
  1493. if (mspecs [i])
  1494. mono_metadata_free_marshal_spec (mspecs [i]);
  1495. g_free (mspecs);
  1496. return res;
  1497. }
  1498. ICALL_EXPORT gint32
  1499. ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
  1500. {
  1501. MonoClass *parent = field->field->parent;
  1502. if (!parent->size_inited)
  1503. mono_class_init (parent);
  1504. return field->field->offset - sizeof (MonoObject);
  1505. }
  1506. ICALL_EXPORT MonoReflectionType*
  1507. ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
  1508. {
  1509. MonoClass *parent;
  1510. MONO_ARCH_SAVE_REGS;
  1511. parent = declaring? field->field->parent: field->klass;
  1512. return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
  1513. }
  1514. ICALL_EXPORT MonoObject *
  1515. ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
  1516. {
  1517. MonoClass *fklass = field->klass;
  1518. MonoClassField *cf = field->field;
  1519. MonoDomain *domain = mono_object_domain (field);
  1520. if (fklass->image->assembly->ref_only)
  1521. mono_raise_exception (mono_get_exception_invalid_operation (
  1522. "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
  1523. if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
  1524. mono_security_core_clr_ensure_reflection_access_field (cf);
  1525. return mono_field_get_value_object (domain, cf, obj);
  1526. }
  1527. ICALL_EXPORT void
  1528. ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
  1529. {
  1530. MonoError error;
  1531. MonoClassField *cf = field->field;
  1532. MonoType *type;
  1533. gchar *v;
  1534. MONO_ARCH_SAVE_REGS;
  1535. if (field->klass->image->assembly->ref_only)
  1536. mono_raise_exception (mono_get_exception_invalid_operation (
  1537. "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
  1538. if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
  1539. mono_security_core_clr_ensure_reflection_access_field (cf);
  1540. type = mono_field_get_type_checked (cf, &error);
  1541. if (!mono_error_ok (&error))
  1542. mono_error_raise_exception (&error);
  1543. v = (gchar *) value;
  1544. if (!type->byref) {
  1545. switch (type->type) {
  1546. case MONO_TYPE_U1:
  1547. case MONO_TYPE_I1:
  1548. case MONO_TYPE_BOOLEAN:
  1549. case MONO_TYPE_U2:
  1550. case MONO_TYPE_I2:
  1551. case MONO_TYPE_CHAR:
  1552. case MONO_TYPE_U:
  1553. case MONO_TYPE_I:
  1554. case MONO_TYPE_U4:
  1555. case MONO_TYPE_I4:
  1556. case MONO_TYPE_R4:
  1557. case MONO_TYPE_U8:
  1558. case MONO_TYPE_I8:
  1559. case MONO_TYPE_R8:
  1560. case MONO_TYPE_VALUETYPE:
  1561. case MONO_TYPE_PTR:
  1562. if (v != NULL)
  1563. v += sizeof (MonoObject);
  1564. break;
  1565. case MONO_TYPE_STRING:
  1566. case MONO_TYPE_OBJECT:
  1567. case MONO_TYPE_CLASS:
  1568. case MONO_TYPE_ARRAY:
  1569. case MONO_TYPE_SZARRAY:
  1570. /* Do nothing */
  1571. break;
  1572. case MONO_TYPE_GENERICINST: {
  1573. MonoGenericClass *gclass = type->data.generic_class;
  1574. g_assert (!gclass->context.class_inst->is_open);
  1575. if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
  1576. MonoClass *nklass = mono_class_from_mono_type (type);
  1577. MonoObject *nullable;
  1578. /*
  1579. * Convert the boxed vtype into a Nullable structure.
  1580. * This is complicated by the fact that Nullables have
  1581. * a variable structure.
  1582. */
  1583. nullable = mono_object_new (mono_domain_get (), nklass);
  1584. mono_nullable_init (mono_object_unbox (nullable), value, nklass);
  1585. v = mono_object_unbox (nullable);
  1586. }
  1587. else
  1588. if (gclass->container_class->valuetype && (v != NULL))
  1589. v += sizeof (MonoObject);
  1590. break;
  1591. }
  1592. default:
  1593. g_error ("type 0x%x not handled in "
  1594. "ves_icall_FieldInfo_SetValueInternal", type->type);
  1595. return;
  1596. }
  1597. }
  1598. if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
  1599. MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE);
  1600. if (!vtable->initialized)
  1601. mono_runtime_class_init (vtable);
  1602. mono_field_static_set_value (vtable, cf, v);
  1603. } else {
  1604. m

Large files files are truncated, but you can click here to view the full file