sre-encode.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  1. /**
  2. * \file
  3. * Routines for encoding SRE builders into a
  4. * MonoDynamicImage and generating tokens.
  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/dynamic-image-internals.h"
  20. #include "mono/metadata/dynamic-stream-internals.h"
  21. #include "mono/metadata/object-internals.h"
  22. #include "mono/metadata/reflection-internals.h"
  23. #include "mono/metadata/sre-internals.h"
  24. #include "mono/metadata/tabledefs.h"
  25. #include "mono/metadata/tokentype.h"
  26. #include "mono/utils/checked-build.h"
  27. #include "icall-decl.h"
  28. typedef struct {
  29. char *p;
  30. char *buf;
  31. char *end;
  32. } SigBuffer;
  33. static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
  34. static void encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
  35. static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
  36. #if G_BYTE_ORDER != G_LITTLE_ENDIAN
  37. static guint32
  38. mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
  39. {
  40. return mono_dynstream_add_data (stream, data, len);
  41. }
  42. #endif
  43. static void
  44. alloc_table (MonoDynamicTable *table, guint nrows)
  45. {
  46. mono_dynimage_alloc_table (table, nrows);
  47. }
  48. static void
  49. sigbuffer_init (SigBuffer *buf, int size)
  50. {
  51. MONO_REQ_GC_NEUTRAL_MODE;
  52. buf->buf = (char *)g_malloc (size);
  53. buf->p = buf->buf;
  54. buf->end = buf->buf + size;
  55. }
  56. static void
  57. sigbuffer_make_room (SigBuffer *buf, int size)
  58. {
  59. MONO_REQ_GC_NEUTRAL_MODE;
  60. if (buf->end - buf->p < size) {
  61. int new_size = buf->end - buf->buf + size + 32;
  62. char *p = (char *)g_realloc (buf->buf, new_size);
  63. size = buf->p - buf->buf;
  64. buf->buf = p;
  65. buf->p = p + size;
  66. buf->end = buf->buf + new_size;
  67. }
  68. }
  69. static void
  70. sigbuffer_add_value (SigBuffer *buf, guint32 val)
  71. {
  72. MONO_REQ_GC_NEUTRAL_MODE;
  73. sigbuffer_make_room (buf, 6);
  74. mono_metadata_encode_value (val, buf->p, &buf->p);
  75. }
  76. static void
  77. sigbuffer_add_byte (SigBuffer *buf, guint8 val)
  78. {
  79. MONO_REQ_GC_NEUTRAL_MODE;
  80. sigbuffer_make_room (buf, 1);
  81. buf->p [0] = val;
  82. buf->p++;
  83. }
  84. static void
  85. sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
  86. {
  87. MONO_REQ_GC_NEUTRAL_MODE;
  88. sigbuffer_make_room (buf, size);
  89. memcpy (buf->p, p, size);
  90. buf->p += size;
  91. }
  92. static void
  93. sigbuffer_free (SigBuffer *buf)
  94. {
  95. MONO_REQ_GC_NEUTRAL_MODE;
  96. g_free (buf->buf);
  97. }
  98. static guint32
  99. sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
  100. {
  101. MONO_REQ_GC_NEUTRAL_MODE;
  102. char blob_size [8];
  103. char *b = blob_size;
  104. guint32 size = buf->p - buf->buf;
  105. /* store length */
  106. g_assert (size <= (buf->end - buf->buf));
  107. mono_metadata_encode_value (size, b, &b);
  108. return mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
  109. }
  110. static void
  111. encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
  112. {
  113. MONO_REQ_GC_NEUTRAL_MODE;
  114. int i;
  115. MonoGenericInst *class_inst;
  116. MonoClass *klass;
  117. g_assert (gclass);
  118. class_inst = gclass->context.class_inst;
  119. sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
  120. klass = gclass->container_class;
  121. sigbuffer_add_value (buf, m_class_get_byval_arg (klass)->type);
  122. sigbuffer_add_value (buf, mono_dynimage_encode_typedef_or_ref_full (assembly, m_class_get_byval_arg (klass), FALSE));
  123. sigbuffer_add_value (buf, class_inst->type_argc);
  124. for (i = 0; i < class_inst->type_argc; ++i)
  125. encode_type (assembly, class_inst->type_argv [i], buf);
  126. }
  127. static void
  128. encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
  129. {
  130. MONO_REQ_GC_NEUTRAL_MODE;
  131. if (!type) {
  132. g_assert_not_reached ();
  133. return;
  134. }
  135. if (type->byref)
  136. sigbuffer_add_value (buf, MONO_TYPE_BYREF);
  137. switch (type->type){
  138. case MONO_TYPE_VOID:
  139. case MONO_TYPE_BOOLEAN:
  140. case MONO_TYPE_CHAR:
  141. case MONO_TYPE_I1:
  142. case MONO_TYPE_U1:
  143. case MONO_TYPE_I2:
  144. case MONO_TYPE_U2:
  145. case MONO_TYPE_I4:
  146. case MONO_TYPE_U4:
  147. case MONO_TYPE_I8:
  148. case MONO_TYPE_U8:
  149. case MONO_TYPE_R4:
  150. case MONO_TYPE_R8:
  151. case MONO_TYPE_I:
  152. case MONO_TYPE_U:
  153. case MONO_TYPE_STRING:
  154. case MONO_TYPE_OBJECT:
  155. case MONO_TYPE_TYPEDBYREF:
  156. sigbuffer_add_value (buf, type->type);
  157. break;
  158. case MONO_TYPE_PTR:
  159. sigbuffer_add_value (buf, type->type);
  160. encode_type (assembly, type->data.type, buf);
  161. break;
  162. case MONO_TYPE_SZARRAY:
  163. sigbuffer_add_value (buf, type->type);
  164. encode_type (assembly, m_class_get_byval_arg (type->data.klass), buf);
  165. break;
  166. case MONO_TYPE_VALUETYPE:
  167. case MONO_TYPE_CLASS: {
  168. MonoClass *k = mono_class_from_mono_type_internal (type);
  169. if (mono_class_is_gtd (k)) {
  170. MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, mono_class_get_generic_container (k)->context.class_inst, TRUE);
  171. encode_generic_class (assembly, gclass, buf);
  172. } else {
  173. /*
  174. * Make sure we use the correct type.
  175. */
  176. sigbuffer_add_value (buf, m_class_get_byval_arg (k)->type);
  177. /*
  178. * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
  179. * otherwise two typerefs could point to the same type, leading to
  180. * verification errors.
  181. */
  182. sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, m_class_get_byval_arg (k)));
  183. }
  184. break;
  185. }
  186. case MONO_TYPE_ARRAY:
  187. sigbuffer_add_value (buf, type->type);
  188. encode_type (assembly, m_class_get_byval_arg (type->data.array->eklass), buf);
  189. sigbuffer_add_value (buf, type->data.array->rank);
  190. sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
  191. sigbuffer_add_value (buf, 0);
  192. break;
  193. case MONO_TYPE_GENERICINST:
  194. encode_generic_class (assembly, type->data.generic_class, buf);
  195. break;
  196. case MONO_TYPE_VAR:
  197. case MONO_TYPE_MVAR:
  198. sigbuffer_add_value (buf, type->type);
  199. sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
  200. break;
  201. default:
  202. g_error ("need to encode type %x", type->type);
  203. }
  204. }
  205. static void
  206. encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionTypeHandle type, SigBuffer *buf, MonoError *error)
  207. {
  208. MONO_REQ_GC_UNSAFE_MODE;
  209. error_init (error);
  210. if (MONO_HANDLE_IS_NULL (type)) {
  211. sigbuffer_add_value (buf, MONO_TYPE_VOID);
  212. return;
  213. }
  214. MonoType *t = mono_reflection_type_handle_mono_type (type, error);
  215. return_if_nok (error);
  216. encode_type (assembly, t, buf);
  217. }
  218. static void
  219. encode_reflection_type_raw (MonoDynamicImage *assembly, MonoReflectionType* type_raw, SigBuffer *buf, MonoError *error)
  220. {
  221. HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_reflection_type_raw should use handles */
  222. error_init (error);
  223. MONO_HANDLE_DCL (MonoReflectionType, type);
  224. encode_reflection_type (assembly, type, buf, error);
  225. HANDLE_FUNCTION_RETURN ();
  226. }
  227. static void
  228. encode_custom_modifiers (MonoDynamicImage *assembly, MonoArrayHandle modreq, MonoArrayHandle modopt, SigBuffer *buf, MonoError *error)
  229. {
  230. HANDLE_FUNCTION_ENTER ();
  231. MONO_REQ_GC_UNSAFE_MODE;
  232. int i;
  233. error_init (error);
  234. /* Have to follow .NET Framework behavior here. For an IL type spec like:
  235. * int32 modreq(A) modreq(B) modopt(C) modopt(D)
  236. *
  237. * we emit:
  238. * cmod_opt [encoding of D] cmod_opt [encoding of C] cmod_req [encoding of B] cmod_req [encoding of A] I4.
  239. *
  240. * Even though the reflection API specifies required and optional
  241. * modifiers in separate arrays, the .NET Framework creates a typespec
  242. * as above: required mods first, then optional. (And so we emit the
  243. * optional ones first, then required).
  244. */
  245. if (!MONO_HANDLE_IS_NULL (modopt)) {
  246. int count = mono_array_handle_length (modopt);
  247. g_assert (count > 0);
  248. for (i = count - 1; i >= 0 ; --i) {
  249. MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
  250. goto_if_nok (error, leave);
  251. sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
  252. sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
  253. }
  254. }
  255. if (!MONO_HANDLE_IS_NULL (modreq)) {
  256. int count = mono_array_handle_length (modreq);
  257. g_assert (count > 0);
  258. for (i = count - 1; i >= 0 ; --i) {
  259. MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
  260. goto_if_nok (error, leave);
  261. sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
  262. sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
  263. }
  264. }
  265. leave:
  266. HANDLE_FUNCTION_RETURN ();
  267. }
  268. static void
  269. encode_custom_modifiers_raw (MonoDynamicImage *assembly, MonoArray *modreq_raw, MonoArray *modopt_raw, SigBuffer *buf, MonoError *error)
  270. {
  271. HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_custom_modifiers_raw should use handles */
  272. error_init (error);
  273. MONO_HANDLE_DCL (MonoArray, modreq);
  274. MONO_HANDLE_DCL (MonoArray, modopt);
  275. encode_custom_modifiers (assembly, modreq, modopt, buf, error);
  276. HANDLE_FUNCTION_RETURN ();
  277. }
  278. #ifndef DISABLE_REFLECTION_EMIT
  279. guint32
  280. mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
  281. {
  282. MONO_REQ_GC_UNSAFE_MODE;
  283. SigBuffer buf;
  284. int i;
  285. guint32 nparams = sig->param_count;
  286. guint32 idx;
  287. if (!assembly->save)
  288. return 0;
  289. sigbuffer_init (&buf, 32);
  290. /*
  291. * FIXME: vararg, explicit_this, differenc call_conv values...
  292. */
  293. idx = sig->call_convention;
  294. if (sig->hasthis)
  295. idx |= 0x20; /* hasthis */
  296. if (sig->generic_param_count)
  297. idx |= 0x10; /* generic */
  298. sigbuffer_add_byte (&buf, idx);
  299. if (sig->generic_param_count)
  300. sigbuffer_add_value (&buf, sig->generic_param_count);
  301. sigbuffer_add_value (&buf, nparams);
  302. encode_type (assembly, sig->ret, &buf);
  303. for (i = 0; i < nparams; ++i) {
  304. if (i == sig->sentinelpos)
  305. sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
  306. encode_type (assembly, sig->params [i], &buf);
  307. }
  308. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  309. sigbuffer_free (&buf);
  310. return idx;
  311. }
  312. #else /* DISABLE_REFLECTION_EMIT */
  313. guint32
  314. mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
  315. {
  316. g_assert_not_reached ();
  317. return 0;
  318. }
  319. #endif
  320. guint32
  321. mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
  322. {
  323. MONO_REQ_GC_UNSAFE_MODE;
  324. error_init (error);
  325. /*
  326. * FIXME: reuse code from method_encode_signature().
  327. */
  328. SigBuffer buf;
  329. int i;
  330. guint32 nparams = mb->parameters ? mono_array_length_internal (mb->parameters): 0;
  331. guint32 ngparams = mb->generic_params ? mono_array_length_internal (mb->generic_params): 0;
  332. guint32 notypes = mb->opt_types ? mono_array_length_internal (mb->opt_types): 0;
  333. guint32 idx;
  334. sigbuffer_init (&buf, 32);
  335. /* LAMESPEC: all the call conv spec is foobared */
  336. idx = mb->call_conv & 0x60; /* has-this, explicit-this */
  337. if (mb->call_conv & 2)
  338. idx |= 0x5; /* vararg */
  339. if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
  340. idx |= 0x20; /* hasthis */
  341. if (ngparams)
  342. idx |= 0x10; /* generic */
  343. sigbuffer_add_byte (&buf, idx);
  344. if (ngparams)
  345. sigbuffer_add_value (&buf, ngparams);
  346. sigbuffer_add_value (&buf, nparams + notypes);
  347. encode_custom_modifiers_raw (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
  348. goto_if_nok (error, leave);
  349. encode_reflection_type_raw (assembly, mb->rtype, &buf, error);
  350. goto_if_nok (error, leave);
  351. for (i = 0; i < nparams; ++i) {
  352. MonoArray *modreq = NULL;
  353. MonoArray *modopt = NULL;
  354. MonoReflectionType *pt;
  355. if (mb->param_modreq && (i < mono_array_length_internal (mb->param_modreq)))
  356. modreq = mono_array_get_internal (mb->param_modreq, MonoArray*, i);
  357. if (mb->param_modopt && (i < mono_array_length_internal (mb->param_modopt)))
  358. modopt = mono_array_get_internal (mb->param_modopt, MonoArray*, i);
  359. encode_custom_modifiers_raw (assembly, modreq, modopt, &buf, error);
  360. goto_if_nok (error, leave);
  361. pt = mono_array_get_internal (mb->parameters, MonoReflectionType*, i);
  362. encode_reflection_type_raw (assembly, pt, &buf, error);
  363. goto_if_nok (error, leave);
  364. }
  365. if (notypes)
  366. sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
  367. for (i = 0; i < notypes; ++i) {
  368. MonoReflectionType *pt;
  369. pt = mono_array_get_internal (mb->opt_types, MonoReflectionType*, i);
  370. encode_reflection_type_raw (assembly, pt, &buf, error);
  371. goto_if_nok (error, leave);
  372. }
  373. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  374. leave:
  375. sigbuffer_free (&buf);
  376. return idx;
  377. }
  378. guint32
  379. mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
  380. {
  381. MONO_REQ_GC_UNSAFE_MODE;
  382. error_init (error);
  383. MonoDynamicTable *table;
  384. guint32 *values;
  385. guint32 idx, sig_idx;
  386. guint nl = mono_array_length_internal (ilgen->locals);
  387. SigBuffer buf;
  388. int i;
  389. sigbuffer_init (&buf, 32);
  390. sigbuffer_add_value (&buf, 0x07);
  391. sigbuffer_add_value (&buf, nl);
  392. for (i = 0; i < nl; ++i) {
  393. MonoReflectionLocalBuilder *lb = mono_array_get_internal (ilgen->locals, MonoReflectionLocalBuilder*, i);
  394. if (lb->is_pinned)
  395. sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
  396. encode_reflection_type_raw (assembly, (MonoReflectionType*)lb->type, &buf, error);
  397. if (!is_ok (error)) {
  398. sigbuffer_free (&buf);
  399. return 0;
  400. }
  401. }
  402. sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  403. sigbuffer_free (&buf);
  404. if (assembly->standalonesig_cache == NULL)
  405. assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
  406. idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
  407. if (idx)
  408. return idx;
  409. table = &assembly->tables [MONO_TABLE_STANDALONESIG];
  410. idx = table->next_idx ++;
  411. table->rows ++;
  412. alloc_table (table, table->rows);
  413. values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
  414. values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
  415. g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
  416. return idx;
  417. }
  418. /*
  419. * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
  420. * dest may be misaligned.
  421. */
  422. #if G_BYTE_ORDER != G_LITTLE_ENDIAN
  423. static void
  424. swap_with_size (char *dest, const char* val, int len, int nelem) {
  425. MONO_REQ_GC_NEUTRAL_MODE;
  426. int elem;
  427. for (elem = 0; elem < nelem; ++elem) {
  428. switch (len) {
  429. case 1:
  430. *dest = *val;
  431. break;
  432. case 2:
  433. dest [0] = val [1];
  434. dest [1] = val [0];
  435. break;
  436. case 4:
  437. dest [0] = val [3];
  438. dest [1] = val [2];
  439. dest [2] = val [1];
  440. dest [3] = val [0];
  441. break;
  442. case 8:
  443. dest [0] = val [7];
  444. dest [1] = val [6];
  445. dest [2] = val [5];
  446. dest [3] = val [4];
  447. dest [4] = val [3];
  448. dest [5] = val [2];
  449. dest [6] = val [1];
  450. dest [7] = val [0];
  451. break;
  452. default:
  453. g_assert_not_reached ();
  454. }
  455. dest += len;
  456. val += len;
  457. }
  458. }
  459. #endif
  460. guint32
  461. mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
  462. {
  463. MONO_REQ_GC_UNSAFE_MODE;
  464. char blob_size [64];
  465. char *b = blob_size;
  466. gpointer box_val;
  467. char* buf;
  468. guint32 idx = 0, len = 0, dummy = 0;
  469. buf = (char *)g_malloc (64);
  470. if (!val) {
  471. *ret_type = MONO_TYPE_CLASS;
  472. len = 4;
  473. box_val = &dummy;
  474. } else {
  475. box_val = mono_object_get_data (val);
  476. *ret_type = m_class_get_byval_arg (val->vtable->klass)->type;
  477. }
  478. handle_enum:
  479. switch (*ret_type) {
  480. case MONO_TYPE_BOOLEAN:
  481. case MONO_TYPE_U1:
  482. case MONO_TYPE_I1:
  483. len = 1;
  484. break;
  485. case MONO_TYPE_CHAR:
  486. case MONO_TYPE_U2:
  487. case MONO_TYPE_I2:
  488. len = 2;
  489. break;
  490. case MONO_TYPE_U4:
  491. case MONO_TYPE_I4:
  492. case MONO_TYPE_R4:
  493. len = 4;
  494. break;
  495. case MONO_TYPE_U8:
  496. case MONO_TYPE_I8:
  497. len = 8;
  498. break;
  499. case MONO_TYPE_R8:
  500. len = 8;
  501. break;
  502. case MONO_TYPE_VALUETYPE: {
  503. MonoClass *klass = val->vtable->klass;
  504. if (m_class_is_enumtype (klass)) {
  505. *ret_type = mono_class_enum_basetype_internal (klass)->type;
  506. goto handle_enum;
  507. } else if (mono_is_corlib_image (m_class_get_image (klass)) && strcmp (m_class_get_name_space (klass), "System") == 0 && strcmp (m_class_get_name (klass), "DateTime") == 0) {
  508. len = 8;
  509. } else
  510. g_error ("we can't encode valuetypes, we should have never reached this line");
  511. break;
  512. }
  513. case MONO_TYPE_CLASS:
  514. break;
  515. case MONO_TYPE_STRING: {
  516. MonoString *str = (MonoString*)val;
  517. /* there is no signature */
  518. len = str->length * 2;
  519. mono_metadata_encode_value (len, b, &b);
  520. #if G_BYTE_ORDER != G_LITTLE_ENDIAN
  521. {
  522. char *swapped = g_malloc (2 * mono_string_length_internal (str));
  523. const char *p = (const char*)mono_string_chars_internal (str);
  524. swap_with_size (swapped, p, 2, mono_string_length_internal (str));
  525. idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
  526. g_free (swapped);
  527. }
  528. #else
  529. idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, mono_string_chars_internal (str), len);
  530. #endif
  531. g_free (buf);
  532. return idx;
  533. }
  534. case MONO_TYPE_GENERICINST:
  535. *ret_type = m_class_get_byval_arg (mono_class_get_generic_class (val->vtable->klass)->container_class)->type;
  536. goto handle_enum;
  537. default:
  538. g_error ("we don't encode constant type 0x%02x yet", *ret_type);
  539. }
  540. /* there is no signature */
  541. mono_metadata_encode_value (len, b, &b);
  542. #if G_BYTE_ORDER != G_LITTLE_ENDIAN
  543. idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
  544. swap_with_size (blob_size, (const char*)box_val, len, 1);
  545. mono_image_add_stream_data (&assembly->blob, blob_size, len);
  546. #else
  547. idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
  548. #endif
  549. g_free (buf);
  550. return idx;
  551. }
  552. guint32
  553. mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
  554. {
  555. MONO_REQ_GC_UNSAFE_MODE;
  556. error_init (error);
  557. SigBuffer buf;
  558. guint32 idx;
  559. guint32 typespec = 0;
  560. MonoType *type;
  561. MonoClass *klass;
  562. type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
  563. return_val_if_nok (error, 0);
  564. klass = mono_class_from_mono_type_internal (type);
  565. sigbuffer_init (&buf, 32);
  566. sigbuffer_add_value (&buf, 0x06);
  567. encode_custom_modifiers_raw (assembly, fb->modreq, fb->modopt, &buf, error);
  568. goto_if_nok (error, fail);
  569. /* encode custom attributes before the type */
  570. if (mono_class_is_gtd (klass))
  571. typespec = create_typespec (assembly, type);
  572. if (typespec) {
  573. MonoGenericClass *gclass;
  574. gclass = mono_metadata_lookup_generic_class (klass, mono_class_get_generic_container (klass)->context.class_inst, TRUE);
  575. encode_generic_class (assembly, gclass, &buf);
  576. } else {
  577. encode_type (assembly, type, &buf);
  578. }
  579. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  580. sigbuffer_free (&buf);
  581. return idx;
  582. fail:
  583. sigbuffer_free (&buf);
  584. return 0;
  585. }
  586. #ifndef DISABLE_REFLECTION_EMIT
  587. /*field_image is the image to which the eventual custom mods have been encoded against*/
  588. guint32
  589. mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
  590. {
  591. MONO_REQ_GC_NEUTRAL_MODE;
  592. SigBuffer buf;
  593. guint32 idx, i, token;
  594. if (!assembly->save)
  595. return 0;
  596. sigbuffer_init (&buf, 32);
  597. sigbuffer_add_value (&buf, 0x06);
  598. /* encode custom attributes before the type */
  599. if (type->has_cmods) {
  600. MonoCustomModContainer *cmods = mono_type_get_cmods (type);
  601. for (i = 0; i < cmods->count; ++i) {
  602. if (field_image) {
  603. ERROR_DECL (error);
  604. MonoClass *klass = mono_class_get_checked (field_image, cmods->modifiers [i].token, error);
  605. g_assert (is_ok (error)); /* FIXME don't swallow the error */
  606. token = mono_image_typedef_or_ref (assembly, m_class_get_byval_arg (klass));
  607. } else {
  608. token = cmods->modifiers [i].token;
  609. }
  610. if (cmods->modifiers [i].required)
  611. sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
  612. else
  613. sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
  614. sigbuffer_add_value (&buf, token);
  615. }
  616. }
  617. encode_type (assembly, type, &buf);
  618. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  619. sigbuffer_free (&buf);
  620. return idx;
  621. }
  622. #else /* DISABLE_REFLECTION_EMIT */
  623. guint32
  624. mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
  625. {
  626. g_assert_not_reached ();
  627. return 0;
  628. }
  629. #endif /* DISABLE_REFLECTION_EMIT */
  630. static guint32
  631. create_typespec (MonoDynamicImage *assembly, MonoType *type)
  632. {
  633. MONO_REQ_GC_NEUTRAL_MODE;
  634. MonoDynamicTable *table;
  635. guint32 *values;
  636. guint32 token;
  637. SigBuffer buf;
  638. if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
  639. return token;
  640. sigbuffer_init (&buf, 32);
  641. switch (type->type) {
  642. case MONO_TYPE_FNPTR:
  643. case MONO_TYPE_PTR:
  644. case MONO_TYPE_SZARRAY:
  645. case MONO_TYPE_ARRAY:
  646. case MONO_TYPE_VAR:
  647. case MONO_TYPE_MVAR:
  648. case MONO_TYPE_GENERICINST:
  649. encode_type (assembly, type, &buf);
  650. break;
  651. case MONO_TYPE_CLASS:
  652. case MONO_TYPE_VALUETYPE: {
  653. MonoClass *k = mono_class_from_mono_type_internal (type);
  654. if (!k || !mono_class_is_gtd (k)) {
  655. sigbuffer_free (&buf);
  656. return 0;
  657. }
  658. encode_type (assembly, type, &buf);
  659. break;
  660. }
  661. default:
  662. sigbuffer_free (&buf);
  663. return 0;
  664. }
  665. table = &assembly->tables [MONO_TABLE_TYPESPEC];
  666. if (assembly->save) {
  667. token = sigbuffer_add_to_blob_cached (assembly, &buf);
  668. alloc_table (table, table->rows + 1);
  669. values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
  670. values [MONO_TYPESPEC_SIGNATURE] = token;
  671. }
  672. sigbuffer_free (&buf);
  673. token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
  674. g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
  675. table->next_idx ++;
  676. return token;
  677. }
  678. guint32
  679. mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
  680. {
  681. MONO_REQ_GC_UNSAFE_MODE;
  682. HANDLE_FUNCTION_ENTER ();
  683. MonoDynamicTable *table;
  684. guint32 *values;
  685. guint32 token, scope, enclosing;
  686. MonoClass *klass;
  687. /* if the type requires a typespec, we must try that first*/
  688. if (try_typespec && (token = create_typespec (assembly, type)))
  689. goto leave;
  690. token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
  691. if (token)
  692. goto leave;
  693. klass = mono_class_from_mono_type_internal (type);
  694. MonoReflectionTypeBuilderHandle tb;
  695. tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, mono_class_get_ref_info (klass));
  696. /*
  697. * If it's in the same module and not a generic type parameter:
  698. */
  699. if ((m_class_get_image (klass) == &assembly->image) && (type->type != MONO_TYPE_VAR) &&
  700. (type->type != MONO_TYPE_MVAR)) {
  701. token = MONO_TYPEDEFORREF_TYPEDEF | (MONO_HANDLE_GETVAL (tb, table_idx) << MONO_TYPEDEFORREF_BITS);
  702. /* This function is called multiple times from sre and sre-save, so same object is okay */
  703. mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
  704. goto leave;
  705. }
  706. if (m_class_get_nested_in (klass)) {
  707. enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, m_class_get_byval_arg (m_class_get_nested_in (klass)), FALSE);
  708. /* get the typeref idx of the enclosing type */
  709. enclosing >>= MONO_TYPEDEFORREF_BITS;
  710. scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
  711. } else {
  712. scope = mono_reflection_resolution_scope_from_image (assembly, m_class_get_image (klass));
  713. }
  714. table = &assembly->tables [MONO_TABLE_TYPEREF];
  715. if (assembly->save) {
  716. alloc_table (table, table->rows + 1);
  717. values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
  718. values [MONO_TYPEREF_SCOPE] = scope;
  719. values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, m_class_get_name (klass));
  720. values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, m_class_get_name_space (klass));
  721. }
  722. token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
  723. g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
  724. table->next_idx ++;
  725. if (!MONO_HANDLE_IS_NULL (tb)) {
  726. /* This function is called multiple times from sre and sre-save, so same object is okay */
  727. mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
  728. }
  729. leave:
  730. HANDLE_FUNCTION_RETURN_VAL (token);
  731. }
  732. /*
  733. * Despite the name, we handle also TypeSpec (with the above helper).
  734. */
  735. static guint32
  736. mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
  737. {
  738. return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
  739. }
  740. guint32
  741. mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
  742. {
  743. SigBuffer buf;
  744. int i;
  745. guint32 nparams = context->method_inst->type_argc;
  746. guint32 idx;
  747. if (!assembly->save)
  748. return 0;
  749. sigbuffer_init (&buf, 32);
  750. /*
  751. * FIXME: vararg, explicit_this, differenc call_conv values...
  752. */
  753. sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
  754. sigbuffer_add_value (&buf, nparams);
  755. for (i = 0; i < nparams; i++)
  756. encode_type (assembly, context->method_inst->type_argv [i], &buf);
  757. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  758. sigbuffer_free (&buf);
  759. return idx;
  760. }
  761. #ifndef DISABLE_REFLECTION_EMIT
  762. static gboolean
  763. encode_sighelper_arg (MonoDynamicImage *assembly, int i, MonoArrayHandle helper_arguments, MonoArrayHandle helper_modreqs, MonoArrayHandle helper_modopts, SigBuffer* buf, MonoError *error)
  764. {
  765. HANDLE_FUNCTION_ENTER();
  766. error_init (error);
  767. MonoArrayHandle modreqs = MONO_HANDLE_NEW (MonoArray, NULL);
  768. MonoArrayHandle modopts = MONO_HANDLE_NEW (MonoArray, NULL);
  769. if (!MONO_HANDLE_IS_NULL (helper_modreqs) && (i < mono_array_handle_length (helper_modreqs)))
  770. MONO_HANDLE_ARRAY_GETREF (modreqs, helper_modreqs, i);
  771. if (!MONO_HANDLE_IS_NULL (helper_modopts) && (i < mono_array_handle_length (helper_modopts)))
  772. MONO_HANDLE_ARRAY_GETREF (modopts, helper_modopts, i);
  773. encode_custom_modifiers (assembly, modreqs, modopts, buf, error);
  774. goto_if_nok (error, leave);
  775. MonoReflectionTypeHandle pt;
  776. pt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
  777. MONO_HANDLE_ARRAY_GETREF (pt, helper_arguments, i);
  778. encode_reflection_type (assembly, pt, buf, error);
  779. goto_if_nok (error, leave);
  780. leave:
  781. HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
  782. }
  783. guint32
  784. mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
  785. {
  786. SigBuffer buf;
  787. guint32 nargs;
  788. guint32 i, idx;
  789. error_init (error);
  790. if (!assembly->save)
  791. return 0;
  792. /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
  793. g_assert (MONO_HANDLE_GETVAL (helper, type) == 2);
  794. MonoArrayHandle arguments = MONO_HANDLE_NEW_GET (MonoArray, helper, arguments);
  795. if (!MONO_HANDLE_IS_NULL (arguments))
  796. nargs = mono_array_handle_length (arguments);
  797. else
  798. nargs = 0;
  799. sigbuffer_init (&buf, 32);
  800. /* Encode calling convention */
  801. /* Change Any to Standard */
  802. if ((MONO_HANDLE_GETVAL (helper, call_conv) & 0x03) == 0x03)
  803. MONO_HANDLE_SETVAL (helper, call_conv, guint32, 0x01);
  804. /* explicit_this implies has_this */
  805. if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x40)
  806. MONO_HANDLE_SETVAL (helper, call_conv, guint32, MONO_HANDLE_GETVAL (helper, call_conv) & 0x20);
  807. if (MONO_HANDLE_GETVAL (helper, call_conv) == 0) { /* Unmanaged */
  808. idx = MONO_HANDLE_GETVAL (helper, unmanaged_call_conv) - 1;
  809. } else {
  810. /* Managed */
  811. idx = MONO_HANDLE_GETVAL (helper, call_conv) & 0x60; /* has_this + explicit_this */
  812. if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x02) /* varargs */
  813. idx += 0x05;
  814. }
  815. sigbuffer_add_byte (&buf, idx);
  816. sigbuffer_add_value (&buf, nargs);
  817. encode_reflection_type (assembly, MONO_HANDLE_NEW_GET (MonoReflectionType, helper, return_type), &buf, error);
  818. goto_if_nok (error, fail);
  819. MonoArrayHandle modreqs;
  820. modreqs = MONO_HANDLE_NEW_GET (MonoArray, helper, modreqs);
  821. MonoArrayHandle modopts;
  822. modopts = MONO_HANDLE_NEW_GET (MonoArray, helper, modopts);
  823. for (i = 0; i < nargs; ++i) {
  824. if (!encode_sighelper_arg (assembly, i, arguments, modreqs, modopts, &buf, error))
  825. goto fail;
  826. }
  827. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  828. sigbuffer_free (&buf);
  829. return idx;
  830. fail:
  831. sigbuffer_free (&buf);
  832. return 0;
  833. }
  834. #else /* DISABLE_REFLECTION_EMIT */
  835. guint32
  836. mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
  837. {
  838. g_assert_not_reached ();
  839. return 0;
  840. }
  841. #endif /* DISABLE_REFLECTION_EMIT */
  842. static gboolean
  843. encode_reflection_types (MonoDynamicImage *assembly, MonoArrayHandle sig_arguments, int i, SigBuffer *buf, MonoError *error)
  844. {
  845. HANDLE_FUNCTION_ENTER ();
  846. error_init (error);
  847. MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
  848. MONO_HANDLE_ARRAY_GETREF (type, sig_arguments, i);
  849. encode_reflection_type (assembly, type, buf, error);
  850. HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
  851. }
  852. static MonoArrayHandle
  853. reflection_sighelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
  854. {
  855. MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
  856. MonoDynamicImage *assembly = MONO_HANDLE_IS_NULL (module) ? NULL : MONO_HANDLE_GETVAL (module, dynamic_image);
  857. MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
  858. guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
  859. guint32 buflen, i;
  860. SigBuffer buf;
  861. error_init (error);
  862. sigbuffer_init (&buf, 32);
  863. sigbuffer_add_value (&buf, 0x07);
  864. sigbuffer_add_value (&buf, na);
  865. if (assembly != NULL){
  866. for (i = 0; i < na; ++i) {
  867. if (!encode_reflection_types (assembly, sig_arguments, i, &buf, error))
  868. goto fail;
  869. }
  870. }
  871. buflen = buf.p - buf.buf;
  872. MonoArrayHandle result;
  873. result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
  874. goto_if_nok (error, fail);
  875. MonoGCHandle gchandle;
  876. void *base;
  877. base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
  878. memcpy (base, buf.buf, buflen);
  879. sigbuffer_free (&buf);
  880. mono_gchandle_free_internal (gchandle);
  881. return result;
  882. fail:
  883. sigbuffer_free (&buf);
  884. return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
  885. }
  886. static MonoArrayHandle
  887. reflection_sighelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
  888. {
  889. MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
  890. MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (module, dynamic_image);
  891. MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
  892. guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
  893. guint32 buflen, i;
  894. SigBuffer buf;
  895. error_init (error);
  896. sigbuffer_init (&buf, 32);
  897. sigbuffer_add_value (&buf, 0x06);
  898. for (i = 0; i < na; ++i) {
  899. if (! encode_reflection_types (assembly, sig_arguments, i, &buf, error))
  900. goto fail;
  901. }
  902. buflen = buf.p - buf.buf;
  903. MonoArrayHandle result;
  904. result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
  905. goto_if_nok (error, fail);
  906. MonoGCHandle gchandle;
  907. void *base;
  908. base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
  909. memcpy (base, buf.buf, buflen);
  910. sigbuffer_free (&buf);
  911. mono_gchandle_free_internal (gchandle);
  912. return result;
  913. fail:
  914. sigbuffer_free (&buf);
  915. return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
  916. }
  917. static char*
  918. type_get_fully_qualified_name (MonoType *type)
  919. {
  920. MONO_REQ_GC_NEUTRAL_MODE;
  921. return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
  922. }
  923. #ifndef DISABLE_REFLECTION_EMIT_SAVE
  924. guint32
  925. mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
  926. {
  927. MONO_REQ_GC_UNSAFE_MODE;
  928. error_init (error);
  929. char *str;
  930. SigBuffer buf;
  931. guint32 idx, len;
  932. sigbuffer_init (&buf, 32);
  933. sigbuffer_add_value (&buf, minfo->type);
  934. switch (minfo->type) {
  935. case MONO_NATIVE_BYVALTSTR:
  936. case MONO_NATIVE_BYVALARRAY:
  937. sigbuffer_add_value (&buf, minfo->count);
  938. break;
  939. case MONO_NATIVE_LPARRAY:
  940. if (minfo->eltype || minfo->has_size) {
  941. sigbuffer_add_value (&buf, minfo->eltype);
  942. if (minfo->has_size) {
  943. sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
  944. sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
  945. /* LAMESPEC: ElemMult is undocumented */
  946. sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
  947. }
  948. }
  949. break;
  950. case MONO_NATIVE_SAFEARRAY:
  951. if (minfo->eltype)
  952. sigbuffer_add_value (&buf, minfo->eltype);
  953. break;
  954. case MONO_NATIVE_CUSTOM:
  955. if (minfo->guid) {
  956. str = mono_string_to_utf8_checked_internal (minfo->guid, error);
  957. if (!is_ok (error)) {
  958. sigbuffer_free (&buf);
  959. return 0;
  960. }
  961. len = strlen (str);
  962. sigbuffer_add_value (&buf, len);
  963. sigbuffer_add_mem (&buf, str, len);
  964. g_free (str);
  965. } else {
  966. sigbuffer_add_value (&buf, 0);
  967. }
  968. /* native type name */
  969. sigbuffer_add_value (&buf, 0);
  970. /* custom marshaler type name */
  971. if (minfo->marshaltype || minfo->marshaltyperef) {
  972. if (minfo->marshaltyperef) {
  973. MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
  974. if (!is_ok (error)) {
  975. sigbuffer_free (&buf);
  976. return 0;
  977. }
  978. str = type_get_fully_qualified_name (marshaltype);
  979. } else {
  980. str = mono_string_to_utf8_checked_internal (minfo->marshaltype, error);
  981. if (!is_ok (error)) {
  982. sigbuffer_free (&buf);
  983. return 0;
  984. }
  985. }
  986. len = strlen (str);
  987. sigbuffer_add_value (&buf, len);
  988. sigbuffer_add_mem (&buf, str, len);
  989. g_free (str);
  990. } else {
  991. /* FIXME: Actually a bug, since this field is required. Punting for now ... */
  992. sigbuffer_add_value (&buf, 0);
  993. }
  994. if (minfo->mcookie) {
  995. str = mono_string_to_utf8_checked_internal (minfo->mcookie, error);
  996. if (!is_ok (error)) {
  997. sigbuffer_free (&buf);
  998. return 0;
  999. }
  1000. len = strlen (str);
  1001. sigbuffer_add_value (&buf, len);
  1002. sigbuffer_add_mem (&buf, str, len);
  1003. g_free (str);
  1004. } else {
  1005. sigbuffer_add_value (&buf, 0);
  1006. }
  1007. break;
  1008. default:
  1009. break;
  1010. }
  1011. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  1012. sigbuffer_free (&buf);
  1013. return idx;
  1014. }
  1015. guint32
  1016. mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
  1017. {
  1018. MONO_REQ_GC_UNSAFE_MODE;
  1019. error_init (error);
  1020. SigBuffer buf;
  1021. guint32 nparams = 0;
  1022. MonoReflectionMethodBuilder *mb = fb->get_method;
  1023. MonoReflectionMethodBuilder *smb = fb->set_method;
  1024. guint32 idx, i;
  1025. if (mb && mb->parameters)
  1026. nparams = mono_array_length_internal (mb->parameters);
  1027. if (!mb && smb && smb->parameters)
  1028. nparams = mono_array_length_internal (smb->parameters) - 1;
  1029. sigbuffer_init (&buf, 32);
  1030. if (fb->call_conv & 0x20)
  1031. sigbuffer_add_byte (&buf, 0x28);
  1032. else
  1033. sigbuffer_add_byte (&buf, 0x08);
  1034. sigbuffer_add_value (&buf, nparams);
  1035. if (mb) {
  1036. encode_reflection_type_raw (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
  1037. if (!is_ok (error))
  1038. goto fail;
  1039. for (i = 0; i < nparams; ++i) {
  1040. MonoReflectionType *pt = mono_array_get_internal (mb->parameters, MonoReflectionType*, i);
  1041. encode_reflection_type_raw (assembly, pt, &buf, error);
  1042. if (!is_ok (error))
  1043. goto fail;
  1044. }
  1045. } else if (smb && smb->parameters) {
  1046. /* the property type is the last param */
  1047. encode_reflection_type_raw (assembly, mono_array_get_internal (smb->parameters, MonoReflectionType*, nparams), &buf, error);
  1048. if (!is_ok (error))
  1049. goto fail;
  1050. for (i = 0; i < nparams; ++i) {
  1051. MonoReflectionType *pt = mono_array_get_internal (smb->parameters, MonoReflectionType*, i);
  1052. encode_reflection_type_raw (assembly, pt, &buf, error);
  1053. if (!is_ok (error))
  1054. goto fail;
  1055. }
  1056. } else {
  1057. encode_reflection_type_raw (assembly, (MonoReflectionType*)fb->type, &buf, error);
  1058. if (!is_ok (error))
  1059. goto fail;
  1060. }
  1061. idx = sigbuffer_add_to_blob_cached (assembly, &buf);
  1062. sigbuffer_free (&buf);
  1063. return idx;
  1064. fail:
  1065. sigbuffer_free (&buf);
  1066. return 0;
  1067. }
  1068. #else /*DISABLE_REFLECTION_EMIT_SAVE*/
  1069. guint32
  1070. mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
  1071. {
  1072. g_assert_not_reached ();
  1073. return 0;
  1074. }
  1075. guint32
  1076. mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
  1077. {
  1078. g_assert_not_reached ();
  1079. return 0;
  1080. }
  1081. #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
  1082. #ifndef DISABLE_REFLECTION_EMIT
  1083. MonoArrayHandle
  1084. ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
  1085. {
  1086. error_init (error);
  1087. return reflection_sighelper_get_signature_local (sig, error);
  1088. }
  1089. MonoArrayHandle
  1090. ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
  1091. {
  1092. error_init (error);
  1093. return reflection_sighelper_get_signature_field (sig, error);
  1094. }
  1095. #else /* DISABLE_REFLECTION_EMIT */
  1096. MonoArrayHandle
  1097. ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
  1098. {
  1099. error_init (error);
  1100. g_assert_not_reached ();
  1101. return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
  1102. }
  1103. MonoArrayHandle
  1104. ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
  1105. {
  1106. error_init (error);
  1107. g_assert_not_reached ();
  1108. return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
  1109. }
  1110. #endif /* DISABLE_REFLECTION_EMIT */