diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-04-29 15:11:57 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-04-29 15:11:57 -0300 |
commit | 9c4398de8f334ffaeb805450f158f89db8fd53c0 (patch) | |
tree | 6f77bdb774cca74049fd67c219e12dcc601dcdb6 /lvm.c | |
parent | a0d4f0fc8aba2bb0a3ba6f49f2a0f1153e4435ba (diff) | |
download | lua-9c4398de8f334ffaeb805450f158f89db8fd53c0.tar.gz lua-9c4398de8f334ffaeb805450f158f89db8fd53c0.tar.bz2 lua-9c4398de8f334ffaeb805450f158f89db8fd53c0.zip |
'for' loop tries to convert limit to integer when initial value and
step are integers
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 25 |
1 files changed, 23 insertions, 2 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.198 2014/04/15 16:32:49 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.199 2014/04/27 14:41:11 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -110,6 +110,24 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) { | |||
110 | } | 110 | } |
111 | 111 | ||
112 | 112 | ||
113 | /* | ||
114 | ** Check whether the limit of a 'for' loop can be safely converted | ||
115 | ** to an integer (rounding down or up depending on the signal of 'step') | ||
116 | */ | ||
117 | static int limittointeger (const TValue *n, lua_Integer *p, lua_Integer step) { | ||
118 | if (ttisinteger(n)) { | ||
119 | *p = ivalue(n); | ||
120 | return 1; | ||
121 | } | ||
122 | else if (!ttisfloat(n)) return 0; | ||
123 | else { | ||
124 | lua_Number f = fltvalue(n); | ||
125 | f = (step >= 0) ? l_floor(f) : -l_floor(-f); | ||
126 | return luaV_numtointeger(f, p); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | |||
113 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | 131 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { |
114 | int loop; | 132 | int loop; |
115 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | 133 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
@@ -946,9 +964,12 @@ void luaV_execute (lua_State *L) { | |||
946 | TValue *init = ra; | 964 | TValue *init = ra; |
947 | TValue *plimit = ra + 1; | 965 | TValue *plimit = ra + 1; |
948 | TValue *pstep = ra + 2; | 966 | TValue *pstep = ra + 2; |
949 | if (ttisinteger(init) && ttisinteger(plimit) && ttisinteger(pstep)) { | 967 | lua_Integer ilimit; |
968 | if (ttisinteger(init) && ttisinteger(pstep) && | ||
969 | limittointeger(plimit, &ilimit, ivalue(pstep))) { | ||
950 | /* all values are integer */ | 970 | /* all values are integer */ |
951 | setivalue(init, ivalue(init) - ivalue(pstep)); | 971 | setivalue(init, ivalue(init) - ivalue(pstep)); |
972 | setivalue(plimit, ilimit); | ||
952 | } | 973 | } |
953 | else { /* try making all values floats */ | 974 | else { /* try making all values floats */ |
954 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | 975 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; |