aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-07-08 12:02:56 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-07-08 12:02:56 -0300
commit31b8c2d4380a762d1ed6a7faee74a1d107f86014 (patch)
tree758ffbdfc17bc9c33f11fdce89abbda33d860e64
parenteb41999461b6f428186c55abd95f4ce1a76217d5 (diff)
downloadlua-31b8c2d4380a762d1ed6a7faee74a1d107f86014.tar.gz
lua-31b8c2d4380a762d1ed6a7faee74a1d107f86014.tar.bz2
lua-31b8c2d4380a762d1ed6a7faee74a1d107f86014.zip
Fixed bug of access violation in finalizers
Errors in finalizers need a valid 'pc' to produce an error message, even if the error is not propagated. Therefore, calls to the GC (which may call finalizers) inside luaV_execute must save the 'pc'.
-rw-r--r--lvm.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/lvm.c b/lvm.c
index d78d6be2..66d451b0 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1101,9 +1101,9 @@ void luaV_finishOp (lua_State *L) {
1101/* idem, but without changing the stack */ 1101/* idem, but without changing the stack */
1102#define halfProtectNT(exp) (savepc(L), (exp)) 1102#define halfProtectNT(exp) (savepc(L), (exp))
1103 1103
1104 1104/* 'c' is the limit of live values in the stack */
1105#define checkGC(L,c) \ 1105#define checkGC(L,c) \
1106 { luaC_condGC(L, L->top = (c), /* limit of live values */ \ 1106 { luaC_condGC(L, (savepc(L), L->top = (c)), \
1107 updatetrap(ci)); \ 1107 updatetrap(ci)); \
1108 luai_threadyield(L); } 1108 luai_threadyield(L); }
1109 1109
@@ -1791,8 +1791,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1791 vmbreak; 1791 vmbreak;
1792 } 1792 }
1793 vmcase(OP_VARARGPREP) { 1793 vmcase(OP_VARARGPREP) {
1794 luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p); 1794 ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
1795 updatetrap(ci);
1796 if (trap) { 1795 if (trap) {
1797 luaD_hookcall(L, ci); 1796 luaD_hookcall(L, ci);
1798 L->oldpc = pc + 1; /* next opcode will be seen as a "new" line */ 1797 L->oldpc = pc + 1; /* next opcode will be seen as a "new" line */