lj_cconv.c 25 KB

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