Browse Source

DUALNUM: Handle integer type in FFI.

Mike Pall 14 years ago
parent
commit
c031d4b6a0
5 changed files with 42 additions and 17 deletions
  1. 4 1
      src/lj_carith.c
  2. 1 1
      src/lj_ccall.c
  3. 28 9
      src/lj_cconv.c
  4. 7 4
      src/lj_cdata.c
  5. 2 2
      src/lj_clib.c

+ 4 - 1
src/lj_carith.c

@@ -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));

+ 1 - 1
src/lj_ccall.c

@@ -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;

+ 28 - 9
src/lj_cconv.c

@@ -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,
-		     (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 {
     } 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))
-      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 {
   } 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;

+ 7 - 4
src/lj_cdata.c

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

+ 2 - 2
src/lj_clib.c

@@ -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);