Răsfoiți Sursa

simpler way to control stack overflow

Roberto Ierusalimschy 23 ani în urmă
părinte
comite
81215cd59f
4 a modificat fișierele cu 51 adăugiri și 44 ștergeri
  1. 2 2
      lapi.c
  2. 37 36
      ldo.c
  3. 10 4
      llimits.h
  4. 2 2
      lstate.h

+ 2 - 2
lapi.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lapi.c,v 1.178 2002/03/18 20:11:52 roberto Exp roberto $
+** $Id: lapi.c,v 1.179 2002/03/20 12:51:29 roberto Exp roberto $
 ** Lua API
 ** Lua API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -85,7 +85,7 @@ void luaA_pushobject (lua_State *L, const TObject *o) {
 LUA_API int lua_checkstack (lua_State *L, int size) {
 LUA_API int lua_checkstack (lua_State *L, int size) {
   int res;
   int res;
   lua_lock(L);
   lua_lock(L);
-  if ((L->top - L->stack) >= LUA_MAXSTACK - size)
+  if ((L->top - L->ci->base + size) > LUA_MAXCSTACK)
     res = 0;  /* stack overflow */
     res = 0;  /* stack overflow */
   else {
   else {
     luaD_checkstack(L, size);
     luaD_checkstack(L, size);

+ 37 - 36
ldo.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.c,v 1.166 2002/03/25 17:47:14 roberto Exp roberto $
+** $Id: ldo.c,v 1.167 2002/03/25 19:45:06 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -70,30 +70,51 @@ void luaD_reallocstack (lua_State *L, int newsize) {
 }
 }
 
 
 
 
+static void correctCI (lua_State *L, CallInfo *oldci) {
+  struct lua_longjmp *lj;
+  for (lj = L->errorJmp; lj != NULL; lj = lj->previous) {
+    lj->ci = (lj->ci - oldci) + L->base_ci;
+  }
+}
+
+
+void luaD_reallocCI (lua_State *L, int newsize) {
+  CallInfo *oldci = L->base_ci;
+  luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
+  L->size_ci = newsize;
+  L->ci = (L->ci - oldci) + L->base_ci;
+  L->end_ci = L->base_ci + L->size_ci;
+  correctCI(L, oldci);
+}
+
+
 static void restore_stack_limit (lua_State *L) {
 static void restore_stack_limit (lua_State *L) {
-  if (L->stacksize > LUA_MAXSTACK) {  /* there was an overflow? */
-    int inuse = (L->top - L->stack);
-    if (inuse + MAXSTACK < LUA_MAXSTACK)  /* can `undo' overflow? */
-      luaD_reallocstack(L, LUA_MAXSTACK);
+  if (L->size_ci > LUA_MAXCALLS) {  /* there was an overflow? */
+    int inuse = (L->ci - L->base_ci);
+    if (inuse + 1 < LUA_MAXCALLS)  /* can `undo' overflow? */
+      luaD_reallocCI(L, LUA_MAXCALLS);
   }
   }
 }
 }
 
 
 
 
 void luaD_growstack (lua_State *L, int n) {
 void luaD_growstack (lua_State *L, int n) {
-  if (L->stacksize > LUA_MAXSTACK) {  /* overflow while handling overflow? */
+  if (n <= L->stacksize)  /* double size is enough? */
+    luaD_reallocstack(L, 2*L->stacksize);
+  else
+    luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK);
+}
+
+
+static void luaD_growCI (lua_State *L) {
+  L->ci--;
+  if (L->size_ci > LUA_MAXCALLS)  /* overflow while handling overflow? */
     luaD_breakrun(L, LUA_ERRERR);  /* break run without error message */
     luaD_breakrun(L, LUA_ERRERR);  /* break run without error message */
-  }
   else {
   else {
-    if (n <= L->stacksize && 2*L->stacksize < LUA_MAXSTACK)  /* can double? */
-      luaD_reallocstack(L, 2*L->stacksize);
-   else if ((L->top - L->stack) + n <= LUA_MAXSTACK)  /* no overflow? */
-      luaD_reallocstack(L, LUA_MAXSTACK);
-   else {
-      /* resize to maximum + some extra space to handle error */
-      luaD_reallocstack(L, LUA_MAXSTACK+4*LUA_MINSTACK);
+    luaD_reallocCI(L, 2*L->size_ci);
+    if (L->size_ci > LUA_MAXCALLS)
       luaD_error(L, "stack overflow");
       luaD_error(L, "stack overflow");
-    }
   }
   }
+  L->ci++;
 }
 }
 
 
 
 
@@ -145,26 +166,6 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
 }
 }
 
 
 
 
-static void correctCI (lua_State *L, CallInfo *oldci) {
-  struct lua_longjmp *lj;
-  for (lj = L->errorJmp; lj != NULL; lj = lj->previous) {
-    lj->ci = (lj->ci - oldci) + L->base_ci;
-  }
-}
-
-
-void luaD_reallocCI (lua_State *L, int newsize) {
-  CallInfo *oldci = L->base_ci;
-  luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
-  L->size_ci = newsize;
-  if (oldci != L->ci) {
-    L->ci = (L->ci - oldci) + L->base_ci;
-    L->end_ci = L->base_ci + L->size_ci;
-    correctCI(L, oldci);
-  }
-}
-
-
 static void adjust_varargs (lua_State *L, int nfixargs) {
 static void adjust_varargs (lua_State *L, int nfixargs) {
   int i;
   int i;
   Table *htab;
   Table *htab;
@@ -205,7 +206,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
 StkId luaD_precall (lua_State *L, StkId func) {
 StkId luaD_precall (lua_State *L, StkId func) {
   CallInfo *ci;
   CallInfo *ci;
   LClosure *cl;
   LClosure *cl;
-  if (++L->ci == L->end_ci) luaD_reallocCI(L, 2*L->size_ci);
+  if (++L->ci == L->end_ci) luaD_growCI(L);
   ci = L->ci;
   ci = L->ci;
   ci->base = ci->top = func+1;  /* pre-init `top' in case of errors */
   ci->base = ci->top = func+1;  /* pre-init `top' in case of errors */
   ci->pc = NULL;
   ci->pc = NULL;

+ 10 - 4
llimits.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: llimits.h,v 1.40 2002/03/14 18:01:52 roberto Exp roberto $
+** $Id: llimits.h,v 1.41 2002/03/18 18:16:16 roberto Exp roberto $
 ** Limits, basic types, and some other `installation-dependent' definitions
 ** Limits, basic types, and some other `installation-dependent' definitions
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -101,9 +101,15 @@ union L_Umaxalign { LUSER_ALIGNMENT_T u; void *s; long l; };
 typedef unsigned long Instruction;
 typedef unsigned long Instruction;
 
 
 
 
-/* maximum size for the Lua stack */
-#ifndef LUA_MAXSTACK
-#define LUA_MAXSTACK        14000
+/* maximum depth for calls */
+#ifndef LUA_MAXCALLS
+#define LUA_MAXCALLS        2048
+#endif
+
+
+/* maximum size for the C stack */
+#ifndef LUA_MAXCSTACK
+#define LUA_MAXCSTACK        2048
 #endif
 #endif
 
 
 
 

+ 2 - 2
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 1.79 2002/03/11 12:45:00 roberto Exp roberto $
+** $Id: lstate.h,v 1.80 2002/03/25 17:47:14 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -69,7 +69,7 @@ struct lua_longjmp;  /* defined in ldo.c */
 #define EXTRA_STACK   4
 #define EXTRA_STACK   4
 
 
 
 
-#define BASIC_CI_SIZE           6
+#define BASIC_CI_SIZE           8
 
 
 #define BASIC_STACK_SIZE        (2*LUA_MINSTACK)
 #define BASIC_STACK_SIZE        (2*LUA_MINSTACK)