aboutsummaryrefslogtreecommitdiff
path: root/src/lj_cconv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_cconv.c')
-rw-r--r--src/lj_cconv.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/src/lj_cconv.c b/src/lj_cconv.c
index 8556952f..3bbfd3f1 100644
--- a/src/lj_cconv.c
+++ b/src/lj_cconv.c
@@ -8,6 +8,7 @@
8#if LJ_HASFFI 8#if LJ_HASFFI
9 9
10#include "lj_err.h" 10#include "lj_err.h"
11#include "lj_buf.h"
11#include "lj_tab.h" 12#include "lj_tab.h"
12#include "lj_ctype.h" 13#include "lj_ctype.h"
13#include "lj_cdata.h" 14#include "lj_cdata.h"
@@ -122,19 +123,25 @@ void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
122 CTInfo dinfo = d->info, sinfo = s->info; 123 CTInfo dinfo = d->info, sinfo = s->info;
123 void *tmpptr; 124 void *tmpptr;
124 125
125 lua_assert(!ctype_isenum(dinfo) && !ctype_isenum(sinfo)); 126 lj_assertCTS(!ctype_isenum(dinfo) && !ctype_isenum(sinfo),
126 lua_assert(!ctype_isattrib(dinfo) && !ctype_isattrib(sinfo)); 127 "unresolved enum");
128 lj_assertCTS(!ctype_isattrib(dinfo) && !ctype_isattrib(sinfo),
129 "unstripped attribute");
127 130
128 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT) 131 if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT)
129 goto err_conv; 132 goto err_conv;
130 133
131 /* Some basic sanity checks. */ 134 /* Some basic sanity checks. */
132 lua_assert(!ctype_isnum(dinfo) || dsize > 0); 135 lj_assertCTS(!ctype_isnum(dinfo) || dsize > 0, "bad size for number type");
133 lua_assert(!ctype_isnum(sinfo) || ssize > 0); 136 lj_assertCTS(!ctype_isnum(sinfo) || ssize > 0, "bad size for number type");
134 lua_assert(!ctype_isbool(dinfo) || dsize == 1 || dsize == 4); 137 lj_assertCTS(!ctype_isbool(dinfo) || dsize == 1 || dsize == 4,
135 lua_assert(!ctype_isbool(sinfo) || ssize == 1 || ssize == 4); 138 "bad size for bool type");
136 lua_assert(!ctype_isinteger(dinfo) || (1u<<lj_fls(dsize)) == dsize); 139 lj_assertCTS(!ctype_isbool(sinfo) || ssize == 1 || ssize == 4,
137 lua_assert(!ctype_isinteger(sinfo) || (1u<<lj_fls(ssize)) == ssize); 140 "bad size for bool type");
141 lj_assertCTS(!ctype_isinteger(dinfo) || (1u<<lj_fls(dsize)) == dsize,
142 "bad size for integer type");
143 lj_assertCTS(!ctype_isinteger(sinfo) || (1u<<lj_fls(ssize)) == ssize,
144 "bad size for integer type");
138 145
139 switch (cconv_idx2(dinfo, sinfo)) { 146 switch (cconv_idx2(dinfo, sinfo)) {
140 /* Destination is a bool. */ 147 /* Destination is a bool. */
@@ -357,7 +364,7 @@ void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s,
357 if ((flags & CCF_CAST) || (d->info & CTF_VLA) || d != s) 364 if ((flags & CCF_CAST) || (d->info & CTF_VLA) || d != s)
358 goto err_conv; /* Must be exact same type. */ 365 goto err_conv; /* Must be exact same type. */
359copyval: /* Copy value. */ 366copyval: /* Copy value. */
360 lua_assert(dsize == ssize); 367 lj_assertCTS(dsize == ssize, "value copy with different sizes");
361 memcpy(dp, sp, dsize); 368 memcpy(dp, sp, dsize);
362 break; 369 break;
363 370
@@ -389,7 +396,7 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
389 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s, 396 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s,
390 (uint8_t *)&o->n, sp, 0); 397 (uint8_t *)&o->n, sp, 0);
391 /* Numbers are NOT canonicalized here! Beware of uninitialized data. */ 398 /* Numbers are NOT canonicalized here! Beware of uninitialized data. */
392 lua_assert(tvisnum(o)); 399 lj_assertCTS(tvisnum(o), "non-canonical NaN passed");
393 } 400 }
394 } else { 401 } else {
395 uint32_t b = s->size == 1 ? (*sp != 0) : (*(int *)sp != 0); 402 uint32_t b = s->size == 1 ? (*sp != 0) : (*(int *)sp != 0);
@@ -406,7 +413,7 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
406 CTSize sz; 413 CTSize sz;
407 copyval: /* Copy value. */ 414 copyval: /* Copy value. */
408 sz = s->size; 415 sz = s->size;
409 lua_assert(sz != CTSIZE_INVALID); 416 lj_assertCTS(sz != CTSIZE_INVALID, "value copy with invalid size");
410 /* Attributes are stripped, qualifiers are kept (but mostly ignored). */ 417 /* Attributes are stripped, qualifiers are kept (but mostly ignored). */
411 cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz); 418 cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz);
412 setcdataV(cts->L, o, cd); 419 setcdataV(cts->L, o, cd);
@@ -421,19 +428,22 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp)
421 CTInfo info = s->info; 428 CTInfo info = s->info;
422 CTSize pos, bsz; 429 CTSize pos, bsz;
423 uint32_t val; 430 uint32_t val;
424 lua_assert(ctype_isbitfield(info)); 431 lj_assertCTS(ctype_isbitfield(info), "bitfield expected");
425 /* NYI: packed bitfields may cause misaligned reads. */ 432 /* NYI: packed bitfields may cause misaligned reads. */
426 switch (ctype_bitcsz(info)) { 433 switch (ctype_bitcsz(info)) {
427 case 4: val = *(uint32_t *)sp; break; 434 case 4: val = *(uint32_t *)sp; break;
428 case 2: val = *(uint16_t *)sp; break; 435 case 2: val = *(uint16_t *)sp; break;
429 case 1: val = *(uint8_t *)sp; break; 436 case 1: val = *(uint8_t *)sp; break;
430 default: lua_assert(0); val = 0; break; 437 default:
438 lj_assertCTS(0, "bad bitfield container size %d", ctype_bitcsz(info));
439 val = 0;
440 break;
431 } 441 }
432 /* Check if a packed bitfield crosses a container boundary. */ 442 /* Check if a packed bitfield crosses a container boundary. */
433 pos = ctype_bitpos(info); 443 pos = ctype_bitpos(info);
434 bsz = ctype_bitbsz(info); 444 bsz = ctype_bitbsz(info);
435 lua_assert(pos < 8*ctype_bitcsz(info)); 445 lj_assertCTS(pos < 8*ctype_bitcsz(info), "bad bitfield position");
436 lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info)); 446 lj_assertCTS(bsz > 0 && bsz <= 8*ctype_bitcsz(info), "bad bitfield size");
437 if (pos + bsz > 8*ctype_bitcsz(info)) 447 if (pos + bsz > 8*ctype_bitcsz(info))
438 lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); 448 lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
439 if (!(info & CTF_BOOL)) { 449 if (!(info & CTF_BOOL)) {
@@ -448,8 +458,10 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp)
448 setintV(o, (int32_t)val); 458 setintV(o, (int32_t)val);
449 } 459 }
450 } else { 460 } else {
451 lua_assert(bsz == 1); 461 uint32_t b = (val >> pos) & 1;
452 setboolV(o, (val >> pos) & 1); 462 lj_assertCTS(bsz == 1, "bad bool bitfield size");
463 setboolV(o, b);
464 setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */
453 } 465 }
454 return 0; /* No GC step needed. */ 466 return 0; /* No GC step needed. */
455} 467}
@@ -551,7 +563,7 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
551 sid = cdataV(o)->ctypeid; 563 sid = cdataV(o)->ctypeid;
552 s = ctype_get(cts, sid); 564 s = ctype_get(cts, sid);
553 if (ctype_isref(s->info)) { /* Resolve reference for value. */ 565 if (ctype_isref(s->info)) { /* Resolve reference for value. */
554 lua_assert(s->size == CTSIZE_PTR); 566 lj_assertCTS(s->size == CTSIZE_PTR, "ref is not pointer-sized");
555 sp = *(void **)sp; 567 sp = *(void **)sp;
556 sid = ctype_cid(s->info); 568 sid = ctype_cid(s->info);
557 } 569 }
@@ -571,7 +583,7 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
571 CType *cct = lj_ctype_getfield(cts, d, str, &ofs); 583 CType *cct = lj_ctype_getfield(cts, d, str, &ofs);
572 if (!cct || !ctype_isconstval(cct->info)) 584 if (!cct || !ctype_isconstval(cct->info))
573 goto err_conv; 585 goto err_conv;
574 lua_assert(d->size == 4); 586 lj_assertCTS(d->size == 4, "only 32 bit enum supported"); /* NYI */
575 sp = (uint8_t *)&cct->size; 587 sp = (uint8_t *)&cct->size;
576 sid = ctype_cid(cct->info); 588 sid = ctype_cid(cct->info);
577 } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */ 589 } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */
@@ -610,8 +622,10 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
610 tmpptr = uddata(ud); 622 tmpptr = uddata(ud);
611 if (ud->udtype == UDTYPE_IO_FILE) 623 if (ud->udtype == UDTYPE_IO_FILE)
612 tmpptr = *(void **)tmpptr; 624 tmpptr = *(void **)tmpptr;
625 else if (ud->udtype == UDTYPE_BUFFER)
626 tmpptr = ((SBufExt *)tmpptr)->r;
613 } else if (tvislightud(o)) { 627 } else if (tvislightud(o)) {
614 tmpptr = lightudV(o); 628 tmpptr = lightudV(cts->g, o);
615 } else if (tvisfunc(o)) { 629 } else if (tvisfunc(o)) {
616 void *p = lj_ccallback_new(cts, d, funcV(o)); 630 void *p = lj_ccallback_new(cts, d, funcV(o));
617 if (p) { 631 if (p) {
@@ -635,10 +649,10 @@ void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o)
635 CTInfo info = d->info; 649 CTInfo info = d->info;
636 CTSize pos, bsz; 650 CTSize pos, bsz;
637 uint32_t val, mask; 651 uint32_t val, mask;
638 lua_assert(ctype_isbitfield(info)); 652 lj_assertCTS(ctype_isbitfield(info), "bitfield expected");
639 if ((info & CTF_BOOL)) { 653 if ((info & CTF_BOOL)) {
640 uint8_t tmpbool; 654 uint8_t tmpbool;
641 lua_assert(ctype_bitbsz(info) == 1); 655 lj_assertCTS(ctype_bitbsz(info) == 1, "bad bool bitfield size");
642 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_BOOL), &tmpbool, o, 0); 656 lj_cconv_ct_tv(cts, ctype_get(cts, CTID_BOOL), &tmpbool, o, 0);
643 val = tmpbool; 657 val = tmpbool;
644 } else { 658 } else {
@@ -647,8 +661,8 @@ void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o)
647 } 661 }
648 pos = ctype_bitpos(info); 662 pos = ctype_bitpos(info);
649 bsz = ctype_bitbsz(info); 663 bsz = ctype_bitbsz(info);
650 lua_assert(pos < 8*ctype_bitcsz(info)); 664 lj_assertCTS(pos < 8*ctype_bitcsz(info), "bad bitfield position");
651 lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info)); 665 lj_assertCTS(bsz > 0 && bsz <= 8*ctype_bitcsz(info), "bad bitfield size");
652 /* Check if a packed bitfield crosses a container boundary. */ 666 /* Check if a packed bitfield crosses a container boundary. */
653 if (pos + bsz > 8*ctype_bitcsz(info)) 667 if (pos + bsz > 8*ctype_bitcsz(info))
654 lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); 668 lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
@@ -659,7 +673,9 @@ void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o)
659 case 4: *(uint32_t *)dp = (*(uint32_t *)dp & ~mask) | (uint32_t)val; break; 673 case 4: *(uint32_t *)dp = (*(uint32_t *)dp & ~mask) | (uint32_t)val; break;
660 case 2: *(uint16_t *)dp = (*(uint16_t *)dp & ~mask) | (uint16_t)val; break; 674 case 2: *(uint16_t *)dp = (*(uint16_t *)dp & ~mask) | (uint16_t)val; break;
661 case 1: *(uint8_t *)dp = (*(uint8_t *)dp & ~mask) | (uint8_t)val; break; 675 case 1: *(uint8_t *)dp = (*(uint8_t *)dp & ~mask) | (uint8_t)val; break;
662 default: lua_assert(0); break; 676 default:
677 lj_assertCTS(0, "bad bitfield container size %d", ctype_bitcsz(info));
678 break;
663 } 679 }
664} 680}
665 681