lj_cconv.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. /*
  2. ** C type conversions.
  3. ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
  4. */
  5. #include "lj_obj.h"
  6. #if LJ_HASFFI
  7. #include "lj_err.h"
  8. #include "lj_tab.h"
  9. #include "lj_ctype.h"
  10. #include "lj_cdata.h"
  11. #include "lj_cconv.h"
  12. #include "lj_ccallback.h"
  13. /* -- Conversion errors --------------------------------------------------- */
  14. /* Bad conversion. */
  15. LJ_NORET static void cconv_err_conv(CTState *cts, CType *d, CType *s,
  16. CTInfo flags)
  17. {
  18. const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
  19. const char *src;
  20. if ((flags & CCF_FROMTV))
  21. src = lj_obj_typename[1+(ctype_isnum(s->info) ? LUA_TNUMBER :
  22. ctype_isarray(s->info) ? LUA_TSTRING : LUA_TNIL)];
  23. else
  24. src = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, s), NULL));
  25. if (CCF_GETARG(flags))
  26. lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst);
  27. else
  28. lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
  29. }
  30. /* Bad conversion from TValue. */
  31. LJ_NORET static void cconv_err_convtv(CTState *cts, CType *d, TValue *o,
  32. CTInfo flags)
  33. {
  34. const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
  35. const char *src = lj_typename(o);
  36. if (CCF_GETARG(flags))
  37. lj_err_argv(cts->L, CCF_GETARG(flags), LJ_ERR_FFI_BADCONV, src, dst);
  38. else
  39. lj_err_callerv(cts->L, LJ_ERR_FFI_BADCONV, src, dst);
  40. }
  41. /* Initializer overflow. */
  42. LJ_NORET static void cconv_err_initov(CTState *cts, CType *d)
  43. {
  44. const char *dst = strdata(lj_ctype_repr(cts->L, ctype_typeid(cts, d), NULL));
  45. lj_err_callerv(cts->L, LJ_ERR_FFI_INITOV, dst);
  46. }
  47. /* -- C type compatibility checks ----------------------------------------- */
  48. /* Get raw type and qualifiers for a child type. Resolves enums, too. */
  49. static CType *cconv_childqual(CTState *cts, CType *ct, CTInfo *qual)
  50. {
  51. ct = ctype_child(cts, ct);
  52. for (;;) {
  53. if (ctype_isattrib(ct->info)) {
  54. if (ctype_attrib(ct->info) == CTA_QUAL) *qual |= ct->size;
  55. } else if (!ctype_isenum(ct->info)) {
  56. break;
  57. }
  58. ct = ctype_child(cts, ct);
  59. }
  60. *qual |= (ct->info & CTF_QUAL);
  61. return ct;
  62. }
  63. /* Check for compatible types when converting to a pointer.
  64. ** Note: these checks are more relaxed than what C99 mandates.
  65. */
  66. int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags)
  67. {
  68. if (!((flags & CCF_CAST) || d == s)) {
  69. CTInfo dqual = 0, squal = 0;
  70. d = cconv_childqual(cts, d, &dqual);
  71. if (!ctype_isstruct(s->info))
  72. s = cconv_childqual(cts, s, &squal);
  73. if ((flags & CCF_SAME)) {
  74. if (dqual != squal)
  75. return 0; /* Different qualifiers. */
  76. } else if (!(flags & CCF_IGNQUAL)) {
  77. if ((dqual & squal) != squal)
  78. return 0; /* Discarded qualifiers. */
  79. if (ctype_isvoid(d->info) || ctype_isvoid(s->info))
  80. return 1; /* Converting to/from void * is always ok. */
  81. }
  82. if (ctype_type(d->info) != ctype_type(s->info) ||
  83. d->size != s->size)
  84. return 0; /* Different type or different size. */
  85. if (ctype_isnum(d->info)) {
  86. if (((d->info ^ s->info) & (CTF_BOOL|CTF_FP)))
  87. return 0; /* Different numeric types. */
  88. } else if (ctype_ispointer(d->info)) {
  89. /* Check child types for compatibility. */
  90. return lj_cconv_compatptr(cts, d, s, flags|CCF_SAME);
  91. } else if (ctype_isstruct(d->info)) {
  92. if (d != s)
  93. return 0; /* Must be exact same type for struct/union. */
  94. } else if (ctype_isfunc(d->info)) {
  95. /* NYI: structural equality of functions. */
  96. }
  97. }
  98. return 1; /* Types are compatible. */
  99. }
  100. /* -- C type to C type conversion ----------------------------------------- */
  101. /* Convert C type to C type. Caveat: expects to get the raw CType!
  102. **
  103. ** Note: This is only used by the interpreter and not optimized at all.
  104. ** The JIT compiler will do a much better job specializing for each case.
  105. */
  106. void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
  107. uint8_t *dp, uint8_t *sp, CTInfo flags)
  108. {
  109. CTSize dsize = d->size, ssize = s->size;
  110. CTInfo dinfo = d->info, sinfo = s->info;
  111. void *tmpptr;
  112. lua_assert(!ctype_isenum(dinfo) && !ctype_isenum(sinfo));
  113. lua_assert(!ctype_isattrib(dinfo) && !ctype_isattrib(sinfo));
  114. if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
  115. goto err_conv;
  116. /* Some basic sanity checks. */
  117. lua_assert(!ctype_isnum(dinfo) || dsize > 0);
  118. lua_assert(!ctype_isnum(sinfo) || ssize > 0);
  119. lua_assert(!ctype_isbool(dinfo) || dsize == 1 || dsize == 4);
  120. lua_assert(!ctype_isbool(sinfo) || ssize == 1 || ssize == 4);
  121. lua_assert(!ctype_isinteger(dinfo) || (1u<<lj_fls(dsize)) == dsize);
  122. lua_assert(!ctype_isinteger(sinfo) || (1u<<lj_fls(ssize)) == ssize);
  123. switch (cconv_idx2(dinfo, sinfo)) {
  124. /* Destination is a bool. */
  125. case CCX(B, B):
  126. /* Source operand is already normalized. */
  127. if (dsize == 1) *dp = *sp; else *(int *)dp = *sp;
  128. break;
  129. case CCX(B, I): {
  130. MSize i;
  131. uint8_t b = 0;
  132. for (i = 0; i < ssize; i++) b |= sp[i];
  133. b = (b != 0);
  134. if (dsize == 1) *dp = b; else *(int *)dp = b;
  135. break;
  136. }
  137. case CCX(B, F): {
  138. uint8_t b;
  139. if (ssize == sizeof(double)) b = (*(double *)sp != 0);
  140. else if (ssize == sizeof(float)) b = (*(float *)sp != 0);
  141. else goto err_conv; /* NYI: long double. */
  142. if (dsize == 1) *dp = b; else *(int *)dp = b;
  143. break;
  144. }
  145. /* Destination is an integer. */
  146. case CCX(I, B):
  147. case CCX(I, I):
  148. conv_I_I:
  149. if (dsize > ssize) { /* Zero-extend or sign-extend LSB. */
  150. #if LJ_LE
  151. uint8_t fill = (!(sinfo & CTF_UNSIGNED) && (sp[ssize-1]&0x80)) ? 0xff : 0;
  152. memcpy(dp, sp, ssize);
  153. memset(dp + ssize, fill, dsize-ssize);
  154. #else
  155. uint8_t fill = (!(sinfo & CTF_UNSIGNED) && (sp[0]&0x80)) ? 0xff : 0;
  156. memset(dp, fill, dsize-ssize);
  157. memcpy(dp + (dsize-ssize), sp, ssize);
  158. #endif
  159. } else { /* Copy LSB. */
  160. #if LJ_LE
  161. memcpy(dp, sp, dsize);
  162. #else
  163. memcpy(dp, sp + (ssize-dsize), dsize);
  164. #endif
  165. }
  166. break;
  167. case CCX(I, F): {
  168. double n; /* Always convert via double. */
  169. conv_I_F:
  170. /* Convert source to double. */
  171. if (ssize == sizeof(double)) n = *(double *)sp;
  172. else if (ssize == sizeof(float)) n = (double)*(float *)sp;
  173. else goto err_conv; /* NYI: long double. */
  174. /* Then convert double to integer. */
  175. /* The conversion must exactly match the semantics of JIT-compiled code! */
  176. if (dsize < 4 || (dsize == 4 && !(dinfo & CTF_UNSIGNED))) {
  177. int32_t i = (int32_t)n;
  178. if (dsize == 4) *(int32_t *)dp = i;
  179. else if (dsize == 2) *(int16_t *)dp = (int16_t)i;
  180. else *(int8_t *)dp = (int8_t)i;
  181. } else if (dsize == 4) {
  182. *(uint32_t *)dp = (uint32_t)n;
  183. } else if (dsize == 8) {
  184. if (!(dinfo & CTF_UNSIGNED))
  185. *(int64_t *)dp = (int64_t)n;
  186. else
  187. *(uint64_t *)dp = lj_num2u64(n);
  188. } else {
  189. goto err_conv; /* NYI: conversion to >64 bit integers. */
  190. }
  191. break;
  192. }
  193. case CCX(I, C):
  194. s = ctype_child(cts, s);
  195. sinfo = s->info;
  196. ssize = s->size;
  197. goto conv_I_F; /* Just convert re. */
  198. case CCX(I, P):
  199. if (!(flags & CCF_CAST)) goto err_conv;
  200. sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
  201. goto conv_I_I;
  202. case CCX(I, A):
  203. if (!(flags & CCF_CAST)) goto err_conv;
  204. sinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
  205. ssize = CTSIZE_PTR;
  206. tmpptr = sp;
  207. sp = (uint8_t *)&tmpptr;
  208. goto conv_I_I;
  209. /* Destination is a floating-point number. */
  210. case CCX(F, B):
  211. case CCX(F, I): {
  212. double n; /* Always convert via double. */
  213. conv_F_I:
  214. /* First convert source to double. */
  215. /* The conversion must exactly match the semantics of JIT-compiled code! */
  216. if (ssize < 4 || (ssize == 4 && !(sinfo & CTF_UNSIGNED))) {
  217. int32_t i;
  218. if (ssize == 4) {
  219. i = *(int32_t *)sp;
  220. } else if (!(sinfo & CTF_UNSIGNED)) {
  221. if (ssize == 2) i = *(int16_t *)sp;
  222. else i = *(int8_t *)sp;
  223. } else {
  224. if (ssize == 2) i = *(uint16_t *)sp;
  225. else i = *(uint8_t *)sp;
  226. }
  227. n = (double)i;
  228. } else if (ssize == 4) {
  229. n = (double)*(uint32_t *)sp;
  230. } else if (ssize == 8) {
  231. if (!(sinfo & CTF_UNSIGNED)) n = (double)*(int64_t *)sp;
  232. else n = (double)*(uint64_t *)sp;
  233. } else {
  234. goto err_conv; /* NYI: conversion from >64 bit integers. */
  235. }
  236. /* Convert double to destination. */
  237. if (dsize == sizeof(double)) *(double *)dp = n;
  238. else if (dsize == sizeof(float)) *(float *)dp = (float)n;
  239. else goto err_conv; /* NYI: long double. */
  240. break;
  241. }
  242. case CCX(F, F): {
  243. double n; /* Always convert via double. */
  244. conv_F_F:
  245. if (ssize == dsize) goto copyval;
  246. /* Convert source to double. */
  247. if (ssize == sizeof(double)) n = *(double *)sp;
  248. else if (ssize == sizeof(float)) n = (double)*(float *)sp;
  249. else goto err_conv; /* NYI: long double. */
  250. /* Convert double to destination. */
  251. if (dsize == sizeof(double)) *(double *)dp = n;
  252. else if (dsize == sizeof(float)) *(float *)dp = (float)n;
  253. else goto err_conv; /* NYI: long double. */
  254. break;
  255. }
  256. case CCX(F, C):
  257. s = ctype_child(cts, s);
  258. sinfo = s->info;
  259. ssize = s->size;
  260. goto conv_F_F; /* Ignore im, and convert from re. */
  261. /* Destination is a complex number. */
  262. case CCX(C, I):
  263. d = ctype_child(cts, d);
  264. dinfo = d->info;
  265. dsize = d->size;
  266. memset(dp + dsize, 0, dsize); /* Clear im. */
  267. goto conv_F_I; /* Convert to re. */
  268. case CCX(C, F):
  269. d = ctype_child(cts, d);
  270. dinfo = d->info;
  271. dsize = d->size;
  272. memset(dp + dsize, 0, dsize); /* Clear im. */
  273. goto conv_F_F; /* Convert to re. */
  274. case CCX(C, C):
  275. if (dsize != ssize) { /* Different types: convert re/im separately. */
  276. CType *dc = ctype_child(cts, d);
  277. CType *sc = ctype_child(cts, s);
  278. lj_cconv_ct_ct(cts, dc, sc, dp, sp, flags);
  279. lj_cconv_ct_ct(cts, dc, sc, dp + dc->size, sp + sc->size, flags);
  280. return;
  281. }
  282. goto copyval; /* Otherwise this is easy. */
  283. /* Destination is a vector. */
  284. case CCX(V, I):
  285. case CCX(V, F):
  286. case CCX(V, C): {
  287. CType *dc = ctype_child(cts, d);
  288. CTSize esize;
  289. /* First convert the scalar to the first element. */
  290. lj_cconv_ct_ct(cts, dc, s, dp, sp, flags);
  291. /* Then replicate it to the other elements (splat). */
  292. for (sp = dp, esize = dc->size; dsize > esize; dsize -= esize) {
  293. dp += esize;
  294. memcpy(dp, sp, esize);
  295. }
  296. break;
  297. }
  298. case CCX(V, V):
  299. /* Copy same-sized vectors, even for different lengths/element-types. */
  300. if (dsize != ssize) goto err_conv;
  301. goto copyval;
  302. /* Destination is a pointer. */
  303. case CCX(P, I):
  304. if (!(flags & CCF_CAST)) goto err_conv;
  305. dinfo = CTINFO(CT_NUM, CTF_UNSIGNED);
  306. goto conv_I_I;
  307. case CCX(P, F):
  308. if (!(flags & CCF_CAST) || !(flags & CCF_FROMTV)) goto err_conv;
  309. /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
  310. dinfo = CTINFO(CT_NUM, (LJ_64 && dsize == 8) ? 0 : CTF_UNSIGNED);
  311. goto conv_I_F;
  312. case CCX(P, P):
  313. if (!lj_cconv_compatptr(cts, d, s, flags)) goto err_conv;
  314. cdata_setptr(dp, dsize, cdata_getptr(sp, ssize));
  315. break;
  316. case CCX(P, A):
  317. case CCX(P, S):
  318. if (!lj_cconv_compatptr(cts, d, s, flags)) goto err_conv;
  319. cdata_setptr(dp, dsize, sp);
  320. break;
  321. /* Destination is an array. */
  322. case CCX(A, A):
  323. if ((flags & CCF_CAST) || (d->info & CTF_VLA) || dsize != ssize ||
  324. d->size == CTSIZE_INVALID || !lj_cconv_compatptr(cts, d, s, flags))
  325. goto err_conv;
  326. goto copyval;
  327. /* Destination is a struct/union. */
  328. case CCX(S, S):
  329. if ((flags & CCF_CAST) || (d->info & CTF_VLA) || d != s)
  330. goto err_conv; /* Must be exact same type. */
  331. copyval: /* Copy value. */
  332. lua_assert(dsize == ssize);
  333. memcpy(dp, sp, dsize);
  334. break;
  335. default:
  336. err_conv:
  337. cconv_err_conv(cts, d, s, flags);
  338. }
  339. }
  340. /* -- C type to TValue conversion ----------------------------------------- */
  341. /* Convert C type to TValue. Caveat: expects to get the raw CType! */
  342. int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
  343. TValue *o, uint8_t *sp)
  344. {
  345. CTInfo sinfo = s->info;
  346. if (ctype_isnum(sinfo)) {
  347. if (!ctype_isbool(sinfo)) {
  348. if (ctype_isinteger(sinfo) && s->size > 4) goto copyval;
  349. if (LJ_DUALNUM && ctype_isinteger(sinfo)) {
  350. int32_t i;
  351. lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT32), s,
  352. (uint8_t *)&i, sp, 0);
  353. if ((sinfo & CTF_UNSIGNED) && i < 0)
  354. setnumV(o, (lua_Number)(uint32_t)i);
  355. else
  356. setintV(o, i);
  357. } else {
  358. lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s,
  359. (uint8_t *)&o->n, sp, 0);
  360. /* Numbers are NOT canonicalized here! Beware of uninitialized data. */
  361. lua_assert(tvisnum(o));
  362. }
  363. } else {
  364. uint32_t b = s->size == 1 ? (*sp != 0) : (*(int *)sp != 0);
  365. setboolV(o, b);
  366. setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */
  367. }
  368. return 0;
  369. } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) {
  370. /* Create reference. */
  371. setcdataV(cts->L, o, lj_cdata_newref(cts, sp, sid));
  372. return 1; /* Need GC step. */
  373. } else {
  374. GCcdata *cd;
  375. CTSize sz;
  376. copyval: /* Copy value. */
  377. sz = s->size;
  378. lua_assert(sz != CTSIZE_INVALID);
  379. /* Attributes are stripped, qualifiers are kept (but mostly ignored). */
  380. cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz);
  381. setcdataV(cts->L, o, cd);
  382. memcpy(cdataptr(cd), sp, sz);
  383. return 1; /* Need GC step. */
  384. }
  385. }
  386. /* Convert bitfield to TValue. */
  387. int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp)
  388. {
  389. CTInfo info = s->info;
  390. CTSize pos, bsz;
  391. uint32_t val;
  392. lua_assert(ctype_isbitfield(info));
  393. /* NYI: packed bitfields may cause misaligned reads. */
  394. switch (ctype_bitcsz(info)) {
  395. case 4: val = *(uint32_t *)sp; break;
  396. case 2: val = *(uint16_t *)sp; break;
  397. case 1: val = *(uint8_t *)sp; break;
  398. default: lua_assert(0); val = 0; break;
  399. }
  400. /* Check if a packed bitfield crosses a container boundary. */
  401. pos = ctype_bitpos(info);
  402. bsz = ctype_bitbsz(info);
  403. lua_assert(pos < 8*ctype_bitcsz(info));
  404. lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info));
  405. if (pos + bsz > 8*ctype_bitcsz(info))
  406. lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
  407. if (!(info & CTF_BOOL)) {
  408. CTSize shift = 32 - bsz;
  409. if (!(info & CTF_UNSIGNED)) {
  410. setintV(o, (int32_t)(val << (shift-pos)) >> shift);
  411. } else {
  412. val = (val << (shift-pos)) >> shift;
  413. if (!LJ_DUALNUM || (int32_t)val < 0)
  414. setnumV(o, (lua_Number)(uint32_t)val);
  415. else
  416. setintV(o, (int32_t)val);
  417. }
  418. } else {
  419. lua_assert(bsz == 1);
  420. setboolV(o, (val >> pos) & 1);
  421. }
  422. return 0; /* No GC step needed. */
  423. }
  424. /* -- TValue to C type conversion ----------------------------------------- */
  425. /* Convert table to array. */
  426. static void cconv_array_tab(CTState *cts, CType *d,
  427. uint8_t *dp, GCtab *t, CTInfo flags)
  428. {
  429. int32_t i;
  430. CType *dc = ctype_rawchild(cts, d); /* Array element type. */
  431. CTSize size = d->size, esize = dc->size, ofs = 0;
  432. for (i = 0; ; i++) {
  433. TValue *tv = (TValue *)lj_tab_getint(t, i);
  434. if (!tv || tvisnil(tv)) {
  435. if (i == 0) continue; /* Try again for 1-based tables. */
  436. break; /* Stop at first nil. */
  437. }
  438. if (ofs >= size)
  439. cconv_err_initov(cts, d);
  440. lj_cconv_ct_tv(cts, dc, dp + ofs, tv, flags);
  441. ofs += esize;
  442. }
  443. if (size != CTSIZE_INVALID) { /* Only fill up arrays with known size. */
  444. if (ofs == esize) { /* Replicate a single element. */
  445. for (; ofs < size; ofs += esize) memcpy(dp + ofs, dp, esize);
  446. } else { /* Otherwise fill the remainder with zero. */
  447. memset(dp + ofs, 0, size - ofs);
  448. }
  449. }
  450. }
  451. /* Convert table to sub-struct/union. */
  452. static void cconv_substruct_tab(CTState *cts, CType *d, uint8_t *dp,
  453. GCtab *t, int32_t *ip, CTInfo flags)
  454. {
  455. CTypeID id = d->sib;
  456. while (id) {
  457. CType *df = ctype_get(cts, id);
  458. id = df->sib;
  459. if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
  460. TValue *tv;
  461. int32_t i = *ip, iz = i;
  462. if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
  463. if (i >= 0) {
  464. retry:
  465. tv = (TValue *)lj_tab_getint(t, i);
  466. if (!tv || tvisnil(tv)) {
  467. if (i == 0) { i = 1; goto retry; } /* 1-based tables. */
  468. if (iz == 0) { *ip = i = -1; goto tryname; } /* Init named fields. */
  469. break; /* Stop at first nil. */
  470. }
  471. *ip = i + 1;
  472. } else {
  473. tryname:
  474. tv = (TValue *)lj_tab_getstr(t, gco2str(gcref(df->name)));
  475. if (!tv || tvisnil(tv)) continue;
  476. }
  477. if (ctype_isfield(df->info))
  478. lj_cconv_ct_tv(cts, ctype_rawchild(cts, df), dp+df->size, tv, flags);
  479. else
  480. lj_cconv_bf_tv(cts, df, dp+df->size, tv);
  481. if ((d->info & CTF_UNION)) break;
  482. } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
  483. cconv_substruct_tab(cts, ctype_rawchild(cts, df),
  484. dp+df->size, t, ip, flags);
  485. } /* Ignore all other entries in the chain. */
  486. }
  487. }
  488. /* Convert table to struct/union. */
  489. static void cconv_struct_tab(CTState *cts, CType *d,
  490. uint8_t *dp, GCtab *t, CTInfo flags)
  491. {
  492. int32_t i = 0;
  493. memset(dp, 0, d->size); /* Much simpler to clear the struct first. */
  494. cconv_substruct_tab(cts, d, dp, t, &i, flags);
  495. }
  496. /* Convert TValue to C type. Caveat: expects to get the raw CType! */
  497. void lj_cconv_ct_tv(CTState *cts, CType *d,
  498. uint8_t *dp, TValue *o, CTInfo flags)
  499. {
  500. CTypeID sid = CTID_P_VOID;
  501. CType *s;
  502. void *tmpptr;
  503. uint8_t tmpbool, *sp = (uint8_t *)&tmpptr;
  504. if (LJ_LIKELY(tvisint(o))) {
  505. sp = (uint8_t *)&o->i;
  506. sid = CTID_INT32;
  507. flags |= CCF_FROMTV;
  508. } else if (LJ_LIKELY(tvisnum(o))) {
  509. sp = (uint8_t *)&o->n;
  510. sid = CTID_DOUBLE;
  511. flags |= CCF_FROMTV;
  512. } else if (tviscdata(o)) {
  513. sp = cdataptr(cdataV(o));
  514. sid = cdataV(o)->ctypeid;
  515. s = ctype_get(cts, sid);
  516. if (ctype_isref(s->info)) { /* Resolve reference for value. */
  517. lua_assert(s->size == CTSIZE_PTR);
  518. sp = *(void **)sp;
  519. sid = ctype_cid(s->info);
  520. }
  521. s = ctype_raw(cts, sid);
  522. if (ctype_isfunc(s->info)) {
  523. sid = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|sid), CTSIZE_PTR);
  524. } else {
  525. if (ctype_isenum(s->info)) s = ctype_child(cts, s);
  526. goto doconv;
  527. }
  528. } else if (tvisstr(o)) {
  529. GCstr *str = strV(o);
  530. if (ctype_isenum(d->info)) { /* Match string against enum constant. */
  531. CTSize ofs;
  532. CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
  533. if (!cct || !ctype_isconstval(cct->info))
  534. goto err_conv;
  535. lua_assert(d->size == 4);
  536. sp = (uint8_t *)&cct->size;
  537. sid = ctype_cid(cct->info);
  538. } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
  539. CType *dc = ctype_rawchild(cts, d);
  540. CTSize sz = str->len+1;
  541. if (!ctype_isinteger(dc->info) || dc->size != 1)
  542. goto err_conv;
  543. if (d->size != 0 && d->size < sz)
  544. sz = d->size;
  545. memcpy(dp, strdata(str), sz);
  546. return;
  547. } else { /* Otherwise pass it as a const char[]. */
  548. sp = (uint8_t *)strdata(str);
  549. sid = CTID_A_CCHAR;
  550. flags |= CCF_FROMTV;
  551. }
  552. } else if (tvistab(o)) {
  553. if (ctype_isarray(d->info)) {
  554. cconv_array_tab(cts, d, dp, tabV(o), flags);
  555. return;
  556. } else if (ctype_isstruct(d->info)) {
  557. cconv_struct_tab(cts, d, dp, tabV(o), flags);
  558. return;
  559. } else {
  560. goto err_conv;
  561. }
  562. } else if (tvisbool(o)) {
  563. tmpbool = boolV(o);
  564. sp = &tmpbool;
  565. sid = CTID_BOOL;
  566. } else if (tvisnil(o)) {
  567. tmpptr = (void *)0;
  568. flags |= CCF_FROMTV;
  569. } else if (tvisudata(o)) {
  570. GCudata *ud = udataV(o);
  571. tmpptr = uddata(ud);
  572. if (ud->udtype == UDTYPE_IO_FILE)
  573. tmpptr = *(void **)tmpptr;
  574. } else if (tvislightud(o)) {
  575. tmpptr = lightudV(o);
  576. } else if (tvisfunc(o)) {
  577. void *p = lj_ccallback_new(cts, d, funcV(o));
  578. if (p) {
  579. *(void **)dp = p;
  580. return;
  581. }
  582. goto err_conv;
  583. } else {
  584. err_conv:
  585. cconv_err_convtv(cts, d, o, flags);
  586. }
  587. s = ctype_get(cts, sid);
  588. doconv:
  589. if (ctype_isenum(d->info)) d = ctype_child(cts, d);
  590. lj_cconv_ct_ct(cts, d, s, dp, sp, flags);
  591. }
  592. /* Convert TValue to bitfield. */
  593. void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o)
  594. {
  595. CTInfo info = d->info;
  596. CTSize pos, bsz;
  597. uint32_t val, mask;
  598. lua_assert(ctype_isbitfield(info));
  599. if ((info & CTF_BOOL)) {
  600. uint8_t tmpbool;
  601. lua_assert(ctype_bitbsz(info) == 1);
  602. lj_cconv_ct_tv(cts, ctype_get(cts, CTID_BOOL), &tmpbool, o, 0);
  603. val = tmpbool;
  604. } else {
  605. CTypeID did = (info & CTF_UNSIGNED) ? CTID_UINT32 : CTID_INT32;
  606. lj_cconv_ct_tv(cts, ctype_get(cts, did), (uint8_t *)&val, o, 0);
  607. }
  608. pos = ctype_bitpos(info);
  609. bsz = ctype_bitbsz(info);
  610. lua_assert(pos < 8*ctype_bitcsz(info));
  611. lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info));
  612. /* Check if a packed bitfield crosses a container boundary. */
  613. if (pos + bsz > 8*ctype_bitcsz(info))
  614. lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
  615. mask = ((1u << bsz) - 1u) << pos;
  616. val = (val << pos) & mask;
  617. /* NYI: packed bitfields may cause misaligned reads/writes. */
  618. switch (ctype_bitcsz(info)) {
  619. case 4: *(uint32_t *)dp = (*(uint32_t *)dp & ~mask) | (uint32_t)val; break;
  620. case 2: *(uint16_t *)dp = (*(uint16_t *)dp & ~mask) | (uint16_t)val; break;
  621. case 1: *(uint8_t *)dp = (*(uint8_t *)dp & ~mask) | (uint8_t)val; break;
  622. default: lua_assert(0); break;
  623. }
  624. }
  625. /* -- Initialize C type with TValues -------------------------------------- */
  626. /* Initialize an array with TValues. */
  627. static void cconv_array_init(CTState *cts, CType *d, CTSize sz, uint8_t *dp,
  628. TValue *o, MSize len)
  629. {
  630. CType *dc = ctype_rawchild(cts, d); /* Array element type. */
  631. CTSize ofs, esize = dc->size;
  632. MSize i;
  633. if (len*esize > sz)
  634. cconv_err_initov(cts, d);
  635. for (i = 0, ofs = 0; i < len; i++, ofs += esize)
  636. lj_cconv_ct_tv(cts, dc, dp + ofs, o + i, 0);
  637. if (ofs == esize) { /* Replicate a single element. */
  638. for (; ofs < sz; ofs += esize) memcpy(dp + ofs, dp, esize);
  639. } else { /* Otherwise fill the remainder with zero. */
  640. memset(dp + ofs, 0, sz - ofs);
  641. }
  642. }
  643. /* Initialize a sub-struct/union with TValues. */
  644. static void cconv_substruct_init(CTState *cts, CType *d, uint8_t *dp,
  645. TValue *o, MSize len, MSize *ip)
  646. {
  647. CTypeID id = d->sib;
  648. while (id) {
  649. CType *df = ctype_get(cts, id);
  650. id = df->sib;
  651. if (ctype_isfield(df->info) || ctype_isbitfield(df->info)) {
  652. MSize i = *ip;
  653. if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
  654. if (i >= len) break;
  655. *ip = i + 1;
  656. if (ctype_isfield(df->info))
  657. lj_cconv_ct_tv(cts, ctype_rawchild(cts, df), dp+df->size, o + i, 0);
  658. else
  659. lj_cconv_bf_tv(cts, df, dp+df->size, o + i);
  660. if ((d->info & CTF_UNION)) break;
  661. } else if (ctype_isxattrib(df->info, CTA_SUBTYPE)) {
  662. cconv_substruct_init(cts, ctype_rawchild(cts, df),
  663. dp+df->size, o, len, ip);
  664. } /* Ignore all other entries in the chain. */
  665. }
  666. }
  667. /* Initialize a struct/union with TValues. */
  668. static void cconv_struct_init(CTState *cts, CType *d, CTSize sz, uint8_t *dp,
  669. TValue *o, MSize len)
  670. {
  671. MSize i = 0;
  672. memset(dp, 0, sz); /* Much simpler to clear the struct first. */
  673. cconv_substruct_init(cts, d, dp, o, len, &i);
  674. if (i < len)
  675. cconv_err_initov(cts, d);
  676. }
  677. /* Check whether to use a multi-value initializer.
  678. ** This is true if an aggregate is to be initialized with a value.
  679. ** Valarrays are treated as values here so ct_tv handles (V|C, I|F).
  680. */
  681. int lj_cconv_multi_init(CTState *cts, CType *d, TValue *o)
  682. {
  683. if (!(ctype_isrefarray(d->info) || ctype_isstruct(d->info)))
  684. return 0; /* Destination is not an aggregate. */
  685. if (tvistab(o) || (tvisstr(o) && !ctype_isstruct(d->info)))
  686. return 0; /* Initializer is not a value. */
  687. if (tviscdata(o) && lj_ctype_rawref(cts, cdataV(o)->ctypeid) == d)
  688. return 0; /* Source and destination are identical aggregates. */
  689. return 1; /* Otherwise the initializer is a value. */
  690. }
  691. /* Initialize C type with TValues. Caveat: expects to get the raw CType! */
  692. void lj_cconv_ct_init(CTState *cts, CType *d, CTSize sz,
  693. uint8_t *dp, TValue *o, MSize len)
  694. {
  695. if (len == 0)
  696. memset(dp, 0, sz);
  697. else if (len == 1 && !lj_cconv_multi_init(cts, d, o))
  698. lj_cconv_ct_tv(cts, d, dp, o, 0);
  699. else if (ctype_isarray(d->info)) /* Also handles valarray init with len>1. */
  700. cconv_array_init(cts, d, sz, dp, o, len);
  701. else if (ctype_isstruct(d->info))
  702. cconv_struct_init(cts, d, sz, dp, o, len);
  703. else
  704. cconv_err_initov(cts, d);
  705. }
  706. #endif