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

@ -41,6 +41,9 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
} }
ca->ct[i] = ct; ca->ct[i] = ct;
ca->p[i] = p; ca->p[i] = p;
} else if (tvisint(o)) {
ca->ct[i] = ctype_get(cts, CTID_INT32);
ca->p[i] = (uint8_t *)&o->i;
} else if (tvisnum(o)) { } else if (tvisnum(o)) {
ca->ct[i] = ctype_get(cts, CTID_DOUBLE); ca->ct[i] = ctype_get(cts, CTID_DOUBLE);
ca->p[i] = (uint8_t *)&o->n; ca->p[i] = (uint8_t *)&o->n;
@ -84,7 +87,7 @@ static int carith_ptr(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
/* All valid pointer differences on x64 are in (-2^47, +2^47), /* All valid pointer differences on x64 are in (-2^47, +2^47),
** which fits into a double without loss of precision. ** which fits into a double without loss of precision.
*/ */
setnumV(L->top-1, (lua_Number)diff); setintptrV(L->top-1, (int32_t)diff);
return 1; return 1;
} else if (mm == MM_lt) { /* Pointer comparison (unsigned). */ } else if (mm == MM_lt) { /* Pointer comparison (unsigned). */
setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2)); setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2));

View File

@ -315,7 +315,7 @@ static void ccall_struct_ret(CCallState *cc, int *rcl, uint8_t *dp, CTSize sz)
/* Infer the destination CTypeID for a vararg argument. */ /* Infer the destination CTypeID for a vararg argument. */
static CTypeID ccall_ctid_vararg(CTState *cts, cTValue *o) static CTypeID ccall_ctid_vararg(CTState *cts, cTValue *o)
{ {
if (tvisnum(o)) { if (tvisnumber(o)) {
return CTID_DOUBLE; return CTID_DOUBLE;
} else if (tviscdata(o)) { } else if (tviscdata(o)) {
CTypeID id = cdataV(o)->typeid; CTypeID id = cdataV(o)->typeid;

View File

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

View File

@ -88,7 +88,10 @@ collect_attrib:
} }
lua_assert(!ctype_isref(ct->info)); /* Interning rejects refs to refs. */ lua_assert(!ctype_isref(ct->info)); /* Interning rejects refs to refs. */
if (tvisnum(key)) { /* Numeric key. */ if (tvisint(key)) {
idx = (ptrdiff_t)intV(key);
goto integer_key;
} else if (tvisnum(key)) { /* Numeric key. */
idx = LJ_64 ? (ptrdiff_t)numV(key) : (ptrdiff_t)lj_num2int(numV(key)); idx = LJ_64 ? (ptrdiff_t)numV(key) : (ptrdiff_t)lj_num2int(numV(key));
integer_key: integer_key:
if (ctype_ispointer(ct->info)) { if (ctype_ispointer(ct->info)) {
@ -171,10 +174,10 @@ static void cdata_getconst(CTState *cts, TValue *o, CType *ct)
CType *ctt = ctype_child(cts, ct); CType *ctt = ctype_child(cts, ct);
lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4); lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4);
/* Constants are already zero-extended/sign-extended to 32 bits. */ /* Constants are already zero-extended/sign-extended to 32 bits. */
if (!(ctt->info & CTF_UNSIGNED)) if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0)
setintV(o, (int32_t)ct->size);
else
setnumV(o, (lua_Number)(uint32_t)ct->size); setnumV(o, (lua_Number)(uint32_t)ct->size);
else
setintV(o, (int32_t)ct->size);
} }
/* Get C data value and convert to TValue. */ /* Get C data value and convert to TValue. */

View File

@ -266,10 +266,10 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
if (ctype_isconstval(ct->info)) { if (ctype_isconstval(ct->info)) {
CType *ctt = ctype_child(cts, ct); CType *ctt = ctype_child(cts, ct);
lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4); lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4);
if ((ctt->info & CTF_UNSIGNED) && ctt->size == 4) if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0)
setnumV(tv, (lua_Number)(uint32_t)ct->size); setnumV(tv, (lua_Number)(uint32_t)ct->size);
else else
setnumV(tv, (lua_Number)(int32_t)ct->size); setintV(tv, (int32_t)ct->size);
} else { } else {
const char *sym = clib_extsym(cts, ct, name); const char *sym = clib_extsym(cts, ct, name);
void *p = clib_getsym(cl, sym); void *p = clib_getsym(cl, sym);