diff options
Diffstat (limited to 'src/lj_cconv.c')
-rw-r--r-- | src/lj_cconv.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/src/lj_cconv.c b/src/lj_cconv.c index 03ed0ce2..400c2ae6 100644 --- a/src/lj_cconv.c +++ b/src/lj_cconv.c | |||
@@ -122,19 +122,25 @@ void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, | |||
122 | CTInfo dinfo = d->info, sinfo = s->info; | 122 | CTInfo dinfo = d->info, sinfo = s->info; |
123 | void *tmpptr; | 123 | void *tmpptr; |
124 | 124 | ||
125 | lua_assert(!ctype_isenum(dinfo) && !ctype_isenum(sinfo)); | 125 | lj_assertCTS(!ctype_isenum(dinfo) && !ctype_isenum(sinfo), |
126 | lua_assert(!ctype_isattrib(dinfo) && !ctype_isattrib(sinfo)); | 126 | "unresolved enum"); |
127 | lj_assertCTS(!ctype_isattrib(dinfo) && !ctype_isattrib(sinfo), | ||
128 | "unstripped attribute"); | ||
127 | 129 | ||
128 | if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT) | 130 | if (ctype_type(dinfo) > CT_MAYCONVERT || ctype_type(sinfo) > CT_MAYCONVERT) |
129 | goto err_conv; | 131 | goto err_conv; |
130 | 132 | ||
131 | /* Some basic sanity checks. */ | 133 | /* Some basic sanity checks. */ |
132 | lua_assert(!ctype_isnum(dinfo) || dsize > 0); | 134 | lj_assertCTS(!ctype_isnum(dinfo) || dsize > 0, "bad size for number type"); |
133 | lua_assert(!ctype_isnum(sinfo) || ssize > 0); | 135 | lj_assertCTS(!ctype_isnum(sinfo) || ssize > 0, "bad size for number type"); |
134 | lua_assert(!ctype_isbool(dinfo) || dsize == 1 || dsize == 4); | 136 | lj_assertCTS(!ctype_isbool(dinfo) || dsize == 1 || dsize == 4, |
135 | lua_assert(!ctype_isbool(sinfo) || ssize == 1 || ssize == 4); | 137 | "bad size for bool type"); |
136 | lua_assert(!ctype_isinteger(dinfo) || (1u<<lj_fls(dsize)) == dsize); | 138 | lj_assertCTS(!ctype_isbool(sinfo) || ssize == 1 || ssize == 4, |
137 | lua_assert(!ctype_isinteger(sinfo) || (1u<<lj_fls(ssize)) == ssize); | 139 | "bad size for bool type"); |
140 | lj_assertCTS(!ctype_isinteger(dinfo) || (1u<<lj_fls(dsize)) == dsize, | ||
141 | "bad size for integer type"); | ||
142 | lj_assertCTS(!ctype_isinteger(sinfo) || (1u<<lj_fls(ssize)) == ssize, | ||
143 | "bad size for integer type"); | ||
138 | 144 | ||
139 | switch (cconv_idx2(dinfo, sinfo)) { | 145 | switch (cconv_idx2(dinfo, sinfo)) { |
140 | /* Destination is a bool. */ | 146 | /* Destination is a bool. */ |
@@ -357,7 +363,7 @@ void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, | |||
357 | if ((flags & CCF_CAST) || (d->info & CTF_VLA) || d != s) | 363 | if ((flags & CCF_CAST) || (d->info & CTF_VLA) || d != s) |
358 | goto err_conv; /* Must be exact same type. */ | 364 | goto err_conv; /* Must be exact same type. */ |
359 | copyval: /* Copy value. */ | 365 | copyval: /* Copy value. */ |
360 | lua_assert(dsize == ssize); | 366 | lj_assertCTS(dsize == ssize, "value copy with different sizes"); |
361 | memcpy(dp, sp, dsize); | 367 | memcpy(dp, sp, dsize); |
362 | break; | 368 | break; |
363 | 369 | ||
@@ -389,7 +395,7 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | |||
389 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s, | 395 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s, |
390 | (uint8_t *)&o->n, sp, 0); | 396 | (uint8_t *)&o->n, sp, 0); |
391 | /* Numbers are NOT canonicalized here! Beware of uninitialized data. */ | 397 | /* Numbers are NOT canonicalized here! Beware of uninitialized data. */ |
392 | lua_assert(tvisnum(o)); | 398 | lj_assertCTS(tvisnum(o), "non-canonical NaN passed"); |
393 | } | 399 | } |
394 | } else { | 400 | } else { |
395 | uint32_t b = s->size == 1 ? (*sp != 0) : (*(int *)sp != 0); | 401 | uint32_t b = s->size == 1 ? (*sp != 0) : (*(int *)sp != 0); |
@@ -406,7 +412,7 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | |||
406 | CTSize sz; | 412 | CTSize sz; |
407 | copyval: /* Copy value. */ | 413 | copyval: /* Copy value. */ |
408 | sz = s->size; | 414 | sz = s->size; |
409 | lua_assert(sz != CTSIZE_INVALID); | 415 | lj_assertCTS(sz != CTSIZE_INVALID, "value copy with invalid size"); |
410 | /* Attributes are stripped, qualifiers are kept (but mostly ignored). */ | 416 | /* Attributes are stripped, qualifiers are kept (but mostly ignored). */ |
411 | cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz); | 417 | cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz); |
412 | setcdataV(cts->L, o, cd); | 418 | setcdataV(cts->L, o, cd); |
@@ -421,19 +427,22 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) | |||
421 | CTInfo info = s->info; | 427 | CTInfo info = s->info; |
422 | CTSize pos, bsz; | 428 | CTSize pos, bsz; |
423 | uint32_t val; | 429 | uint32_t val; |
424 | lua_assert(ctype_isbitfield(info)); | 430 | lj_assertCTS(ctype_isbitfield(info), "bitfield expected"); |
425 | /* NYI: packed bitfields may cause misaligned reads. */ | 431 | /* NYI: packed bitfields may cause misaligned reads. */ |
426 | switch (ctype_bitcsz(info)) { | 432 | switch (ctype_bitcsz(info)) { |
427 | case 4: val = *(uint32_t *)sp; break; | 433 | case 4: val = *(uint32_t *)sp; break; |
428 | case 2: val = *(uint16_t *)sp; break; | 434 | case 2: val = *(uint16_t *)sp; break; |
429 | case 1: val = *(uint8_t *)sp; break; | 435 | case 1: val = *(uint8_t *)sp; break; |
430 | default: lua_assert(0); val = 0; break; | 436 | default: |
437 | lj_assertCTS(0, "bad bitfield container size %d", ctype_bitcsz(info)); | ||
438 | val = 0; | ||
439 | break; | ||
431 | } | 440 | } |
432 | /* Check if a packed bitfield crosses a container boundary. */ | 441 | /* Check if a packed bitfield crosses a container boundary. */ |
433 | pos = ctype_bitpos(info); | 442 | pos = ctype_bitpos(info); |
434 | bsz = ctype_bitbsz(info); | 443 | bsz = ctype_bitbsz(info); |
435 | lua_assert(pos < 8*ctype_bitcsz(info)); | 444 | lj_assertCTS(pos < 8*ctype_bitcsz(info), "bad bitfield position"); |
436 | lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info)); | 445 | lj_assertCTS(bsz > 0 && bsz <= 8*ctype_bitcsz(info), "bad bitfield size"); |
437 | if (pos + bsz > 8*ctype_bitcsz(info)) | 446 | if (pos + bsz > 8*ctype_bitcsz(info)) |
438 | lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); | 447 | lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); |
439 | if (!(info & CTF_BOOL)) { | 448 | if (!(info & CTF_BOOL)) { |
@@ -449,7 +458,7 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) | |||
449 | } | 458 | } |
450 | } else { | 459 | } else { |
451 | uint32_t b = (val >> pos) & 1; | 460 | uint32_t b = (val >> pos) & 1; |
452 | lua_assert(bsz == 1); | 461 | lj_assertCTS(bsz == 1, "bad bool bitfield size"); |
453 | setboolV(o, b); | 462 | setboolV(o, b); |
454 | setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */ | 463 | setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */ |
455 | } | 464 | } |
@@ -553,7 +562,7 @@ void lj_cconv_ct_tv(CTState *cts, CType *d, | |||
553 | sid = cdataV(o)->ctypeid; | 562 | sid = cdataV(o)->ctypeid; |
554 | s = ctype_get(cts, sid); | 563 | s = ctype_get(cts, sid); |
555 | if (ctype_isref(s->info)) { /* Resolve reference for value. */ | 564 | if (ctype_isref(s->info)) { /* Resolve reference for value. */ |
556 | lua_assert(s->size == CTSIZE_PTR); | 565 | lj_assertCTS(s->size == CTSIZE_PTR, "ref is not pointer-sized"); |
557 | sp = *(void **)sp; | 566 | sp = *(void **)sp; |
558 | sid = ctype_cid(s->info); | 567 | sid = ctype_cid(s->info); |
559 | } | 568 | } |
@@ -571,7 +580,7 @@ void lj_cconv_ct_tv(CTState *cts, CType *d, | |||
571 | CType *cct = lj_ctype_getfield(cts, d, str, &ofs); | 580 | CType *cct = lj_ctype_getfield(cts, d, str, &ofs); |
572 | if (!cct || !ctype_isconstval(cct->info)) | 581 | if (!cct || !ctype_isconstval(cct->info)) |
573 | goto err_conv; | 582 | goto err_conv; |
574 | lua_assert(d->size == 4); | 583 | lj_assertCTS(d->size == 4, "only 32 bit enum supported"); /* NYI */ |
575 | sp = (uint8_t *)&cct->size; | 584 | sp = (uint8_t *)&cct->size; |
576 | sid = ctype_cid(cct->info); | 585 | sid = ctype_cid(cct->info); |
577 | } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */ | 586 | } else if (ctype_isrefarray(d->info)) { /* Copy string to array. */ |
@@ -635,10 +644,10 @@ void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o) | |||
635 | CTInfo info = d->info; | 644 | CTInfo info = d->info; |
636 | CTSize pos, bsz; | 645 | CTSize pos, bsz; |
637 | uint32_t val, mask; | 646 | uint32_t val, mask; |
638 | lua_assert(ctype_isbitfield(info)); | 647 | lj_assertCTS(ctype_isbitfield(info), "bitfield expected"); |
639 | if ((info & CTF_BOOL)) { | 648 | if ((info & CTF_BOOL)) { |
640 | uint8_t tmpbool; | 649 | uint8_t tmpbool; |
641 | lua_assert(ctype_bitbsz(info) == 1); | 650 | lj_assertCTS(ctype_bitbsz(info) == 1, "bad bool bitfield size"); |
642 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_BOOL), &tmpbool, o, 0); | 651 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_BOOL), &tmpbool, o, 0); |
643 | val = tmpbool; | 652 | val = tmpbool; |
644 | } else { | 653 | } else { |
@@ -647,8 +656,8 @@ void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o) | |||
647 | } | 656 | } |
648 | pos = ctype_bitpos(info); | 657 | pos = ctype_bitpos(info); |
649 | bsz = ctype_bitbsz(info); | 658 | bsz = ctype_bitbsz(info); |
650 | lua_assert(pos < 8*ctype_bitcsz(info)); | 659 | lj_assertCTS(pos < 8*ctype_bitcsz(info), "bad bitfield position"); |
651 | lua_assert(bsz > 0 && bsz <= 8*ctype_bitcsz(info)); | 660 | lj_assertCTS(bsz > 0 && bsz <= 8*ctype_bitcsz(info), "bad bitfield size"); |
652 | /* Check if a packed bitfield crosses a container boundary. */ | 661 | /* Check if a packed bitfield crosses a container boundary. */ |
653 | if (pos + bsz > 8*ctype_bitcsz(info)) | 662 | if (pos + bsz > 8*ctype_bitcsz(info)) |
654 | lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); | 663 | lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT); |
@@ -659,7 +668,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; | 668 | 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; | 669 | 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; | 670 | case 1: *(uint8_t *)dp = (*(uint8_t *)dp & ~mask) | (uint8_t)val; break; |
662 | default: lua_assert(0); break; | 671 | default: |
672 | lj_assertCTS(0, "bad bitfield container size %d", ctype_bitcsz(info)); | ||
673 | break; | ||
663 | } | 674 | } |
664 | } | 675 | } |
665 | 676 | ||