diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-24 11:59:15 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-24 11:59:15 -0200 |
commit | 7e63d3da0240325db4011f5d2f2e8abfb5d60288 (patch) | |
tree | f6f486aaa9c1279ccdc26a1cc8bc814e005a277b /lvm.c | |
parent | 84e32ad2ebd6bd160c1320456743a5b1d8f233e9 (diff) | |
download | lua-7e63d3da0240325db4011f5d2f2e8abfb5d60288.tar.gz lua-7e63d3da0240325db4011f5d2f2e8abfb5d60288.tar.bz2 lua-7e63d3da0240325db4011f5d2f2e8abfb5d60288.zip |
Some bugs with stack reallocation by 'luaF_close'
(Long time without testing with '-DHARDSTACKTESTS'...)
With the introduction of to-be-closed variables, calls to 'luaF_close'
can move the stack, but some call sites where keeping pointers to the
stack without correcting them.
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 21 |
1 files changed, 9 insertions, 12 deletions
@@ -946,6 +946,9 @@ void luaV_finishOp (lua_State *L) { | |||
946 | #define updatebase(ci) (base = ci->func + 1) | 946 | #define updatebase(ci) (base = ci->func + 1) |
947 | 947 | ||
948 | 948 | ||
949 | #define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } } | ||
950 | |||
951 | |||
949 | /* | 952 | /* |
950 | ** Execute a jump instruction. The 'updatetrap' allows signals to stop | 953 | ** Execute a jump instruction. The 'updatetrap' allows signals to stop |
951 | ** tight loops. (Without it, the local copy of 'trap' could never change.) | 954 | ** tight loops. (Without it, the local copy of 'trap' could never change.) |
@@ -1557,24 +1560,21 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1557 | L->top = ra + b; | 1560 | L->top = ra + b; |
1558 | else /* previous instruction set top */ | 1561 | else /* previous instruction set top */ |
1559 | b = cast_int(L->top - ra); | 1562 | b = cast_int(L->top - ra); |
1560 | savepc(ci); | ||
1561 | if (TESTARG_k(i)) { | 1563 | if (TESTARG_k(i)) { |
1562 | int nparams1 = GETARG_C(i); | 1564 | int nparams1 = GETARG_C(i); |
1563 | if (nparams1) /* vararg function? */ | 1565 | if (nparams1) /* vararg function? */ |
1564 | delta = ci->u.l.nextraargs + nparams1; | 1566 | delta = ci->u.l.nextraargs + nparams1; |
1565 | luaF_close(L, base, LUA_OK); /* close upvalues from current call */ | 1567 | /* close upvalues from current call */ |
1568 | ProtectNT(luaF_close(L, base, LUA_OK)); | ||
1569 | updatestack(ci); | ||
1566 | } | 1570 | } |
1567 | if (!ttisfunction(s2v(ra))) { /* not a function? */ | 1571 | if (!ttisfunction(s2v(ra))) { /* not a function? */ |
1568 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ | 1572 | luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ |
1569 | b++; /* there is now one extra argument */ | 1573 | b++; /* there is now one extra argument */ |
1570 | } | 1574 | } |
1571 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | 1575 | if (!ttisLclosure(s2v(ra))) { /* C function? */ |
1572 | luaD_call(L, ra, LUA_MULTRET); /* call it */ | 1576 | ProtectNT(luaD_call(L, ra, LUA_MULTRET)); /* call it */ |
1573 | updatetrap(ci); | 1577 | updatestack(ci); /* stack may have been relocated */ |
1574 | if (trap) { /* stack may have been relocated */ | ||
1575 | updatebase(ci); | ||
1576 | ra = RA(i); | ||
1577 | } | ||
1578 | ci->func -= delta; | 1578 | ci->func -= delta; |
1579 | luaD_poscall(L, ci, cast_int(L->top - ra)); | 1579 | luaD_poscall(L, ci, cast_int(L->top - ra)); |
1580 | return; | 1580 | return; |
@@ -1739,10 +1739,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1739 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); | 1739 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); |
1740 | L->top = ra + 4 + 3; | 1740 | L->top = ra + 4 + 3; |
1741 | Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ | 1741 | Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ |
1742 | if (trap) { /* stack may have changed? */ | 1742 | updatestack(ci); /* stack may have changed */ |
1743 | updatebase(ci); /* keep 'base' correct */ | ||
1744 | ra = RA(i); /* keep 'ra' correct for next instruction */ | ||
1745 | } | ||
1746 | i = *(pc++); /* go to next instruction */ | 1743 | i = *(pc++); /* go to next instruction */ |
1747 | ra += 2; /* adjust for next instruction */ | 1744 | ra += 2; /* adjust for next instruction */ |
1748 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); | 1745 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); |