diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-25 13:55:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-25 13:55:29 -0300 |
commit | 9a37dc0ce64c51fd57f5e658a5af8f3671a26b0a (patch) | |
tree | 32d5d49d87ea9124c8209803d1ac78c94ec7a881 /lvm.c | |
parent | 0eb6aa4013051c8c0148c09d8c85ee7cbdc96f42 (diff) | |
download | lua-9a37dc0ce64c51fd57f5e658a5af8f3671a26b0a.tar.gz lua-9a37dc0ce64c51fd57f5e658a5af8f3671a26b0a.tar.bz2 lua-9a37dc0ce64c51fd57f5e658a5af8f3671a26b0a.zip |
Small corrections when setting 'L->top'
- OP_NEWTABLE can use 'ra + 1' to set top (instead of ci->top);
- OP_CLOSE doesn't need to set top ('Protect' already does that);
- OP_TFORCALL must use 'ProtectNT', to preserve the top already set.
(That was a small bug, because iterators could be called with
extra parameters besides the state and the control variable.)
- Comments and an extra test for the bug in previous item.
Diffstat (limited to '')
-rw-r--r-- | lvm.c | 7 |
1 files changed, 3 insertions, 4 deletions
@@ -1258,7 +1258,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1258 | if (TESTARG_k(i)) | 1258 | if (TESTARG_k(i)) |
1259 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); | 1259 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); |
1260 | pc++; /* skip extra argument */ | 1260 | pc++; /* skip extra argument */ |
1261 | L->top = ci->top; /* correct top in case of GC */ | 1261 | L->top = ra + 1; /* correct top in case of emergency GC */ |
1262 | t = luaH_new(L); /* memory allocation */ | 1262 | t = luaH_new(L); /* memory allocation */ |
1263 | sethvalue2s(L, ra, t); | 1263 | sethvalue2s(L, ra, t); |
1264 | if (b != 0 || c != 0) | 1264 | if (b != 0 || c != 0) |
@@ -1478,7 +1478,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1478 | vmbreak; | 1478 | vmbreak; |
1479 | } | 1479 | } |
1480 | vmcase(OP_CLOSE) { | 1480 | vmcase(OP_CLOSE) { |
1481 | L->top = ra + 1; /* everything is free after this slot */ | ||
1482 | Protect(luaF_close(L, ra, LUA_OK)); | 1481 | Protect(luaF_close(L, ra, LUA_OK)); |
1483 | vmbreak; | 1482 | vmbreak; |
1484 | } | 1483 | } |
@@ -1755,7 +1754,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1755 | /* push function, state, and control variable */ | 1754 | /* push function, state, and control variable */ |
1756 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); | 1755 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); |
1757 | L->top = ra + 4 + 3; | 1756 | L->top = ra + 4 + 3; |
1758 | Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ | 1757 | ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ |
1759 | updatestack(ci); /* stack may have changed */ | 1758 | updatestack(ci); /* stack may have changed */ |
1760 | i = *(pc++); /* go to next instruction */ | 1759 | i = *(pc++); /* go to next instruction */ |
1761 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); | 1760 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); |
@@ -1776,7 +1775,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1776 | if (n == 0) | 1775 | if (n == 0) |
1777 | n = cast_int(L->top - ra) - 1; /* get up to the top */ | 1776 | n = cast_int(L->top - ra) - 1; /* get up to the top */ |
1778 | else | 1777 | else |
1779 | L->top = ci->top; /* correct top in case of GC */ | 1778 | L->top = ci->top; /* correct top in case of emergency GC */ |
1780 | last += n; | 1779 | last += n; |
1781 | if (TESTARG_k(i)) { | 1780 | if (TESTARG_k(i)) { |
1782 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); | 1781 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); |