Showing with 33 additions and 3 deletions.
  1. +7 −0 lcode.c
  2. +22 −3 lstrlib.c
  3. +4 −0 lvm.c
@@ -603,6 +603,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) {
TValue o;
lua_Integer ik;
setfltvalue(&o, r);
#ifndef LUA_AVOID_FLOAT
if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */
return addk(fs, &o, &o); /* use number itself as key */
else { /* must build an alternative key */
@@ -616,6 +617,12 @@ static int luaK_numberK (FuncState *fs, lua_Number r) {
l_mathop(fabs)(r) >= l_mathop(1e6));
return addk(fs, &kv, &o);
}
#else
/*
** When we're avoiding floats, allow any collision since floats are ints.
*/
return addk(fs, &o, &o); /* use number itself as key */
#endif
}


@@ -1142,6 +1142,7 @@ static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
}


#ifndef LUA_AVOID_FLOAT
/*
** Serialize a floating-point number in such a way that it can be
** scanned back by Lua. Use hexadecimal format for "common" numbers
@@ -1170,7 +1171,7 @@ static int quotefloat (lua_State *L, char *buff, lua_Number n) {
/* for the fixed representations */
return l_sprintf(buff, MAX_ITEM, "%s", s);
}

#endif

static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
switch (lua_type(L, arg)) {
@@ -1183,9 +1184,13 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
case LUA_TNUMBER: {
char *buff = luaL_prepbuffsize(b, MAX_ITEM);
int nb;
#ifndef LUA_AVOID_FLOAT
if (!lua_isinteger(L, arg)) /* float? */
nb = quotefloat(L, buff, lua_tonumber(L, arg));
else { /* integers */
#else
{
#endif
lua_Integer n = lua_tointeger(L, arg);
const char *format = (n == LUA_MININTEGER) /* corner case? */
? "0x%" LUA_INTEGER_FRMLEN "x" /* use hex */
@@ -1319,10 +1324,12 @@ static int str_format (lua_State *L) {
nb = lua_number2strx(L, buff, maxitem, form,
luaL_checknumber(L, arg));
break;
#ifndef LUA_AVOID_FLOAT
case 'f':
maxitem = MAX_ITEMF; /* extra space for '%f' */
buff = luaL_prepbuffsize(&b, maxitem);
/* FALLTHROUGH */
#endif
case 'e': case 'E': case 'g': case 'G': {
lua_Number n = luaL_checknumber(L, arg);
checkformat(L, form, L_FMTFLAGSF, 1);
@@ -1428,9 +1435,11 @@ typedef struct Header {
typedef enum KOption {
Kint, /* signed integers */
Kuint, /* unsigned integers */
#ifndef LUA_AVOID_FLOAT
Kfloat, /* single-precision floating-point numbers */
Knumber, /* Lua "native" floating-point numbers */
Kdouble, /* double-precision floating-point numbers */
#endif
Knumber, /* Lua "native" floating-point numbers */
Kchar, /* fixed-length strings */
Kstring, /* strings with prefixed length */
Kzstr, /* zero-terminated strings */
@@ -1500,9 +1509,11 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
case 'j': *size = sizeof(lua_Integer); return Kint;
case 'J': *size = sizeof(lua_Integer); return Kuint;
case 'T': *size = sizeof(size_t); return Kuint;
#ifndef LUA_AVOID_FLOAT
case 'f': *size = sizeof(float); return Kfloat;
case 'n': *size = sizeof(lua_Number); return Knumber;
case 'd': *size = sizeof(double); return Kdouble;
#endif
case 'n': *size = sizeof(lua_Number); return Knumber;
case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint;
case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
@@ -1632,6 +1643,7 @@ static int str_pack (lua_State *L) {
packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
break;
}
#ifndef LUA_AVOID_FLOAT
case Kfloat: { /* C float */
float f = (float)luaL_checknumber(L, arg); /* get argument */
char *buff = luaL_prepbuffsize(&b, sizeof(f));
@@ -1640,6 +1652,7 @@ static int str_pack (lua_State *L) {
luaL_addsize(&b, size);
break;
}
#endif
case Knumber: { /* Lua float */
lua_Number f = luaL_checknumber(L, arg); /* get argument */
char *buff = luaL_prepbuffsize(&b, sizeof(f));
@@ -1648,6 +1661,7 @@ static int str_pack (lua_State *L) {
luaL_addsize(&b, size);
break;
}
#ifndef LUA_AVOID_FLOAT
case Kdouble: { /* C double */
double f = (double)luaL_checknumber(L, arg); /* get argument */
char *buff = luaL_prepbuffsize(&b, sizeof(f));
@@ -1656,6 +1670,7 @@ static int str_pack (lua_State *L) {
luaL_addsize(&b, size);
break;
}
#endif
case Kchar: { /* fixed-size string */
size_t len;
const char *s = luaL_checklstring(L, arg, &len);
@@ -1777,24 +1792,28 @@ static int str_unpack (lua_State *L) {
lua_pushinteger(L, res);
break;
}
#ifndef LUA_AVOID_FLOAT
case Kfloat: {
float f;
copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
lua_pushnumber(L, (lua_Number)f);
break;
}
#endif
case Knumber: {
lua_Number f;
copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
lua_pushnumber(L, f);
break;
}
#ifndef LUA_AVOID_FLOAT
case Kdouble: {
double f;
copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
lua_pushnumber(L, (lua_Number)f);
break;
}
#endif
case Kchar: {
lua_pushlstring(L, data + pos, size);
break;
4 lvm.c
@@ -52,7 +52,10 @@
/*
** 'l_intfitsf' checks whether a given integer is in the range that
** can be converted to a float without rounding. Used in comparisons.
** May be defined in luaconf.h if this test is incorrect for custom
** LUA_FLOAT_TYPEs.
*/
#if !defined(l_intfitsf)

/* number of bits in the mantissa of a float */
#define NBM (l_floatatt(MANT_DIG))
@@ -79,6 +82,7 @@

#endif

#endif /* !defined(l_intfitsf) */

/*
** Try to convert a value from string to a number value.