DUALNUM: Handle integer type in FFI.

This commit is contained in:
Mike Pall
2011-02-27 01:31:22 +01:00
parent d437086c5a
commit c031d4b6a0
5 changed files with 42 additions and 17 deletions

View File

@@ -375,10 +375,20 @@ int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid,
if (ctype_isnum(sinfo)) {
if (!ctype_isbool(sinfo)) {
if (ctype_isinteger(sinfo) && s->size > 4) goto copyval;
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s,
(uint8_t *)&o->n, sp, 0);
/* Numbers are NOT canonicalized here! Beware of uninitialized data. */
lua_assert(tvisnum(o));
if (LJ_DUALNUM && ctype_isinteger(sinfo)) {
int32_t i;
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT32), s,
(uint8_t *)&i, sp, 0);
if ((sinfo & CTF_UNSIGNED) && i < 0)
setnumV(o, (lua_Number)(uint32_t)i);
else
setintV(o, i);
} else {
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_DOUBLE), s,
(uint8_t *)&o->n, sp, 0);
/* Numbers are NOT canonicalized here! Beware of uninitialized data. */
lua_assert(tvisnum(o));
}
} else {
uint32_t b = ((*sp) & 1);
setboolV(o, b);
@@ -426,10 +436,15 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp)
lj_err_caller(cts->L, LJ_ERR_FFI_NYIPACKBIT);
if (!(info & CTF_BOOL)) {
CTSize shift = 32 - bsz;
if (!(info & CTF_UNSIGNED))
setnumV(o, (lua_Number)((int32_t)(val << (shift-pos)) >> shift));
else
setnumV(o, (lua_Number)((val << (shift-pos)) >> shift));
if (!(info & CTF_UNSIGNED)) {
setintV(o, (int32_t)(val << (shift-pos)) >> shift);
} else {
val = (val << (shift-pos)) >> shift;
if (!LJ_DUALNUM || (int32_t)val < 0)
setnumV(o, (lua_Number)(uint32_t)val);
else
setintV(o, (int32_t)val);
}
} else {
lua_assert(bsz == 1);
setboolV(o, (val >> pos) & 1);
@@ -519,7 +534,11 @@ void lj_cconv_ct_tv(CTState *cts, CType *d,
CType *s;
void *tmpptr;
uint8_t tmpbool, *sp = (uint8_t *)&tmpptr;
if (LJ_LIKELY(tvisnum(o))) {
if (LJ_LIKELY(tvisint(o))) {
sp = (uint8_t *)&o->i;
sid = CTID_INT32;
flags |= CCF_FROMTV;
} else if (LJ_LIKELY(tvisnum(o))) {
sp = (uint8_t *)&o->n;
sid = CTID_DOUBLE;
flags |= CCF_FROMTV;