** Prepare a numerical for loop (opcode OP_FORPREP). ** Return true to skip the loop. Otherwise, ** after preparation, stack will be as follows: ** ra : internal index (safe copy of the control variable) ** ra + 1 : loop counter (integer loops) or limit (float loops) ** ra + 2 : step ** ra + 3 : control variable */
| 204 | ** ra + 3 : control variable |
| 205 | */ |
| 206 | static int forprep (lua_State *L, StkId ra) { |
| 207 | TValue *pinit = s2v(ra); |
| 208 | TValue *plimit = s2v(ra + 1); |
| 209 | TValue *pstep = s2v(ra + 2); |
| 210 | if (ttisinteger(pinit) && ttisinteger(pstep)) { /* integer loop? */ |
| 211 | lua_Integer init = ivalue(pinit); |
| 212 | lua_Integer step = ivalue(pstep); |
| 213 | lua_Integer limit; |
| 214 | if (step == 0) |
| 215 | luaG_runerror(L, "'for' step is zero"); |
| 216 | setivalue(s2v(ra + 3), init); /* control variable */ |
| 217 | if (forlimit(L, init, plimit, &limit, step)) |
| 218 | return 1; /* skip the loop */ |
| 219 | else { /* prepare loop counter */ |
| 220 | lua_Unsigned count; |
| 221 | if (step > 0) { /* ascending loop? */ |
| 222 | count = l_castS2U(limit) - l_castS2U(init); |
| 223 | if (step != 1) /* avoid division in the too common case */ |
| 224 | count /= l_castS2U(step); |
| 225 | } |
| 226 | else { /* step < 0; descending loop */ |
| 227 | count = l_castS2U(init) - l_castS2U(limit); |
| 228 | /* 'step+1' avoids negating 'mininteger' */ |
| 229 | count /= l_castS2U(-(step + 1)) + 1u; |
| 230 | } |
| 231 | /* store the counter in place of the limit (which won't be |
| 232 | needed anymore */ |
| 233 | setivalue(plimit, l_castU2S(count)); |
| 234 | } |
| 235 | } |
| 236 | else { /* try making all values floats */ |
| 237 | lua_Number init; lua_Number limit; lua_Number step; |
| 238 | if (unlikely(!tonumber(plimit, &limit))) |
| 239 | luaG_forerror(L, plimit, "limit"); |
| 240 | if (unlikely(!tonumber(pstep, &step))) |
| 241 | luaG_forerror(L, pstep, "step"); |
| 242 | if (unlikely(!tonumber(pinit, &init))) |
| 243 | luaG_forerror(L, pinit, "initial value"); |
| 244 | if (step == 0) |
| 245 | luaG_runerror(L, "'for' step is zero"); |
| 246 | if (luai_numlt(0, step) ? luai_numlt(limit, init) |
| 247 | : luai_numlt(init, limit)) |
| 248 | return 1; /* skip the loop */ |
| 249 | else { |
| 250 | /* make sure internal values are all floats */ |
| 251 | setfltvalue(plimit, limit); |
| 252 | setfltvalue(pstep, step); |
| 253 | setfltvalue(s2v(ra), init); /* internal index */ |
| 254 | setfltvalue(s2v(ra + 3), init); /* control variable */ |
| 255 | } |
| 256 | } |
| 257 | return 0; |
| 258 | } |
| 259 | |
| 260 | |
| 261 | /* |
no test coverage detected