Explorar o código

configurable stack size + some corrections in error recovery in
`protectedrun'

Roberto Ierusalimschy %!s(int64=26) %!d(string=hai) anos
pai
achega
f356eb010b
Modificáronse 1 ficheiros con 27 adicións e 32 borrados
  1. 27 32
      ldo.c

+ 27 - 32
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.55 1999/12/02 16:24:45 roberto Exp roberto $
+** $Id: ldo.c,v 1.56 1999/12/02 16:41:29 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -28,23 +28,19 @@
 #include "lzio.h"
 
 
-
-#ifndef DEFAULT_STACK_SIZE
-#define DEFAULT_STACK_SIZE      1024
-#endif
-
 #define EXTRA_STACK	32	/* space to handle stack overflow errors */
 
 /*
-** typical numer of recursive calls that fit in the stack
-** (only for error messages)
+** typical numer of stack slots used by a (big) function
+** (this constant is used only for choosing error messages)
 */
-#define REC_DEEP	(DEFAULT_STACK_SIZE/20)
+#define SLOTS_PER_F	20
 
 
-void luaD_init (lua_State *L) {
-  L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject);
-  L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
+void luaD_init (lua_State *L, int stacksize) {
+  L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
+  L->stack_last = L->stack+(stacksize-1);
+  L->stacksize = stacksize;
   L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
   L->Cstack.num = 0;
 }
@@ -52,15 +48,15 @@ void luaD_init (lua_State *L) {
 
 void luaD_checkstack (lua_State *L, int n) {
   if (L->stack_last-L->top <= n) {  /* stack overflow? */
-    if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-1)) {
+    if (L->stack_last-L->stack > (L->stacksize-1)) {
       /* overflow while handling overflow: do what?? */
       L->top -= EXTRA_STACK;
       lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!");
     }
     else {
       L->stack_last += EXTRA_STACK;  /* to be used by error message */
-      if (lua_stackedfunction(L, REC_DEEP) == LUA_NOOBJECT) {
-        /* less than REC_DEEP funcs on stack: doesn't look like a rec. loop */
+      if (lua_stackedfunction(L, L->stacksize/SLOTS_PER_F) == LUA_NOOBJECT) {
+        /* too few funcs on stack: doesn't look like a rec. loop */
         lua_error(L, "Lua2C - C2Lua overflow");
       }
       else
@@ -71,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) {
 
 
 static void restore_stack_limit (lua_State *L) {
-  if (L->top-L->stack < DEFAULT_STACK_SIZE-1)
-    L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
+  if (L->top-L->stack < L->stacksize-1)
+    L->stack_last = L->stack+(L->stacksize-1);
 }
 
 
@@ -145,7 +141,7 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
   if (L->callhook)
     luaD_callHook(L, base, NULL, 0);
   (*f)(L);  /* do the actual call */
-  if (L->callhook)  /* test again: `func' may have changed callhook */
+  if (L->callhook)  /* test again: `func' may change callhook */
     luaD_callHook(L, base, NULL, 1);
   firstResult = L->Cstack.base;
   L->Cstack = oldCLS;
@@ -201,7 +197,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
                        luaV_execute(L, c, tfvalue(proto), func+1);
       break;
     }
-    default: { /* func is not a function */
+    default: { /* `func' is not a function */
       /* Check the tag method for invalid functions */
       const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
       if (ttype(im) == LUA_T_NIL)
@@ -251,13 +247,12 @@ void lua_error (lua_State *L, const char *s) {
 ** parameters are on top of it. Leave nResults on the stack.
 */
 int luaD_protectedrun (lua_State *L) {
-  volatile struct C_Lua_Stack oldCLS = L->Cstack;
   struct lua_longjmp myErrorJmp;
+  volatile StkId base = L->Cstack.base;
   volatile int status;
   struct lua_longjmp *volatile oldErr = L->errorJmp;
   L->errorJmp = &myErrorJmp;
   if (setjmp(myErrorJmp.b) == 0) {
-    StkId base = L->Cstack.base;
     luaD_call(L, base, MULT_RET);
     L->Cstack.lua2C = base;  /* position of the new results */
     L->Cstack.num = L->top - base;
@@ -265,8 +260,8 @@ int luaD_protectedrun (lua_State *L) {
     status = 0;
   }
   else {  /* an error occurred: restore the stack */
-    L->Cstack = oldCLS;
-    L->top = L->Cstack.base;
+    L->Cstack.num = 0;  /* no results */
+    L->top = L->Cstack.base = L->Cstack.lua2C = base;
     restore_stack_limit(L);
     status = 1;
   }
@@ -279,29 +274,29 @@ int luaD_protectedrun (lua_State *L) {
 ** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
 */
 static int protectedparser (lua_State *L, ZIO *z, int bin) {
-  volatile struct C_Lua_Stack oldCLS = L->Cstack;
   struct lua_longjmp myErrorJmp;
+  volatile StkId base = L->Cstack.base;
   volatile int status;
   TProtoFunc *volatile tf;
   struct lua_longjmp *volatile oldErr = L->errorJmp;
   L->errorJmp = &myErrorJmp;
+  L->top = base;   /* erase C2Lua */
   if (setjmp(myErrorJmp.b) == 0) {
     tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
     status = 0;
   }
-  else {  /* an error occurred: restore L->Cstack and L->top */
-    L->Cstack = oldCLS;
-    L->top = L->Cstack.base;
+  else {  /* an error occurred: restore Cstack and top */
+    L->Cstack.num = 0;  /* no results */
+    L->top = L->Cstack.base = L->Cstack.lua2C = base;
     tf = NULL;
     status = 1;
   }
   L->errorJmp = oldErr;
   if (status) return 1;  /* error code */
   if (tf == NULL) return 2;  /* `natural' end */
-  luaD_adjusttop(L, L->Cstack.base, 1);  /* one slot for the pseudo-function */
-  L->Cstack.base->ttype = LUA_T_PROTO;
-  L->Cstack.base->value.tf = tf;
-  luaV_closure(L, 0);
+  L->top->ttype = LUA_T_PROTO;  /* push new function on the stack */
+  L->top->value.tf = tf;
+  incr_top;
   return 0;
 }
 
@@ -313,7 +308,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
     long old_blocks = (luaC_checkGC(L), L->nblocks);
     status = protectedparser(L, z, bin);
     if (status == 1) return 1;  /* error */
-    else if (status == 2) return 0;  /* 'natural' end */
+    else if (status == 2) return 0;  /* `natural' end */
     else {
       unsigned long newelems2 = 2*(L->nblocks-old_blocks);
       L->GCthreshold += newelems2;