aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldo.c11
-rw-r--r--ldo.h1
-rw-r--r--lgc.c7
3 files changed, 16 insertions, 3 deletions
diff --git a/ldo.c b/ldo.c
index 75ce1488..6d0184ec 100644
--- a/ldo.c
+++ b/ldo.c
@@ -221,6 +221,17 @@ l_noret luaD_errerr (lua_State *L) {
221 221
222 222
223/* 223/*
224** Check whether stack has enough space to run a simple function (such
225** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack and
226** 2 slots in the C stack.
227*/
228int luaD_checkminstack (lua_State *L) {
229 return ((stacksize(L) < MAXSTACK - BASIC_STACK_SIZE) &&
230 (getCcalls(L) < LUAI_MAXCCALLS - 2));
231}
232
233
234/*
224** In ISO C, any pointer use after the pointer has been deallocated is 235** In ISO C, any pointer use after the pointer has been deallocated is
225** undefined behavior. So, before a stack reallocation, all pointers 236** undefined behavior. So, before a stack reallocation, all pointers
226** should be changed to offsets, and after the reallocation they should 237** should be changed to offsets, and after the reallocation they should
diff --git a/ldo.h b/ldo.h
index 2d4ca8be..b6472954 100644
--- a/ldo.h
+++ b/ldo.h
@@ -89,6 +89,7 @@ LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror);
89LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 89LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror);
90LUAI_FUNC void luaD_shrinkstack (lua_State *L); 90LUAI_FUNC void luaD_shrinkstack (lua_State *L);
91LUAI_FUNC void luaD_inctop (lua_State *L); 91LUAI_FUNC void luaD_inctop (lua_State *L);
92LUAI_FUNC int luaD_checkminstack (lua_State *L);
92 93
93LUAI_FUNC l_noret luaD_throw (lua_State *L, TStatus errcode); 94LUAI_FUNC l_noret luaD_throw (lua_State *L, TStatus errcode);
94LUAI_FUNC l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode); 95LUAI_FUNC l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode);
diff --git a/lgc.c b/lgc.c
index 60f042c7..c64d74b8 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1293,7 +1293,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
1293 correctgraylists(g); 1293 correctgraylists(g);
1294 checkSizes(L, g); 1294 checkSizes(L, g);
1295 g->gcstate = GCSpropagate; /* skip restart */ 1295 g->gcstate = GCSpropagate; /* skip restart */
1296 if (!g->gcemergency) 1296 if (!g->gcemergency && luaD_checkminstack(L))
1297 callallpendingfinalizers(L); 1297 callallpendingfinalizers(L);
1298} 1298}
1299 1299
@@ -1667,12 +1667,13 @@ static l_mem singlestep (lua_State *L, int fast) {
1667 break; 1667 break;
1668 } 1668 }
1669 case GCScallfin: { /* call finalizers */ 1669 case GCScallfin: { /* call finalizers */
1670 if (g->tobefnz && !g->gcemergency) { 1670 if (g->tobefnz && !g->gcemergency && luaD_checkminstack(L)) {
1671 g->gcstopem = 0; /* ok collections during finalizers */ 1671 g->gcstopem = 0; /* ok collections during finalizers */
1672 GCTM(L); /* call one finalizer */ 1672 GCTM(L); /* call one finalizer */
1673 stepresult = CWUFIN; 1673 stepresult = CWUFIN;
1674 } 1674 }
1675 else { /* emergency mode or no more finalizers */ 1675 else { /* no more finalizers or emergency mode or no enough stack
1676 to run finalizers */
1676 g->gcstate = GCSpause; /* finish collection */ 1677 g->gcstate = GCSpause; /* finish collection */
1677 stepresult = step2pause; 1678 stepresult = step2pause;
1678 } 1679 }