}
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;
/* 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));
/* 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;
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);
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);
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;
}
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)) {
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. */
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);