aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/lvm.c b/lvm.c
index 2e84dc63..bdfef434 100644
--- a/lvm.c
+++ b/lvm.c
@@ -196,12 +196,15 @@ static int forlimit (lua_State *L, lua_Integer init, const TValue *lim,
196 196
197/* 197/*
198** Prepare a numerical for loop (opcode OP_FORPREP). 198** Prepare a numerical for loop (opcode OP_FORPREP).
199** Before execution, stack is as follows:
200** ra : initial value
201** ra + 1 : limit
202** ra + 2 : step
199** Return true to skip the loop. Otherwise, 203** Return true to skip the loop. Otherwise,
200** after preparation, stack will be as follows: 204** after preparation, stack will be as follows:
201** ra : internal index (safe copy of the control variable) 205** ra : loop counter (integer loops) or limit (float loops)
202** ra + 1 : loop counter (integer loops) or limit (float loops) 206** ra + 1 : step
203** ra + 2 : step 207** ra + 2 : control variable
204** ra + 3 : control variable
205*/ 208*/
206static int forprep (lua_State *L, StkId ra) { 209static int forprep (lua_State *L, StkId ra) {
207 TValue *pinit = s2v(ra); 210 TValue *pinit = s2v(ra);
@@ -213,7 +216,6 @@ static int forprep (lua_State *L, StkId ra) {
213 lua_Integer limit; 216 lua_Integer limit;
214 if (step == 0) 217 if (step == 0)
215 luaG_runerror(L, "'for' step is zero"); 218 luaG_runerror(L, "'for' step is zero");
216 setivalue(s2v(ra + 3), init); /* control variable */
217 if (forlimit(L, init, plimit, &limit, step)) 219 if (forlimit(L, init, plimit, &limit, step))
218 return 1; /* skip the loop */ 220 return 1; /* skip the loop */
219 else { /* prepare loop counter */ 221 else { /* prepare loop counter */
@@ -228,9 +230,10 @@ static int forprep (lua_State *L, StkId ra) {
228 /* 'step+1' avoids negating 'mininteger' */ 230 /* 'step+1' avoids negating 'mininteger' */
229 count /= l_castS2U(-(step + 1)) + 1u; 231 count /= l_castS2U(-(step + 1)) + 1u;
230 } 232 }
231 /* store the counter in place of the limit (which won't be 233 /* use 'chgivalue' for places that for sure had integers */
232 needed anymore) */ 234 chgivalue(s2v(ra), l_castU2S(count)); /* change init to count */
233 setivalue(plimit, l_castU2S(count)); 235 setivalue(s2v(ra + 1), step); /* change limit to step */
236 chgivalue(s2v(ra + 2), init); /* change step to init */
234 } 237 }
235 } 238 }
236 else { /* try making all values floats */ 239 else { /* try making all values floats */
@@ -247,11 +250,10 @@ static int forprep (lua_State *L, StkId ra) {
247 : luai_numlt(init, limit)) 250 : luai_numlt(init, limit))
248 return 1; /* skip the loop */ 251 return 1; /* skip the loop */
249 else { 252 else {
250 /* make sure internal values are all floats */ 253 /* make sure all values are floats */
251 setfltvalue(plimit, limit); 254 setfltvalue(s2v(ra), limit);
252 setfltvalue(pstep, step); 255 setfltvalue(s2v(ra + 1), step);
253 setfltvalue(s2v(ra), init); /* internal index */ 256 setfltvalue(s2v(ra + 2), init); /* control variable */
254 setfltvalue(s2v(ra + 3), init); /* control variable */
255 } 257 }
256 } 258 }
257 return 0; 259 return 0;
@@ -264,14 +266,13 @@ static int forprep (lua_State *L, StkId ra) {
264** written online with opcode OP_FORLOOP, for performance.) 266** written online with opcode OP_FORLOOP, for performance.)
265*/ 267*/
266static int floatforloop (StkId ra) { 268static int floatforloop (StkId ra) {
267 lua_Number step = fltvalue(s2v(ra + 2)); 269 lua_Number step = fltvalue(s2v(ra + 1));
268 lua_Number limit = fltvalue(s2v(ra + 1)); 270 lua_Number limit = fltvalue(s2v(ra));
269 lua_Number idx = fltvalue(s2v(ra)); /* internal index */ 271 lua_Number idx = fltvalue(s2v(ra + 2)); /* control variable */
270 idx = luai_numadd(L, idx, step); /* increment index */ 272 idx = luai_numadd(L, idx, step); /* increment index */
271 if (luai_numlt(0, step) ? luai_numle(idx, limit) 273 if (luai_numlt(0, step) ? luai_numle(idx, limit)
272 : luai_numle(limit, idx)) { 274 : luai_numle(limit, idx)) {
273 chgfltvalue(s2v(ra), idx); /* update internal index */ 275 chgfltvalue(s2v(ra + 2), idx); /* update control variable */
274 setfltvalue(s2v(ra + 3), idx); /* and control variable */
275 return 1; /* jump back */ 276 return 1; /* jump back */
276 } 277 }
277 else 278 else
@@ -1781,15 +1782,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1781 } 1782 }
1782 vmcase(OP_FORLOOP) { 1783 vmcase(OP_FORLOOP) {
1783 StkId ra = RA(i); 1784 StkId ra = RA(i);
1784 if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ 1785 if (ttisinteger(s2v(ra + 1))) { /* integer loop? */
1785 lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); 1786 lua_Unsigned count = l_castS2U(ivalue(s2v(ra)));
1786 if (count > 0) { /* still more iterations? */ 1787 if (count > 0) { /* still more iterations? */
1787 lua_Integer step = ivalue(s2v(ra + 2)); 1788 lua_Integer step = ivalue(s2v(ra + 1));
1788 lua_Integer idx = ivalue(s2v(ra)); /* internal index */ 1789 lua_Integer idx = ivalue(s2v(ra + 2)); /* control variable */
1789 chgivalue(s2v(ra + 1), count - 1); /* update counter */ 1790 chgivalue(s2v(ra), count - 1); /* update counter */
1790 idx = intop(+, idx, step); /* add step to index */ 1791 idx = intop(+, idx, step); /* add step to index */
1791 chgivalue(s2v(ra), idx); /* update internal index */ 1792 chgivalue(s2v(ra + 2), idx); /* update control variable */
1792 setivalue(s2v(ra + 3), idx); /* and control variable */
1793 pc -= GETARG_Bx(i); /* jump back */ 1793 pc -= GETARG_Bx(i); /* jump back */
1794 } 1794 }
1795 } 1795 }