Browse Source

some bugs related to stack reallocation

Roberto Ierusalimschy 20 years ago
parent
commit
98296f6b45
6 changed files with 42 additions and 38 deletions
  1. 2 1
      lapi.c
  2. 14 18
      ldo.c
  3. 1 11
      ldo.h
  4. 4 2
      lgc.h
  5. 10 1
      llimits.h
  6. 11 5
      lvm.c

+ 2 - 1
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.45 2005/07/06 18:07:30 roberto Exp roberto $
+** $Id: lapi.c,v 2.46 2005/07/31 17:12:32 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -344,6 +344,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
       return NULL;
     }
     luaC_checkGC(L);
+    o = index2adr(L, idx);  /* previous call may reallocate the stack */
     lua_unlock(L);
   }
   if (len != NULL) *len = tsvalue(o)->len;

+ 14 - 18
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.30 2005/08/22 18:54:49 roberto Exp roberto $
+** $Id: ldo.c,v 2.31 2005/08/22 19:58:29 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -205,19 +205,17 @@ void luaD_callhook (lua_State *L, int event, int line) {
 }
 
 
-static StkId adjust_varargs (lua_State *L, int nfixargs, int actual,
-                             int style) {
+static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
   int i;
+  int nfixargs = p->numparams;
   Table *htab = NULL;
   StkId base, fixed;
-  if (actual < nfixargs) {
-    for (; actual < nfixargs; ++actual)
-      setnilvalue(L->top++);
-  }
+  for (; actual < nfixargs; ++actual)
+    setnilvalue(L->top++);
 #if defined(LUA_COMPAT_VARARG)
-  if (style & VARARG_NEEDSARG) {  /* compatibility with old-style vararg */
+  if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
     int nvar = actual - nfixargs;  /* number of extra arguments */
-    lua_assert(style & VARARG_HASARG);
+    lua_assert(p->is_vararg & VARARG_HASARG);
     luaC_checkGC(L);
     htab = luaH_new(L, nvar, 1);  /* create `arg' table */
     for (i=0; i<nvar; i++)  /* put extra arguments into `arg' table */
@@ -276,16 +274,14 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
     CallInfo *ci;
     StkId st, base;
     Proto *p = cl->p;
-    if (p->is_vararg) {  /* varargs? */
-      int nargs = cast(int, L->top - restorestack(L, funcr)) - 1;
-      luaD_checkstack(L, p->maxstacksize + nargs);
-      base = adjust_varargs(L, p->numparams, nargs, p->is_vararg);
-      func = restorestack(L, funcr);
-    }
-    else {
-      luaD_checkstack(L, p->maxstacksize);
-      func = restorestack(L, funcr);
+    luaD_checkstack(L, p->maxstacksize);
+    func = restorestack(L, funcr);
+    if (!p->is_vararg)  /* no varargs? */
       base = func + 1;
+    else {  /* vararg function */
+      int nargs = cast(int, L->top - func) - 1;
+      base = adjust_varargs(L, p, nargs);
+      func = restorestack(L, funcr);  /* previous call may change the stack */
     }
     ci = inc_ci(L);  /* now `enter' new function */
     ci->func = func;

+ 1 - 11
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 2.5 2005/08/22 18:54:49 roberto Exp roberto $
+** $Id: ldo.h,v 2.6 2005/08/22 19:58:29 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -13,16 +13,6 @@
 #include "lzio.h"
 
 
-/*
-** macro to control inclusion of some hard tests on stack reallocation
-*/ 
-#ifndef HARDSTACKTESTS
-#define condhardstacktests(x)	((void)0)
-#else
-#define condhardstacktests(x)	x
-#endif
-
-
 #define luaD_checkstack(L,n)	\
   if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
     luaD_growstack(L, n); \

+ 4 - 2
lgc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.h,v 2.13 2005/04/25 19:24:10 roberto Exp roberto $
+** $Id: lgc.h,v 2.14 2005/06/07 18:53:45 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -77,7 +77,9 @@
 #define luaC_white(g)	cast(lu_byte, (g)->currentwhite & WHITEBITS)
 
 
-#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
+#define luaC_checkGC(L) { \
+  condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
+  if (G(L)->totalbytes >= G(L)->GCthreshold) \
 	luaC_step(L); }
 
 

+ 10 - 1
llimits.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llimits.h,v 1.65 2005/03/09 16:28:07 roberto Exp roberto $
+** $Id: llimits.h,v 1.66 2005/08/04 13:37:10 roberto Exp roberto $
 ** Limits, basic types, and some other `installation-dependent' definitions
 ** See Copyright Notice in lua.h
 */
@@ -103,4 +103,13 @@ typedef lu_int32 Instruction;
 #endif
 
 
+/*
+** macro to control inclusion of some hard tests on stack reallocation
+*/ 
+#ifndef HARDSTACKTESTS
+#define condhardstacktests(x)	((void)0)
+#else
+#define condhardstacktests(x)	x
+#endif
+
 #endif

+ 11 - 5
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.51 2005/08/10 20:20:13 roberto Exp roberto $
+** $Id: lvm.c,v 2.52 2005/08/22 18:54:49 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -763,13 +763,19 @@ void luaV_execute (lua_State *L, int nexeccalls) {
         CallInfo *ci = L->ci;
         int n = cast(int, ci->base - ci->func) - cl->p->numparams - 1;
         if (b == LUA_MULTRET) {
+          Protect(luaD_checkstack(L, n));
+          ra = RA(i);  /* previous call may change the stack */
           b = n;
           L->top = ra + n;
         }
-        for (j=0; j<b && j<n; j++)
-          setobjs2s(L, ra+j, ci->base - n + j);
-        for (; j<b; j++)
-          setnilvalue(ra+j);
+        for (j = 0; j < b; j++) {
+          if (j < n) {
+            setobjs2s(L, ra + j, ci->base - n + j);
+          }
+          else {
+            setnilvalue(ra + j);
+          }
+        }
         continue;
       }
     }