示例#1
0
文件: ldump.c 项目: oss-forks/lua
static void DumpNumber(lua_Number x, DumpState* D)
{
 /*
   http://stackoverflow.com/questions/14954088/how-do-i-handle-byte-order-differences-when-reading-writing-floating-point-types/14955046#14955046

   10-byte little-endian serialized format for double:
   - normalized mantissa stored as 64-bit (8-byte) signed integer:
       negative range: (-2^53, -2^52]
       zero: 0
       positive range: [+2^52, +2^53)
   - 16-bit (2-byte) signed exponent:
       range: [-0x7FFE, +0x7FFE]

   Represented value = mantissa * 2^(exponent - 53)

   Special cases:
   - +infinity: mantissa = 0x7FFFFFFFFFFFFFFF, exp = 0x7FFF
   - -infinity: mantissa = 0x8000000000000000, exp = 0x7FFF
   - NaN:       mantissa = 0x0000000000000000, exp = 0x7FFF
   - +/-0:      only one zero supported
 */
 double y=(double)x,m;
 unsigned char z[8];
 long long im;
 int ie;
 if (luai_numisnan(NULL,x)) { DumpChar(0,D); /* NaN */ return; }
 else if (x == LUA_INFINITY) { DumpChar(1,D); /* +inf */ return; }
 else if (x == -LUA_INFINITY) { DumpChar(2,D); /* -inf */ return; }
 else if (x == 0) { DumpChar(3,D); /* 0 */ return; }
 /* Split double into normalized mantissa (range: (-1, -0.5], 0, [+0.5, +1)) and base-2 exponent */
 m = frexp(y, &ie); /* y = m * 2^ie exactly for FLT_RADIX=2, frexp() can't fail */
 /* Extract most significant 53 bits of mantissa as integer */
 m = ldexp(m, 53); /* can't overflow because DBL_MAX_10_EXP >= 37 equivalent to DBL_MAX_2_EXP >= 122 */
 im = (long long)trunc(m);    /* exact unless DBL_MANT_DIG > 53 */
 /* If the exponent is too small or too big, reduce the number to 0 or +/- infinity */
 if (ie>0x7FFE)
 {
   if (im<0) DumpChar(2,D); /* -inf */ else DumpChar(1,D); /* +inf */
   return;
 }
 else if (ie<-0x7FFE) { DumpChar(3,D); /* 0 */ return; }
 DumpChar(4,D); /* encoded */
 /* Store im as signed 64-bit little-endian integer */
 z[0]=(unsigned char)(im&0xFF);
 z[1]=(unsigned char)((im>>8)&0xFF);
 z[2]=(unsigned char)((im>>16)&0xFF);
 z[3]=(unsigned char)((im>>24)&0xFF);
 z[4]=(unsigned char)((im>>32)&0xFF);
 z[5]=(unsigned char)((im>>40)&0xFF);
 z[6]=(unsigned char)((im>>48)&0xFF);
 z[7]=(unsigned char)((im>>56)&0xFF);
 DumpMem(z,1,8,D);
 /* Store ie as signed 16-bit little-endian integer */
 z[0]=(unsigned char)(ie&0xFF);
 z[1]=(unsigned char)((ie>>8)&0xFF);
 DumpMem(z,1,2,D);
}
示例#2
0
文件: ltable.c 项目: luciouskami/YDWE
static int l_hashfloat (lua_Number n) {
  int i;
  lua_Integer ni;
  n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
  if (!lua_numbertointeger(n, &ni)) {  /* is 'n' inf/-inf/NaN? */
    lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL));
    return 0;
  }
  else {  /* normal case */
    unsigned int u = cast_uint(i) + cast_uint(ni);
    return cast_int(u <= cast_uint(INT_MAX) ? u : ~u);
  }
}
示例#3
0
int luaK_numberK (FuncState *fs, lua_Number r) {
  int n;
  lua_State *L = fs->ls->L;
  TValue o;
  setnvalue(&o, r);
  if (r == 0 || luai_numisnan(NULL, r)) {  /* handle -0 and NaN */
    /* use raw representation as key to avoid numeric problems */
    setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
    n = addk(fs, L->top - 1, &o);
    L->top--;
  }
  else
    n = addk(fs, &o, &o);  /* regular case */
  return n;
}
示例#4
0
/*
** Return 'l <= r', for numbers.
*/
static int LEnum (const TValue *l, const TValue *r) {
  if (ttisinteger(l)) {
    lua_Integer li = ivalue(l);
    if (ttisinteger(r))
      return li <= ivalue(r);  /* both are integers */
    else  /* 'l' is int and 'r' is float */
      return LEintfloat(li, fltvalue(r));  /* l <= r ? */
  }
  else {
    lua_Number lf = fltvalue(l);  /* 'l' must be float */
    if (ttisfloat(r))
      return luai_numle(lf, fltvalue(r));  /* both are float */
    else if (luai_numisnan(lf))  /* 'r' is int and 'l' is float */
      return 0;  /*  NaN <= i is always false */
    else  /* without NaN, (l <= r)  <-->  not(r < l) */
      return !LTintfloat(ivalue(r), lf);  /* not (r < l) ? */
  }
}
示例#5
0
/*
** Try to "constant-fold" an operation; return 1 iff successful
*/
static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
  TValue v1, v2, res;
  if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
    return 0;  /* non-numeric operands or not safe to fold */
  luaO_arith(fs->ls->L, op, &v1, &v2, &res);
  if (ttisinteger(&res)) {
    e1->k = VKINT;
    e1->u.ival = ivalue(&res);
  }
  else {
    lua_Number n = fltvalue(&res);
    if (luai_numisnan(n) || isminuszero(n))
      return 0;  /* folds neither NaN nor -0 */
    e1->k = VKFLT;
    e1->u.nval = n;
  }
  return 1;
}
示例#6
0
文件: load.c 项目: Aegisub/Aegisub
static int load_table(lua_State * L, lbs_LoadState * ls)
{
  int array_size = 0;
  int hash_size = 0;
  unsigned int total_size = 0;

  int result = lbsLS_readbytes(ls, (unsigned char *)&array_size, LUABINS_LINT);
  if (result == LUABINS_ESUCCESS)
  {
    result = lbsLS_readbytes(ls, (unsigned char *)&hash_size, LUABINS_LINT);
  }

  if (result == LUABINS_ESUCCESS)
  {
    total_size = array_size + hash_size;
/*
    SPAM((
        "LT SIZE CHECK\n"
        "* array_size %d limit 0 .. %d\n"
        "* hash_size %d limit >0\n"
        "* hash_size bytes %d, limit %d\n"
        "* unread %u limit >min_size %u (total_size %u)\n",
        array_size, MAXASIZE,
        hash_size,
        ceillog2((unsigned int)hash_size), MAXBITS,
        (unsigned int)lbsLS_unread(ls),
        (unsigned int)luabins_min_table_data_size(total_size),
        (unsigned int)total_size
      ));
*/
    if (
        array_size < 0 || array_size > MAXASIZE ||
        hash_size < 0  ||
        (hash_size > 0 && ceillog2((unsigned int)hash_size) > MAXBITS) ||
        lbsLS_unread(ls) < luabins_min_table_data_size(total_size)
      )
    {
      result = LUABINS_EBADSIZE;
    }
  }

  if (result == LUABINS_ESUCCESS)
  {
    unsigned int i = 0;

    XSPAM((
        "* load: creating table a:%d + h:%d = %d\n",
        array_size, hash_size, total_size
      ));

    lua_createtable(L, array_size, hash_size);

    for (i = 0; i < total_size; ++i)
    {
      int key_type = LUA_TNONE;

      result = load_value(L, ls); /* Load key. */
      if (result != LUABINS_ESUCCESS)
      {
        break;
      }

      /* Table key can't be nil or NaN */
      key_type = lua_type(L, -1);
      if (key_type == LUA_TNIL)
      {
        /* Corrupt data? */
        SPAM(("load: nil as key detected\n"));
        result = LUABINS_EBADDATA;
        break;
      }

      if (key_type == LUA_TNUMBER)
      {
        lua_Number key = lua_tonumber(L, -1);
        if (luai_numisnan(key))
        {
          /* Corrupt data? */
          SPAM(("load: NaN as key detected\n"));
          result = LUABINS_EBADDATA;
          break;
        }
      }

      result = load_value(L, ls); /* Load value. */
      if (result != LUABINS_ESUCCESS)
      {
        break;
      }

      lua_rawset(L, -3);
    }
  }

  return result;
}
示例#7
0
/*
** Both NaN and -0.0 should not go to the constant table, as they have
** problems with the hashing. (NaN is not a valid key, -0.0 collides
** with +0.0.)
*/ 
static int luaK_numberK (FuncState *fs, lua_Number r) {
  TValue o;
  lua_assert(!luai_numisnan(r) && !isminuszero(r));
  setfltvalue(&o, r);
  return addk(fs, &o, &o);
}