diff options
| -rw-r--r-- | lcode.c | 4 | ||||
| -rw-r--r-- | ltable.c | 4 | ||||
| -rw-r--r-- | lvm.c | 25 | ||||
| -rw-r--r-- | lvm.h | 19 |
4 files changed, 30 insertions, 22 deletions
| @@ -653,7 +653,7 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) { | |||
| 653 | 653 | ||
| 654 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { | 654 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { |
| 655 | lua_Integer fi; | 655 | lua_Integer fi; |
| 656 | if (luaV_flttointeger(f, &fi, 0) && fitsBx(fi)) | 656 | if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) |
| 657 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); | 657 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); |
| 658 | else | 658 | else |
| 659 | luaK_codek(fs, reg, luaK_numberK(fs, f)); | 659 | luaK_codek(fs, reg, luaK_numberK(fs, f)); |
| @@ -1220,7 +1220,7 @@ static int isSCnumber (expdesc *e, int *pi, int *isfloat) { | |||
| 1220 | lua_Integer i; | 1220 | lua_Integer i; |
| 1221 | if (e->k == VKINT) | 1221 | if (e->k == VKINT) |
| 1222 | i = e->u.ival; | 1222 | i = e->u.ival; |
| 1223 | else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, 0)) | 1223 | else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq)) |
| 1224 | *isfloat = 1; | 1224 | *isfloat = 1; |
| 1225 | else | 1225 | else |
| 1226 | return 0; /* not a number */ | 1226 | return 0; /* not a number */ |
| @@ -626,7 +626,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 626 | else if (ttisfloat(key)) { | 626 | else if (ttisfloat(key)) { |
| 627 | lua_Number f = fltvalue(key); | 627 | lua_Number f = fltvalue(key); |
| 628 | lua_Integer k; | 628 | lua_Integer k; |
| 629 | if (luaV_flttointeger(f, &k, 0)) { /* does key fit in an integer? */ | 629 | if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */ |
| 630 | setivalue(&aux, k); | 630 | setivalue(&aux, k); |
| 631 | key = &aux; /* insert it as an integer */ | 631 | key = &aux; /* insert it as an integer */ |
| 632 | } | 632 | } |
| @@ -745,7 +745,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
| 745 | case LUA_TNIL: return &absentkey; | 745 | case LUA_TNIL: return &absentkey; |
| 746 | case LUA_TNUMFLT: { | 746 | case LUA_TNUMFLT: { |
| 747 | lua_Integer k; | 747 | lua_Integer k; |
| 748 | if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */ | 748 | if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ |
| 749 | return luaH_getint(t, k); /* use specialized version */ | 749 | return luaH_getint(t, k); /* use specialized version */ |
| 750 | /* else... */ | 750 | /* else... */ |
| 751 | } /* FALLTHROUGH */ | 751 | } /* FALLTHROUGH */ |
| @@ -116,16 +116,13 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | |||
| 116 | 116 | ||
| 117 | 117 | ||
| 118 | /* | 118 | /* |
| 119 | ** try to convert a float to an integer, rounding according to 'mode': | 119 | ** try to convert a float to an integer, rounding according to 'mode'. |
| 120 | ** mode == 0: accepts only integral values | ||
| 121 | ** mode == 1: takes the floor of the number | ||
| 122 | ** mode == 2: takes the ceil of the number | ||
| 123 | */ | 120 | */ |
| 124 | int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode) { | 121 | int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) { |
| 125 | lua_Number f = l_floor(n); | 122 | lua_Number f = l_floor(n); |
| 126 | if (n != f) { /* not an integral value? */ | 123 | if (n != f) { /* not an integral value? */ |
| 127 | if (mode == 0) return 0; /* fails if mode demands integral value */ | 124 | if (mode == F2Ieq) return 0; /* fails if mode demands integral value */ |
| 128 | else if (mode == 2) /* needs ceil? */ | 125 | else if (mode == F2Iceil) /* needs ceil? */ |
| 129 | f += 1; /* convert floor to ceil (remember: n != f) */ | 126 | f += 1; /* convert floor to ceil (remember: n != f) */ |
| 130 | } | 127 | } |
| 131 | return lua_numbertointeger(f, p); | 128 | return lua_numbertointeger(f, p); |
| @@ -137,7 +134,7 @@ int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode) { | |||
| 137 | ** without string coercion. | 134 | ** without string coercion. |
| 138 | ** ("Fast track" handled by macro 'tointegerns'.) | 135 | ** ("Fast track" handled by macro 'tointegerns'.) |
| 139 | */ | 136 | */ |
| 140 | int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode) { | 137 | int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) { |
| 141 | if (ttisfloat(obj)) | 138 | if (ttisfloat(obj)) |
| 142 | return luaV_flttointeger(fltvalue(obj), p, mode); | 139 | return luaV_flttointeger(fltvalue(obj), p, mode); |
| 143 | else if (ttisinteger(obj)) { | 140 | else if (ttisinteger(obj)) { |
| @@ -152,7 +149,7 @@ int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode) { | |||
| 152 | /* | 149 | /* |
| 153 | ** try to convert a value to an integer. | 150 | ** try to convert a value to an integer. |
| 154 | */ | 151 | */ |
| 155 | int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | 152 | int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) { |
| 156 | TValue v; | 153 | TValue v; |
| 157 | if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ | 154 | if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ |
| 158 | obj = &v; /* change it to point to its corresponding number */ | 155 | obj = &v; /* change it to point to its corresponding number */ |
| @@ -178,7 +175,7 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
| 178 | */ | 175 | */ |
| 179 | static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, | 176 | static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, |
| 180 | lua_Integer *p, lua_Integer step) { | 177 | lua_Integer *p, lua_Integer step) { |
| 181 | if (!luaV_tointeger(lim, p, (step < 0 ? 2 : 1))) { | 178 | if (!luaV_tointeger(lim, p, (step < 0 ? F2Iceil : F2Ifloor))) { |
| 182 | /* not coercible to in integer */ | 179 | /* not coercible to in integer */ |
| 183 | lua_Number flim; /* try to convert to float */ | 180 | lua_Number flim; /* try to convert to float */ |
| 184 | if (!tonumber(lim, &flim)) /* cannot convert to float? */ | 181 | if (!tonumber(lim, &flim)) /* cannot convert to float? */ |
| @@ -417,7 +414,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) { | |||
| 417 | return luai_numlt(cast_num(i), f); /* compare them as floats */ | 414 | return luai_numlt(cast_num(i), f); /* compare them as floats */ |
| 418 | else { /* i < f <=> i < ceil(f) */ | 415 | else { /* i < f <=> i < ceil(f) */ |
| 419 | lua_Integer fi; | 416 | lua_Integer fi; |
| 420 | if (luaV_flttointeger(f, &fi, 2)) /* fi = ceil(f) */ | 417 | if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ |
| 421 | return i < fi; /* compare them as integers */ | 418 | return i < fi; /* compare them as integers */ |
| 422 | else /* 'f' is either greater or less than all integers */ | 419 | else /* 'f' is either greater or less than all integers */ |
| 423 | return f > 0; /* greater? */ | 420 | return f > 0; /* greater? */ |
| @@ -434,7 +431,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) { | |||
| 434 | return luai_numle(cast_num(i), f); /* compare them as floats */ | 431 | return luai_numle(cast_num(i), f); /* compare them as floats */ |
| 435 | else { /* i <= f <=> i <= floor(f) */ | 432 | else { /* i <= f <=> i <= floor(f) */ |
| 436 | lua_Integer fi; | 433 | lua_Integer fi; |
| 437 | if (luaV_flttointeger(f, &fi, 1)) /* fi = floor(f) */ | 434 | if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ |
| 438 | return i <= fi; /* compare them as integers */ | 435 | return i <= fi; /* compare them as integers */ |
| 439 | else /* 'f' is either greater or less than all integers */ | 436 | else /* 'f' is either greater or less than all integers */ |
| 440 | return f > 0; /* greater? */ | 437 | return f > 0; /* greater? */ |
| @@ -451,7 +448,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) { | |||
| 451 | return luai_numlt(f, cast_num(i)); /* compare them as floats */ | 448 | return luai_numlt(f, cast_num(i)); /* compare them as floats */ |
| 452 | else { /* f < i <=> floor(f) < i */ | 449 | else { /* f < i <=> floor(f) < i */ |
| 453 | lua_Integer fi; | 450 | lua_Integer fi; |
| 454 | if (luaV_flttointeger(f, &fi, 1)) /* fi = floor(f) */ | 451 | if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ |
| 455 | return fi < i; /* compare them as integers */ | 452 | return fi < i; /* compare them as integers */ |
| 456 | else /* 'f' is either greater or less than all integers */ | 453 | else /* 'f' is either greater or less than all integers */ |
| 457 | return f < 0; /* less? */ | 454 | return f < 0; /* less? */ |
| @@ -468,7 +465,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) { | |||
| 468 | return luai_numle(f, cast_num(i)); /* compare them as floats */ | 465 | return luai_numle(f, cast_num(i)); /* compare them as floats */ |
| 469 | else { /* f <= i <=> ceil(f) <= i */ | 466 | else { /* f <= i <=> ceil(f) <= i */ |
| 470 | lua_Integer fi; | 467 | lua_Integer fi; |
| 471 | if (luaV_flttointeger(f, &fi, 2)) /* fi = ceil(f) */ | 468 | if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ |
| 472 | return fi <= i; /* compare them as integers */ | 469 | return fi <= i; /* compare them as integers */ |
| 473 | else /* 'f' is either greater or less than all integers */ | 470 | else /* 'f' is either greater or less than all integers */ |
| 474 | return f < 0; /* less? */ | 471 | return f < 0; /* less? */ |
| @@ -33,10 +33,20 @@ | |||
| 33 | ** integral values) | 33 | ** integral values) |
| 34 | */ | 34 | */ |
| 35 | #if !defined(LUA_FLOORN2I) | 35 | #if !defined(LUA_FLOORN2I) |
| 36 | #define LUA_FLOORN2I 0 | 36 | #define LUA_FLOORN2I F2Ieq |
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /* | ||
| 41 | ** Rounding modes for float->integer coercion | ||
| 42 | */ | ||
| 43 | typedef enum { | ||
| 44 | F2Ieq, /* no rounding; accepts only integral values */ | ||
| 45 | F2Ifloor, /* takes the floor of the number */ | ||
| 46 | F2Iceil, /* takes the ceil of the number */ | ||
| 47 | } F2Imod; | ||
| 48 | |||
| 49 | |||
| 40 | /* convert an object to a float (including string coercion) */ | 50 | /* convert an object to a float (including string coercion) */ |
| 41 | #define tonumber(o,n) \ | 51 | #define tonumber(o,n) \ |
| 42 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) | 52 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) |
| @@ -104,9 +114,10 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); | |||
| 104 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | 114 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); |
| 105 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | 115 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); |
| 106 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); | 116 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); |
| 107 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); | 117 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); |
| 108 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, int mode); | 118 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, |
| 109 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, int mode); | 119 | F2Imod mode); |
| 120 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); | ||
| 110 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, | 121 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, |
| 111 | StkId val, const TValue *slot); | 122 | StkId val, const TValue *slot); |
| 112 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 123 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, |
