]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
DUALNUM: Handle integer type in FFI.
authorMike Pall <mike>
Sun, 27 Feb 2011 00:31:22 +0000 (01:31 +0100)
committerMike Pall <mike>
Sun, 27 Feb 2011 00:31:22 +0000 (01:31 +0100)
src/lj_carith.c
src/lj_ccall.c
src/lj_cconv.c
src/lj_cdata.c
src/lj_clib.c

index f1435e1e3d4d70c1dcbfef779e05e638efe4406a..a59665d8f3e2b82c181800f46287d1d53e29c8a5 100644 (file)
@@ -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));
index 3f548c3088d9e97016888d6bd2f930113896b934..a3908e5037e0ac2a4e4532bdeace36dc03b7964d 100644 (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. */
 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;
index 94a9895ff0fd5ccae09ccedf50538dfab95a9ff0..884edef1a6429f2146d7892c2ca7d06f7c3dea04 100644 (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;
index af78d05e01a1fb1597e41f771973eeb31300a772..ae66b4b5771a18f1eeb45aa541457f8a2cbb2dfe 100644 (file)
@@ -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. */
index 98d74cded105c22e72fc9338a69218f3d8f784ad..d7721860c3ff4015ee73bd18788bda95f2a07cb4 100644 (file)
@@ -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);