mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
DUALNUM: Handle integer type in FFI.
This commit is contained in:
parent
d437086c5a
commit
c031d4b6a0
@ -41,6 +41,9 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
|
||||
}
|
||||
ca->ct[i] = ct;
|
||||
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)) {
|
||||
ca->ct[i] = ctype_get(cts, CTID_DOUBLE);
|
||||
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),
|
||||
** 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;
|
||||
} else if (mm == MM_lt) { /* Pointer comparison (unsigned). */
|
||||
setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2));
|
||||
|
@ -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. */
|
||||
static CTypeID ccall_ctid_vararg(CTState *cts, cTValue *o)
|
||||
{
|
||||
if (tvisnum(o)) {
|
||||
if (tvisnumber(o)) {
|
||||
return CTID_DOUBLE;
|
||||
} else if (tviscdata(o)) {
|
||||
CTypeID id = cdataV(o)->typeid;
|
||||
|
@ -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;
|
||||
|
@ -88,7 +88,10 @@ collect_attrib:
|
||||
}
|
||||
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));
|
||||
integer_key:
|
||||
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);
|
||||
lua_assert(ctype_isinteger(ctt->info) && ctt->size <= 4);
|
||||
/* Constants are already zero-extended/sign-extended to 32 bits. */
|
||||
if (!(ctt->info & CTF_UNSIGNED))
|
||||
setintV(o, (int32_t)ct->size);
|
||||
else
|
||||
if ((ctt->info & CTF_UNSIGNED) && (int32_t)ct->size < 0)
|
||||
setnumV(o, (lua_Number)(uint32_t)ct->size);
|
||||
else
|
||||
setintV(o, (int32_t)ct->size);
|
||||
}
|
||||
|
||||
/* Get C data value and convert to TValue. */
|
||||
|
@ -266,10 +266,10 @@ TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name)
|
||||
if (ctype_isconstval(ct->info)) {
|
||||
CType *ctt = ctype_child(cts, ct);
|
||||
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);
|
||||
else
|
||||
setnumV(tv, (lua_Number)(int32_t)ct->size);
|
||||
setintV(tv, (int32_t)ct->size);
|
||||
} else {
|
||||
const char *sym = clib_extsym(cts, ct, name);
|
||||
void *p = clib_getsym(cl, sym);
|
||||
|
Loading…
Reference in New Issue
Block a user