diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-21 15:35:40 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-21 15:35:40 -0300 |
| commit | 873588dc5f04bfc37006c3dc6ceb9a495ea503f2 (patch) | |
| tree | 3d47594a73706e49cce5e814982607607cde45d7 | |
| parent | b2f7b3b79f3117885b265575f6c5dbf934757797 (diff) | |
| download | lua-873588dc5f04bfc37006c3dc6ceb9a495ea503f2.tar.gz lua-873588dc5f04bfc37006c3dc6ceb9a495ea503f2.tar.bz2 lua-873588dc5f04bfc37006c3dc6ceb9a495ea503f2.zip | |
Simplification in opcodes for numerical 'for'
As the control variable is read only, the code doesn't need to keep
an internal copy of it.
| -rw-r--r-- | lparser.c | 4 | ||||
| -rw-r--r-- | lvm.c | 50 |
2 files changed, 27 insertions, 27 deletions
| @@ -1580,7 +1580,6 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
| 1580 | int base = fs->freereg; | 1580 | int base = fs->freereg; |
| 1581 | new_localvarliteral(ls, "(for state)"); | 1581 | new_localvarliteral(ls, "(for state)"); |
| 1582 | new_localvarliteral(ls, "(for state)"); | 1582 | new_localvarliteral(ls, "(for state)"); |
| 1583 | new_localvarliteral(ls, "(for state)"); | ||
| 1584 | new_localvarkind(ls, varname, RDKCONST); /* control variable */ | 1583 | new_localvarkind(ls, varname, RDKCONST); /* control variable */ |
| 1585 | checknext(ls, '='); | 1584 | checknext(ls, '='); |
| 1586 | exp1(ls); /* initial value */ | 1585 | exp1(ls); /* initial value */ |
| @@ -1592,7 +1591,8 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
| 1592 | luaK_int(fs, fs->freereg, 1); | 1591 | luaK_int(fs, fs->freereg, 1); |
| 1593 | luaK_reserveregs(fs, 1); | 1592 | luaK_reserveregs(fs, 1); |
| 1594 | } | 1593 | } |
| 1595 | adjustlocalvars(ls, 3); /* control variables */ | 1594 | adjustlocalvars(ls, 2); /* start scope for internal state variables */ |
| 1595 | fs->freereg--; /* OP_FORPREP removes one register from the stack */ | ||
| 1596 | forbody(ls, base, line, 1, 0); | 1596 | forbody(ls, base, line, 1, 0); |
| 1597 | } | 1597 | } |
| 1598 | 1598 | ||
| @@ -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 | */ |
| 206 | static int forprep (lua_State *L, StkId ra) { | 209 | static 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 | */ |
| 266 | static int floatforloop (StkId ra) { | 268 | static 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 | } |
