Browse Source

cleaner and more correct code for 'luaD_shrinkstack' (the old
test "inuse <= LUAI_MAXSTACK" for stack overflow is not correct,
as the real maximum usable size is "LUAI_MAXSTACK - EXTRA_STACK")

Roberto Ierusalimschy 9 years ago
parent
commit
7fe1a4cff3
1 changed files with 8 additions and 5 deletions
  1. 8 5
      ldo.c

+ 8 - 5
ldo.c

@@ -221,14 +221,17 @@ static int stackinuse (lua_State *L) {
 void luaD_shrinkstack (lua_State *L) {
 void luaD_shrinkstack (lua_State *L) {
   int inuse = stackinuse(L);
   int inuse = stackinuse(L);
   int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
   int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
-  if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
-  if (L->stacksize > LUAI_MAXSTACK)  /* was handling stack overflow? */
+  if (goodsize > LUAI_MAXSTACK)
+    goodsize = LUAI_MAXSTACK;  /* respect stack limit */
+  if (L->stacksize > LUAI_MAXSTACK)  /* had been handling stack overflow? */
     luaE_freeCI(L);  /* free all CIs (list grew because of an error) */
     luaE_freeCI(L);  /* free all CIs (list grew because of an error) */
   else
   else
     luaE_shrinkCI(L);  /* shrink list */
     luaE_shrinkCI(L);  /* shrink list */
-  if (inuse <= LUAI_MAXSTACK &&  /* not handling stack overflow? */
-      goodsize < L->stacksize)  /* trying to shrink? */
-    luaD_reallocstack(L, goodsize);  /* shrink it */
+  /* if thread is currently not handling a stack overflow and its
+     good size is smaller than current size, shrink its stack */
+  if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
+      goodsize < L->stacksize)
+    luaD_reallocstack(L, goodsize);
   else
   else
     condmovestack(L,,);  /* don't change stack (change only for debugging) */
     condmovestack(L,,);  /* don't change stack (change only for debugging) */
 }
 }