Browse Source

fixed stack; first version.

Roberto Ierusalimschy 26 years ago
parent
commit
fe237ad808
10 changed files with 400 additions and 402 deletions
  1. 50 53
      lapi.c
  2. 46 53
      lbuiltin.c
  3. 88 83
      ldo.c
  4. 9 9
      ldo.h
  5. 4 4
      lgc.c
  6. 4 4
      lparser.c
  7. 2 5
      lstate.c
  8. 14 13
      lstate.h
  9. 178 173
      lvm.c
  10. 5 5
      lvm.h

+ 50 - 53
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.59 1999/11/29 19:11:36 roberto Exp roberto $
+** $Id: lapi.c,v 1.60 1999/11/29 19:31:29 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -63,28 +63,28 @@ static const TObject *luaA_protovalue (const TObject *o) {
 
 
 static void checkCparams (lua_State *L, int nParams) {
-  if (L->stack.top-L->stack.stack < L->Cstack.base+nParams)
+  if (nParams > L->top-L->Cstack.base)
     lua_error(L, "API error - wrong number of arguments in C2lua stack");
 }
 
 
 static lua_Object put_luaObject (lua_State *L, const TObject *o) {
-  luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base);
-  L->stack.stack[L->Cstack.base++] = *o;
-  return L->Cstack.base;  /* this is +1 real position (see Ref) */
+  luaD_openstack(L, L->Cstack.base);
+  *L->Cstack.base++ = *o;
+  return Ref(L, L->Cstack.base-1);
 }
 
 
 lua_Object luaA_putObjectOnTop (lua_State *L) {
-  luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base);
-  L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
-  return L->Cstack.base;  /* this is +1 real position (see Ref) */
+  luaD_openstack(L, L->Cstack.base);
+  *L->Cstack.base++ = *(--L->top);
+  return Ref(L, L->Cstack.base-1);
 }
 
 
 static void top2LC (lua_State *L, int n) {
   /* Put the 'n' elements on the top as the Lua2C contents */
-  L->Cstack.base = (L->stack.top-L->stack.stack);  /* new base */
+  L->Cstack.base = L->top;  /* new base */
   L->Cstack.lua2C = L->Cstack.base-n;  /* position of the new results */
   L->Cstack.num = n;  /* number of results */
 }
@@ -98,13 +98,11 @@ lua_Object lua_pop (lua_State *L) {
 
 /*
 ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
-** 'number' must be 1 to get the first parameter.
+** `number' must be 1 to get the first parameter.
 */
 lua_Object lua_lua2C (lua_State *L, int number) {
   if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
-  /* Ref(L, L->stack.stack+(L->Cstack.lua2C+number-1)) ==
-     L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */
-  return L->Cstack.lua2C+number;
+  return Ref(L, L->Cstack.lua2C+number-1);
 }
 
 
@@ -112,8 +110,8 @@ int lua_callfunction (lua_State *L, lua_Object function) {
   if (function == LUA_NOOBJECT)
     return 1;
   else {
-    luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base);
-    set_normalized(L->stack.stack+L->Cstack.base, Address(L, function));
+    luaD_openstack(L, L->Cstack.base);
+    set_normalized(L->Cstack.base, Address(L, function));
     return luaD_protectedrun(L);
   }
 }
@@ -126,7 +124,7 @@ lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) {
 
 lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) {
   checkCparams(L, 1);
-  luaT_settagmethod(L, tag, event, L->stack.top-1);
+  luaT_settagmethod(L, tag, event, L->top-1);
   return luaA_putObjectOnTop(L);
 }
 
@@ -149,24 +147,24 @@ lua_Object lua_gettable (lua_State *L) {
 
 lua_Object lua_rawgettable (lua_State *L) {
   checkCparams(L, 2);
-  if (ttype(L->stack.top-2) != LUA_T_ARRAY)
+  if (ttype(L->top-2) != LUA_T_ARRAY)
     lua_error(L, "indexed expression not a table in rawgettable");
-  *(L->stack.top-2) = *luaH_get(L, avalue(L->stack.top-2), L->stack.top-1);
-  --L->stack.top;
+  *(L->top-2) = *luaH_get(L, avalue(L->top-2), L->top-1);
+  --L->top;
   return luaA_putObjectOnTop(L);
 }
 
 
 void lua_settable (lua_State *L) {
   checkCparams(L, 3);
-  luaV_settable(L, L->stack.top-3);
-  L->stack.top -= 2;  /* pop table and index */
+  luaV_settable(L, L->top-3);
+  L->top -= 2;  /* pop table and index */
 }
 
 
 void lua_rawsettable (lua_State *L) {
   checkCparams(L, 3);
-  luaV_rawsettable(L, L->stack.top-3);
+  luaV_rawsettable(L, L->top-3);
 }
 
 
@@ -202,7 +200,7 @@ void lua_setglobal (lua_State *L, const char *name) {
 void lua_rawsetglobal (lua_State *L, const char *name) {
   GlobalVar *gv = luaS_assertglobalbyname(L, name);
   checkCparams(L, 1);
-  gv->value = *(--L->stack.top);
+  gv->value = *(--L->top);
 }
 
 
@@ -280,19 +278,19 @@ lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
 
 
 void lua_pushnil (lua_State *L) {
-  ttype(L->stack.top) = LUA_T_NIL;
+  ttype(L->top) = LUA_T_NIL;
   incr_top;
 }
 
 void lua_pushnumber (lua_State *L, double n) {
-  ttype(L->stack.top) = LUA_T_NUMBER;
-  nvalue(L->stack.top) = n;
+  ttype(L->top) = LUA_T_NUMBER;
+  nvalue(L->top) = n;
   incr_top;
 }
 
 void lua_pushlstring (lua_State *L, const char *s, long len) {
-  tsvalue(L->stack.top) = luaS_newlstr(L, s, len);
-  ttype(L->stack.top) = LUA_T_STRING;
+  tsvalue(L->top) = luaS_newlstr(L, s, len);
+  ttype(L->top) = LUA_T_STRING;
   incr_top;
   luaC_checkGC(L);
 }
@@ -308,8 +306,8 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
   if (fn == NULL)
     lua_error(L, "API error - attempt to push a NULL Cfunction");
   checkCparams(L, n);
-  ttype(L->stack.top) = LUA_T_CPROTO;
-  fvalue(L->stack.top) = fn;
+  ttype(L->top) = LUA_T_CPROTO;
+  fvalue(L->top) = fn;
   incr_top;
   luaV_closure(L, n);
   luaC_checkGC(L);
@@ -318,21 +316,21 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
 void lua_pushusertag (lua_State *L, void *u, int tag) {
   if (tag < 0 && tag != LUA_ANYTAG)
     luaT_realtag(L, tag);  /* error if tag is not valid */
-  tsvalue(L->stack.top) = luaS_createudata(L, u, tag);
-  ttype(L->stack.top) = LUA_T_USERDATA;
+  tsvalue(L->top) = luaS_createudata(L, u, tag);
+  ttype(L->top) = LUA_T_USERDATA;
   incr_top;
   luaC_checkGC(L);
 }
 
 void luaA_pushobject (lua_State *L, const TObject *o) {
-  *L->stack.top = *o;
+  *L->top = *o;
   incr_top;
 }
 
 void lua_pushobject (lua_State *L, lua_Object o) {
   if (o == LUA_NOOBJECT)
     lua_error(L, "API error - attempt to push a NOOBJECT");
-  set_normalized(L->stack.top, Address(L, o));
+  set_normalized(L->top, Address(L, o));
   incr_top;
 }
 
@@ -368,18 +366,18 @@ int lua_tag (lua_State *L, lua_Object lo) {
 void lua_settag (lua_State *L, int tag) {
   checkCparams(L, 1);
   luaT_realtag(L, tag);
-  switch (ttype(L->stack.top-1)) {
+  switch (ttype(L->top-1)) {
     case LUA_T_ARRAY:
-      (L->stack.top-1)->value.a->htag = tag;
+      (L->top-1)->value.a->htag = tag;
       break;
     case LUA_T_USERDATA:
-      (L->stack.top-1)->value.ts->u.d.tag = tag;
+      (L->top-1)->value.ts->u.d.tag = tag;
       break;
     default:
       luaL_verror(L, "cannot change the tag of a %.20s",
-                  luaO_typename(L, L->stack.top-1));
+                  luaO_typename(L, L->top-1));
   }
-  L->stack.top--;
+  L->top--;
 }
 
 
@@ -395,7 +393,7 @@ GlobalVar *luaA_nextvar (lua_State *L, TaggedString *ts) {
   while (gv && gv->value.ttype == LUA_T_NIL)  /* skip globals with nil */
     gv = gv->next;
   if (gv) {
-    ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = gv->name;
+    ttype(L->top) = LUA_T_STRING; tsvalue(L->top) = gv->name;
     incr_top;
     luaA_pushobject(L, &gv->value);
   }
@@ -479,12 +477,12 @@ int lua_setdebug (lua_State *L, int debug) {
 
 
 lua_Function lua_stackedfunction (lua_State *L, int level) {
-  StkId i;
-  for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) {
-    int t = L->stack.stack[i].ttype;
+  int i;
+  for (i = (L->top-1)-L->stack; i>=0; i--) {
+    int t = L->stack[i].ttype;
     if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
       if (level-- == 0)
-        return Ref(L, L->stack.stack+i);
+        return Ref(L, L->stack+i);
   }
   return LUA_NOOBJECT;
 }
@@ -498,8 +496,7 @@ int lua_nups (lua_State *L, lua_Function func) {
 
 int lua_currentline (lua_State *L, lua_Function func) {
   const TObject *f = Address(L, func);
-  return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ?
-             (f+1)->value.i : -1;
+  return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1;
 }
 
 
@@ -533,11 +530,11 @@ int lua_setlocal (lua_State *L, lua_Function func, int local_number) {
     const char *name = luaF_getlocalname(fp, local_number,
                                          lua_currentline(L, func));
     checkCparams(L, 1);
-    --L->stack.top;
+    --L->top;
     if (name) {
       /* if "name", there must be a LUA_T_LINE */
       /* therefore, f+2 points to function base */
-      *((f+2)+(local_number-1)) = *L->stack.top;
+      *((f+2)+(local_number-1)) = *L->top;
       return 1;
     }
     else
@@ -565,14 +562,14 @@ void lua_funcinfo (lua_State *L, lua_Object func,
 
 
 static int checkfunc (lua_State *L, TObject *o) {
-  return luaO_equalObj(o, L->stack.top);
+  return luaO_equalObj(o, L->top);
 }
 
 
 const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) {
   /* try to find a name for given function */
   GlobalVar *g;
-  set_normalized(L->stack.top, Address(L, o)); /* to be used by `checkfunc' */
+  set_normalized(L->top, Address(L, o)); /* to be used by `checkfunc' */
   for (g=L->rootglobal; g; g=g->next) {
     if (checkfunc(L, &g->value)) {
       *name = g->name->str;
@@ -610,7 +607,7 @@ void lua_beginblock (lua_State *L) {
 void lua_endblock (lua_State *L) {
   --L->numCblocks;
   L->Cstack = L->Cblocks[L->numCblocks];
-  luaD_adjusttop(L, L->Cstack.base);
+  L->top = L->Cstack.base;
 }
 
 
@@ -618,8 +615,8 @@ void lua_endblock (lua_State *L) {
 int lua_ref (lua_State *L, int lock) {
   int ref;
   checkCparams(L, 1);
-  ref = luaR_ref(L, L->stack.top-1, lock);
-  L->stack.top--;
+  ref = luaR_ref(L, L->top-1, lock);
+  L->top--;
   return ref;
 }
 

+ 46 - 53
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.77 1999/11/29 19:11:36 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.78 1999/11/30 13:06:50 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -37,8 +37,8 @@
 
 
 static void pushtagstring (lua_State *L, TaggedString *s) {
-  ttype(L->stack.top) = LUA_T_STRING;
-  tsvalue(L->stack.top) = s;
+  ttype(L->top) = LUA_T_STRING;
+  tsvalue(L->top) = s;
   incr_top;
 }
 
@@ -303,7 +303,7 @@ static void luaB_call (lua_State *L) {
   /* push arg[1...n] */
   luaD_checkstack(L, narg);
   for (i=0; i<narg; i++)
-    *(L->stack.top++) = *luaH_getint(L, arg, i+1);
+    *(L->top++) = *luaH_getint(L, arg, i+1);
   status = lua_callfunction(L, f);
   if (err != LUA_NOOBJECT) {  /* restore old error method */
     lua_pushobject(L, err);
@@ -319,7 +319,7 @@ static void luaB_call (lua_State *L) {
   }
   else {  /* no errors */
     if (strchr(options, 'p')) {  /* pack results? */
-      luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->stack.top);
+      luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top);
       incr_top;
     }
     else
@@ -414,65 +414,60 @@ static void luaB_assert (lua_State *L) {
 
 
 static void luaB_foreachi (lua_State *L) {
-  struct Stack *S = &L->stack;
   const Hash *t = gettable(L, 1);
   int n = (int)getnarg(L, t);
   int i;
-  StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack;
-  /* 'f' cannot be a pointer to TObject, because it is on the stack, and the
-     stack may be reallocated by the call. */
+  StkId f = luaA_Address(L, luaL_functionarg(L, 2));
   luaD_checkstack(L, 3);  /* for f, key, and val */
   for (i=1; i<=n; i++) {
-    *(S->top++) = *(S->stack+f);
-    ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i;
-    *(S->top++) = *luaH_getint(L, t, i);
-    luaD_call(L, S->top-3, 1);
-    if (ttype(S->top-1) != LUA_T_NIL)
+    *(L->top++) = *f;
+    ttype(L->top) = LUA_T_NUMBER; nvalue(L->top++) = i;
+    *(L->top++) = *luaH_getint(L, t, i);
+    luaD_call(L, L->top-3, 1);
+    if (ttype(L->top-1) != LUA_T_NIL)
       return;
-    S->top--;
+    L->top--;
   }
 }
 
 
 static void luaB_foreach (lua_State *L) {
-  struct Stack *S = &L->stack;
   const Hash *a = gettable(L, 1);
-  StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack;
+  StkId f = luaA_Address(L, luaL_functionarg(L, 2));
   int i;
   luaD_checkstack(L, 3);  /* for f, key, and val */
   for (i=0; i<a->size; i++) {
     const Node *nd = &(a->node[i]);
     if (ttype(val(nd)) != LUA_T_NIL) {
-      *(S->top++) = *(S->stack+f);
-      *(S->top++) = *key(nd);
-      *(S->top++) = *val(nd);
-      luaD_call(L, S->top-3, 1);
-      if (ttype(S->top-1) != LUA_T_NIL)
+      *(L->top++) = *f;
+      *(L->top++) = *key(nd);
+      *(L->top++) = *val(nd);
+      luaD_call(L, L->top-3, 1);
+      if (ttype(L->top-1) != LUA_T_NIL)
         return;
-      S->top--;  /* remove result */
+      L->top--;  /* remove result */
     }
   }
 }
 
 
 static void luaB_foreachvar (lua_State *L) {
-  struct Stack *S = &L->stack;
-  StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack;
+  StkId f = luaA_Address(L, luaL_functionarg(L, 1));
   GlobalVar *gv;
   luaD_checkstack(L, 4);  /* for extra var name, f, var name, and globalval */
   for (gv = L->rootglobal; gv; gv = gv->next) {
     if (gv->value.ttype != LUA_T_NIL) {
       pushtagstring(L, gv->name);  /* keep (extra) name on stack to avoid GC */
-      *(S->top++) = *(S->stack+f);
+      *(L->top++) = *f;
       pushtagstring(L, gv->name);
-      *(S->top++) = gv->value;
-      luaD_call(L, S->top-3, 1);
-      if (ttype(S->top-1) != LUA_T_NIL) {
-        S->top--;
-        *(S->top-1) = *S->top;  /* remove extra name */
+      *(L->top++) = gv->value;
+      luaD_call(L, L->top-3, 1);
+      if (ttype(L->top-1) != LUA_T_NIL) {
+        L->top--;
+        *(L->top-1) = *L->top;  /* remove extra name */
         return;
       }
-      S->top-=2;  /* remove result and extra name */
+      L->top-=2;  /* remove result and extra name */
     }
   }
 }
@@ -530,26 +525,24 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
                                                   const TObject *b) {
   /* notice: the caller (auxsort) must check stack space */
   if (f != LUA_NOOBJECT) {
-    *(L->stack.top) = *luaA_Address(L, f);
-    *(L->stack.top+1) = *a;
-    *(L->stack.top+2) = *b;
-    L->stack.top += 3;
-    luaD_call(L, L->stack.top-3, 1);
+    *(L->top) = *luaA_Address(L, f);
+    *(L->top+1) = *a;
+    *(L->top+2) = *b;
+    L->top += 3;
+    luaD_call(L, L->top-3, 1);
   }
   else {  /* a < b? */
-    *(L->stack.top) = *a;
-    *(L->stack.top+1) = *b;
-    L->stack.top += 2;
-    luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
+    *(L->top) = *a;
+    *(L->top+1) = *b;
+    luaV_comparison(L, L->top+2, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
+    L->top++;  /* result of comparison */
   }
-  return ttype(--(L->stack.top)) != LUA_T_NIL;
+  return ttype(--(L->top)) != LUA_T_NIL;
 }
 
 static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
-  struct Stack *S = &L->stack;
-  StkId P = S->top - S->stack;  /* temporary place for pivot */
-  S->top++;
-  ttype(S->stack+P) = LUA_T_NIL;
+  StkId P = L->top++;  /* temporary place for pivot */
+  ttype(P) = LUA_T_NIL;
   while (l < u) {  /* for tail recursion */
     int i, j;
     /* sort elements a[l], a[(l+u)/2] and a[u] */
@@ -557,22 +550,22 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
       swap(L, a, l, u);  /* a[u]<a[l] */
     if (u-l == 1) break;  /* only 2 elements */
     i = (l+u)/2;
-    *(S->stack+P) = *luaH_getint(L, a, i);  /* P = a[i] */
-    if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l)))  /* a[i]<a[l]? */
+    *P = *luaH_getint(L, a, i);  /* P = a[i] */
+    if (sort_comp(L, f, P, luaH_getint(L, a, l)))  /* a[i]<a[l]? */
       swap(L, a, l, i);
-    else if (sort_comp(L, f, luaH_getint(L, a, u), S->stack+P)) /* a[u]<a[i]? */
+    else if (sort_comp(L, f, luaH_getint(L, a, u), P))  /* a[u]<a[i]? */
       swap(L, a, i, u);
     if (u-l == 2) break;  /* only 3 elements */
-    *(S->stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */
+    *P = *luaH_getint(L, a, i);  /* save pivot on stack (GC) */
     swap(L, a, i, u-1);  /* put median element as pivot (a[u-1]) */
     /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
     i = l; j = u-1;
     for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
       /* repeat i++ until a[i] >= P */
-      while (sort_comp(L, f, luaH_getint(L, a, ++i), S->stack+P))
+      while (sort_comp(L, f, luaH_getint(L, a, ++i), P))
         if (i>u) lua_error(L, "invalid order function for sorting");
       /* repeat j-- until a[j] <= P */
-      while (sort_comp(L, f, (S->stack+P), luaH_getint(L, a, --j)))
+      while (sort_comp(L, f, P, luaH_getint(L, a, --j)))
         if (j<l) lua_error(L, "invalid order function for sorting");
       if (j<i) break;
       swap(L, a, i, j);
@@ -588,7 +581,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
     }
     auxsort(L, a, j, i, f);  /* call recursively the smaller one */
   }  /* repeat the routine for the larger one */
-  S->top--;  /* remove pivot from stack */
+  L->top--;  /* remove pivot from stack */
 }
 
 static void luaB_sort (lua_State *L) {

+ 88 - 83
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.52 1999/11/22 13:12:07 roberto Exp roberto $
+** $Id: ldo.c,v 1.53 1999/11/25 18:58:51 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -28,39 +28,40 @@
 
 
 
-#ifndef STACK_LIMIT
-#define STACK_LIMIT     6000  /* arbitrary limit */
+#ifndef DEFAULT_STACK_SIZE
+#define DEFAULT_STACK_SIZE      1024
 #endif
 
+#define EXTRA_STACK	32	/* space to handle stack overflow errors */
 
-
-#define STACK_UNIT	128
-
-
-#ifdef DEBUG
-#undef STACK_UNIT
-#define STACK_UNIT	2
-#endif
+/*
+** typical numer of recursive calls that fit in the stack
+** (only for error messages)
+*/
+#define REC_DEEP	(DEFAULT_STACK_SIZE/20)
 
 
 void luaD_init (lua_State *L) {
-  L->stack.stack = luaM_newvector(L, STACK_UNIT, TObject);
-  L->stack.top = L->stack.stack;
-  L->stack.last = L->stack.stack+(STACK_UNIT-1);
+  L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject);
+  L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
+  L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
+  L->Cstack.num = 0;
 }
 
 
 void luaD_checkstack (lua_State *L, int n) {
-  struct Stack *S = &L->stack;
-  if (S->last-S->top <= n) {
-    StkId top = S->top-S->stack;
-    int stacksize = (S->last-S->stack)+STACK_UNIT+n;
-    luaM_reallocvector(L, S->stack, stacksize, TObject);
-    S->last = S->stack+(stacksize-1);
-    S->top = S->stack + top;
-    if (stacksize >= STACK_LIMIT) {  /* stack overflow? */
-      if (lua_stackedfunction(L, 100) == LUA_NOOBJECT)  /* 100 funcs on stack? */
-        lua_error(L, "Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */
+  if (L->stack_last-L->top <= n) {  /* stack overflow? */
+    if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-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 */
+        lua_error(L, "Lua2C - C2Lua overflow");
+      }
       else
         lua_error(L, "stack size overflow");
     }
@@ -68,54 +69,62 @@ 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);
+}
+
+
 /*
-** Adjust stack. Set top to the given value, pushing NILs if needed.
+** Adjust stack. Set top to base+extra, pushing NILs if needed.
+** (we cannot add base+extra unless we are sure it fits in the stack;
+**  otherwise the result of such operation on pointers is undefined)
 */
-void luaD_adjusttop (lua_State *L, StkId newtop) {
-  int diff = newtop-(L->stack.top-L->stack.stack);
+void luaD_adjusttop (lua_State *L, StkId base, int extra) {
+  int diff = extra-(L->top-base);
   if (diff <= 0)
-    L->stack.top += diff;
+    L->top = base+extra;
   else {
     luaD_checkstack(L, diff);
     while (diff--)
-      ttype(L->stack.top++) = LUA_T_NIL;
+      ttype(L->top++) = LUA_T_NIL;
   }
 }
 
 
 /*
-** Open a hole below "nelems" from the L->stack.top.
+** Open a hole inside the stack at `pos'
 */
-void luaD_openstack (lua_State *L, int nelems) {
-  luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems,
-             nelems*sizeof(TObject));
+void luaD_openstack (lua_State *L, StkId pos) {
+  luaO_memup(pos+1, pos, (L->top-pos)*sizeof(TObject));
   incr_top;
 }
 
 
 void luaD_lineHook (lua_State *L, int line) {
   struct C_Lua_Stack oldCLS = L->Cstack;
-  StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
+  StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
   L->Cstack.num = 0;
   (*L->linehook)(L, line);
-  L->stack.top = L->stack.stack+old_top;
+  L->top = old_top;
   L->Cstack = oldCLS;
 }
 
 
-void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn) {
+void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf,
+                    int isreturn) {
   struct C_Lua_Stack oldCLS = L->Cstack;
-  StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
+  StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
   L->Cstack.num = 0;
   if (isreturn)
     (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0);
   else {
-    TObject *f = L->stack.stack+base-1;
+    TObject *f = base-1;
     if (tf)
       (*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined);
     else (*L->callhook)(L, Ref(L, f), "(C)", -1);
   }
-  L->stack.top = L->stack.stack+old_top;
+  L->top = old_top;
   L->Cstack = oldCLS;
 }
 
@@ -126,43 +135,41 @@ void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn
 ** first argument. Returns an index to the first result from C.
 */
 static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
-  struct C_Lua_Stack *cls = &L->Cstack;
-  struct C_Lua_Stack oldCLS = *cls;
+  struct C_Lua_Stack oldCLS = L->Cstack;
   StkId firstResult;
-  int numarg = (L->stack.top-L->stack.stack) - base;
-  cls->num = numarg;
-  cls->lua2C = base;
-  cls->base = base+numarg;  /* == top-stack */
+  int numarg = L->top - base;
+  L->Cstack.num = numarg;
+  L->Cstack.lua2C = base;
+  L->Cstack.base = L->top;
   if (L->callhook)
     luaD_callHook(L, base, NULL, 0);
   (*f)(L);  /* do the actual call */
-  if (L->callhook)  /* func may have changed callhook */
+  if (L->callhook)  /* test again: `func' may have changed callhook */
     luaD_callHook(L, base, NULL, 1);
-  firstResult = cls->base;
-  *cls = oldCLS;
+  firstResult = L->Cstack.base;
+  L->Cstack = oldCLS;
   return firstResult;
 }
 
 
 static StkId callCclosure (lua_State *L, const struct Closure *cl,
                            lua_CFunction f, StkId base) {
-  TObject *pbase;
   int nup = cl->nelems;  /* number of upvalues */
   luaD_checkstack(L, nup);
-  pbase = L->stack.stack+base;  /* care: previous call may change this */
   /* open space for upvalues as extra arguments */
-  luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject));
+  luaO_memup(base+nup, base, (L->top-base)*sizeof(TObject));
   /* copy upvalues into stack */
-  memcpy(pbase, cl->consts+1, nup*sizeof(TObject));
-  L->stack.top += nup;
+  memcpy(base, cl->consts+1, nup*sizeof(TObject));
+  L->top += nup;
   return callC(L, f, base);
 }
 
 
 void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
-  luaD_openstack(L, nParams);
-  *(L->stack.top-nParams-1) = *f;
-  luaD_call(L, L->stack.top-nParams-1, nResults);
+  StkId base = L->top - nParams;
+  luaD_openstack(L, base);
+  *base = *f;
+  luaD_call(L, base, nResults);
 }
 
 
@@ -173,26 +180,24 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
 ** function position.
 ** The number of results is nResults, unless nResults=MULT_RET.
 */ 
-void luaD_call (lua_State *L, TObject *func, int nResults) {
-  struct Stack *S = &L->stack;  /* to optimize */
-  StkId base = func - S->stack + 1;  /* where is first argument */
+void luaD_call (lua_State *L, StkId func, int nResults) {
   StkId firstResult;
   switch (ttype(func)) {
     case LUA_T_CPROTO:
       ttype(func) = LUA_T_CMARK;
-      firstResult = callC(L, fvalue(func), base);
+      firstResult = callC(L, fvalue(func), func+1);
       break;
     case LUA_T_PROTO:
       ttype(func) = LUA_T_PMARK;
-      firstResult = luaV_execute(L, NULL, tfvalue(func), base);
+      firstResult = luaV_execute(L, NULL, tfvalue(func), func+1);
       break;
     case LUA_T_CLOSURE: {
       Closure *c = clvalue(func);
       TObject *proto = c->consts;
       ttype(func) = LUA_T_CLMARK;
       firstResult = (ttype(proto) == LUA_T_CPROTO) ?
-                       callCclosure(L, c, fvalue(proto), base) :
-                       luaV_execute(L, c, tfvalue(proto), base);
+                       callCclosure(L, c, fvalue(proto), func+1) :
+                       luaV_execute(L, c, tfvalue(proto), func+1);
       break;
     }
     default: { /* func is not a function */
@@ -200,19 +205,18 @@ void luaD_call (lua_State *L, TObject *func, int nResults) {
       const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
       if (ttype(im) == LUA_T_NIL)
         lua_error(L, "call expression not a function");
-      luaD_callTM(L, im, (S->top-S->stack)-(base-1), nResults);
+      luaD_callTM(L, im, L->top-func, nResults);
       return;
     }
   }
   /* adjust the number of results */
   if (nResults == MULT_RET)
-    nResults = (S->top-S->stack)-firstResult;
+    nResults = L->top - firstResult;
   else
-    luaD_adjusttop(L, firstResult+nResults);
-  /* move results to base-1 (to erase parameters and function) */
-  base--;
-  luaO_memdown(S->stack+base, S->stack+firstResult, nResults*sizeof(TObject));
-  S->top -= firstResult-base;
+    luaD_adjusttop(L, firstResult, nResults);
+  /* move results to func (to erase parameters and function) */
+  luaO_memdown(func, firstResult, nResults*sizeof(TObject));
+  L->top = func+nResults;
 }
 
 
@@ -220,10 +224,10 @@ static void message (lua_State *L, const char *s) {
   const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
   if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
       ttype(em) == LUA_T_CLOSURE) {
-    *L->stack.top = *em;
+    *L->top = *em;
     incr_top;
     lua_pushstring(L, s);
-    luaD_call(L, L->stack.top-2, 0);
+    luaD_call(L, L->top-2, 0);
   }
 }
 
@@ -253,15 +257,16 @@ int luaD_protectedrun (lua_State *L) {
   L->errorJmp = &myErrorJmp;
   if (setjmp(myErrorJmp.b) == 0) {
     StkId base = L->Cstack.base;
-    luaD_call(L, L->stack.stack+base, MULT_RET);
+    luaD_call(L, base, MULT_RET);
     L->Cstack.lua2C = base;  /* position of the new results */
-    L->Cstack.num = (L->stack.top-L->stack.stack) - base;
+    L->Cstack.num = L->top - base;
     L->Cstack.base = base + L->Cstack.num;  /* incorporate results on stack */
     status = 0;
   }
-  else {  /* an error occurred: restore L->Cstack and L->stack.top */
+  else {  /* an error occurred: restore the stack */
     L->Cstack = oldCLS;
-    L->stack.top = L->stack.stack+L->Cstack.base;
+    L->top = L->Cstack.base;
+    restore_stack_limit(L);
     status = 1;
   }
   L->errorJmp = oldErr;
@@ -283,18 +288,18 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
     tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
     status = 0;
   }
-  else {  /* an error occurred: restore L->Cstack and L->stack.top */
+  else {  /* an error occurred: restore L->Cstack and L->top */
     L->Cstack = oldCLS;
-    L->stack.top = L->stack.stack+L->Cstack.base;
+    L->top = L->Cstack.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->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO;
-  L->stack.stack[L->Cstack.base].value.tf = tf;
+  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);
   return 0;
 }
@@ -323,7 +328,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
 void luaD_gcIM (lua_State *L, const TObject *o) {
   const TObject *im = luaT_getimbyObj(L, o, IM_GC);
   if (ttype(im) != LUA_T_NIL) {
-    *L->stack.top = *o;
+    *L->top = *o;
     incr_top;
     luaD_callTM(L, im, 1, 0);
   }

+ 9 - 9
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.10 1999/11/22 13:12:07 roberto Exp roberto $
+** $Id: ldo.h,v 1.11 1999/11/25 18:58:51 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -20,22 +20,22 @@
 ** macro to increment stack top.
 ** There must be always an empty slot at the L->stack.top
 */
-#define incr_top { if (L->stack.top >= L->stack.last) luaD_checkstack(L, 1); \
-                   L->stack.top++; }
+#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
 
 
 /* macros to convert from lua_Object to (TObject *) and back */
 
-#define Address(L, lo)     ((lo)+L->stack.stack-1)
-#define Ref(L, st)         ((st)-L->stack.stack+1)
+#define Address(L, lo)     ((lo)+L->stack-1)
+#define Ref(L, st)         ((st)-L->stack+1)
 
 
 void luaD_init (lua_State *L);
-void luaD_adjusttop (lua_State *L, StkId newtop);
-void luaD_openstack (lua_State *L, int nelems);
+void luaD_adjusttop (lua_State *L, StkId base, int extra);
+void luaD_openstack (lua_State *L, StkId pos);
 void luaD_lineHook (lua_State *L, int line);
-void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn);
-void luaD_call (lua_State *L, TObject *func, int nResults);
+void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf,
+                    int isreturn);
+void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
 int luaD_protectedrun (lua_State *L);
 void luaD_gcIM (lua_State *L, const TObject *o);

+ 4 - 4
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.33 1999/11/23 13:58:02 roberto Exp roberto $
+** $Id: lgc.c,v 1.34 1999/11/26 18:59:20 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -77,9 +77,9 @@ static void travglobal (lua_State *L) {
 
 
 static void travstack (lua_State *L) {
-  StkId i;
-  for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
-    markobject(L, L->stack.stack+i);
+  int i;
+  for (i = (L->top-1)-L->stack; i>=0; i--)
+    markobject(L, L->stack+i);
 }
 
 

+ 4 - 4
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.43 1999/11/22 13:12:07 roberto Exp roberto $
+** $Id: lparser.c,v 1.44 1999/11/25 18:59:43 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -581,8 +581,8 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
   code_byte(ls, 0);  /* to be filled with maxstacksize */
   code_byte(ls, 0);  /* to be filled with arg information */
   /* push function (to avoid GC) */
-  tfvalue(L->stack.top) = f;
-  ttype(L->stack.top) = LUA_T_PROTO;
+  tfvalue(L->top) = f;
+  ttype(L->top) = LUA_T_PROTO;
   incr_top;
 }
 
@@ -599,7 +599,7 @@ static void close_func (LexState *ls) {
     luaM_reallocvector(ls->L, f->locvars, fs->nvars, LocVar);
   }
   ls->fs = fs->prev;
-  ls->L->stack.top--;  /* pop function */
+  ls->L->top--;  /* pop function */
 }
 
 

+ 2 - 5
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.17 1999/11/22 13:12:07 roberto Exp roberto $
+** $Id: lstate.c,v 1.18 1999/11/29 19:12:07 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -23,9 +23,6 @@ lua_State *lua_state = NULL;
 
 lua_State *lua_newstate (void) {
   lua_State *L = luaM_new(NULL, lua_State);
-  L->Cstack.base = 0;
-  L->Cstack.lua2C = 0;
-  L->Cstack.num = 0;
   L->errorJmp = NULL;
   L->Mbuffer = NULL;
   L->Mbuffbase = 0;
@@ -63,7 +60,7 @@ void lua_close (lua_State *L) {
   LUA_ASSERT(L, L->rootglobal == NULL, "list should be empty");
   LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
   luaS_freeall(L);
-  luaM_free(L, L->stack.stack);
+  luaM_free(L, L->stack);
   luaM_free(L, L->IMtable);
   luaM_free(L, L->refArray);
   luaM_free(L, L->Mbuffer);

+ 14 - 13
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 1.22 1999/11/10 15:39:35 roberto Exp roberto $
+** $Id: lstate.h,v 1.23 1999/11/22 13:12:07 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -15,7 +15,7 @@
 
 
 
-typedef int StkId;  /* index to stack elements */
+typedef TObject *StkId;  /* index to stack elements */
 
 
 /*
@@ -27,17 +27,16 @@ struct lua_longjmp {
 };
 
 
-struct Stack {
-  TObject *top;
-  TObject *stack;
-  TObject *last;
-};
-
+/*
+** stack layout for C point of view:
+** [lua2C, lua2C+num) - `array' lua2C
+** [lua2C+num, base)  - space for extra lua_Objects
+** [base, L->top)     - `stack' C2Lua
+*/
 struct C_Lua_Stack {
-  StkId base;  /* when Lua calls C or C calls Lua, points to */
-               /* the first slot after the last parameter. */
-  StkId lua2C; /* points to first element of "array" lua2C */
-  int num;     /* size of "array" lua2C */
+  StkId base;
+  StkId lua2C;
+  int num;
 };
 
 
@@ -51,7 +50,9 @@ typedef struct stringtable {
 
 struct lua_State {
   /* thread-specific state */
-  struct Stack stack;  /* Lua stack */
+  StkId top;  /* first free slot in the stack */
+  StkId stack;  /* stack base */
+  StkId stack_last;  /* last free slot in the stack */
   struct C_Lua_Stack Cstack;  /* C2lua struct */
   struct lua_longjmp *errorJmp;  /* current error recover point */
   char *Mbuffer;  /* global buffer */

+ 178 - 173
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.67 1999/11/25 18:59:43 roberto Exp roberto $
+** $Id: lvm.c,v 1.68 1999/11/29 18:27:49 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -83,13 +83,12 @@ void luaV_setn (lua_State *L, Hash *t, int val) {
 
 void luaV_closure (lua_State *L, int nelems) {
   if (nelems > 0) {
-    struct Stack *S = &L->stack;
     Closure *c = luaF_newclosure(L, nelems);
-    c->consts[0] = *(S->top-1);
-    memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
-    S->top -= nelems;
-    ttype(S->top-1) = LUA_T_CLOSURE;
-    (S->top-1)->value.cl = c;
+    c->consts[0] = *(L->top-1);
+    L->top -= nelems;
+    memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject));
+    ttype(L->top-1) = LUA_T_CLOSURE;
+    (L->top-1)->value.cl = c;
   }
 }
 
@@ -99,7 +98,7 @@ void luaV_closure (lua_State *L, int nelems) {
 ** Receives the table at top-2 and the index at top-1.
 */
 void luaV_gettable (lua_State *L) {
-  TObject *table = L->stack.top-2;
+  TObject *table = L->top-2;
   const TObject *im;
   if (ttype(table) != LUA_T_ARRAY) {  /* not a table, get gettable method */
     im = luaT_getimbyObj(L, table, IM_GETTABLE);
@@ -117,7 +116,7 @@ void luaV_gettable (lua_State *L) {
         luaD_callTM(L, im, 2, 1);  /* calls it */
       }
       else {
-        L->stack.top--;
+        L->top--;
         *table = *h;  /* "push" result into table position */
       }
       return;
@@ -132,8 +131,7 @@ void luaV_gettable (lua_State *L) {
 /*
 ** Receives table at *t, index at *(t+1) and value at top.
 */
-void luaV_settable (lua_State *L, const TObject *t) {
-  struct Stack *S = &L->stack;
+void luaV_settable (lua_State *L, StkId t) {
   const TObject *im;
   if (ttype(t) != LUA_T_ARRAY) {  /* not a table, get "settable" method */
     im = luaT_getimbyObj(L, t, IM_SETTABLE);
@@ -143,29 +141,28 @@ void luaV_settable (lua_State *L, const TObject *t) {
   else {  /* object is a table... */
     im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
     if (ttype(im) == LUA_T_NIL) {  /* and does not have a "settable" method */
-      luaH_set(L, avalue(t), t+1, S->top-1);
-      S->top--;  /* pop value */
+      luaH_set(L, avalue(t), t+1, L->top-1);
+      L->top--;  /* pop value */
       return;
     }
     /* else it has a "settable" method, go through to next command */
   }
   /* object is not a table, or it has a "settable" method */
   /* prepare arguments and call the tag method */
-  *(S->top+1) = *(L->stack.top-1);
-  *(S->top) = *(t+1);
-  *(S->top-1) = *t;
-  S->top += 2;  /* WARNING: caller must assure stack space */
+  *(L->top+1) = *(L->top-1);
+  *(L->top) = *(t+1);
+  *(L->top-1) = *t;
+  L->top += 2;  /* WARNING: caller must assure stack space */
   luaD_callTM(L, im, 3, 0);
 }
 
 
-void luaV_rawsettable (lua_State *L, const TObject *t) {
+void luaV_rawsettable (lua_State *L, StkId t) {
   if (ttype(t) != LUA_T_ARRAY)
     lua_error(L, "indexed expression not a table");
   else {
-    struct Stack *S = &L->stack;
-    luaH_set(L, avalue(t), t+1, S->top-1);
-    S->top -= 3;
+    luaH_set(L, avalue(t), t+1, L->top-1);
+    L->top -= 3;
   }
 }
 
@@ -178,17 +175,16 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv) {
     case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
       TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
       if (ttype(im) != LUA_T_NIL) {  /* is there a tag method? */
-        struct Stack *S = &L->stack;
-        ttype(S->top) = LUA_T_STRING;
-        tsvalue(S->top) = gv->name;  /* global name */
-        S->top++;
-        *S->top++ = *value;
+        ttype(L->top) = LUA_T_STRING;
+        tsvalue(L->top) = gv->name;  /* global name */
+        L->top++;
+        *L->top++ = *value;
         luaD_callTM(L, im, 2, 1);
         return;
       }
       /* else no tag method: go through to default behavior */
     }
-    default: *L->stack.top++ = *value;  /* default behavior */
+    default: *L->top++ = *value;  /* default behavior */
   }
 }
 
@@ -197,26 +193,26 @@ void luaV_setglobal (lua_State *L, GlobalVar *gv) {
   const TObject *oldvalue = &gv->value;
   const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
   if (ttype(im) == LUA_T_NIL)  /* is there a tag method? */
-    gv->value = *(--L->stack.top);
+    gv->value = *(--L->top);
   else {
     /* WARNING: caller must assure stack space */
-    struct Stack *S = &L->stack;
     TObject newvalue;
-    newvalue = *(S->top-1);
-    ttype(S->top-1) = LUA_T_STRING;
-    tsvalue(S->top-1) = gv->name;
-    *S->top++ = *oldvalue;
-    *S->top++ = newvalue;
+    newvalue = *(L->top-1);
+    ttype(L->top-1) = LUA_T_STRING;
+    tsvalue(L->top-1) = gv->name;
+    *L->top++ = *oldvalue;
+    *L->top++ = newvalue;
     luaD_callTM(L, im, 3, 0);
   }
 }
 
 
-static void call_binTM (lua_State *L, IMS event, const char *msg) {
+static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) {
   /* try first operand */
-  const TObject *im = luaT_getimbyObj(L, L->stack.top-2, event);
+  const TObject *im = luaT_getimbyObj(L, top-2, event);
+  L->top = top;
   if (ttype(im) == LUA_T_NIL) {
-    im = luaT_getimbyObj(L, L->stack.top-1, event);  /* try second operand */
+    im = luaT_getimbyObj(L, top-1, event);  /* try second operand */
     if (ttype(im) == LUA_T_NIL) {
       im = luaT_getim(L, 0, event);  /* try a 'global' i.m. */
       if (ttype(im) == LUA_T_NIL)
@@ -228,8 +224,8 @@ static void call_binTM (lua_State *L, IMS event, const char *msg) {
 }
 
 
-static void call_arith (lua_State *L, IMS event) {
-  call_binTM(L, event, "unexpected type in arithmetic operation");
+static void call_arith (lua_State *L, StkId top, IMS event) {
+  call_binTM(L, top, event, "unexpected type in arithmetic operation");
 }
 
 
@@ -249,11 +245,10 @@ static int luaV_strcomp (const char *l, long ll, const char *r, long lr) {
   }
 }
 
-void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
-                      lua_Type ttype_great, IMS op) {
-  struct Stack *S = &L->stack;
-  const TObject *l = S->top-2;
-  const TObject *r = S->top-1;
+void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
+                      lua_Type ttype_equal, lua_Type ttype_great, IMS op) {
+  const TObject *l = top-2;
+  const TObject *r = top-1;
   real result;
   if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
     result = nvalue(l)-nvalue(r);
@@ -261,39 +256,41 @@ void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
     result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
                           svalue(r), tsvalue(r)->u.s.len);
   else {
-    call_binTM(L, op, "unexpected type in comparison");
+    call_binTM(L, top, op, "unexpected type in comparison");
     return;
   }
-  S->top--;
-  nvalue(S->top-1) = 1;
-  ttype(S->top-1) = (result < 0) ? ttype_less :
+  nvalue(top-2) = 1;
+  ttype(top-2) = (result < 0) ? ttype_less :
                                 (result == 0) ? ttype_equal : ttype_great;
 }
 
 
-void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) {
-  TObject *firstelem = L->stack.stack+firstel;
+void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
   int i;
   Hash *htab;
-  if (nvararg < 0) nvararg = 0;
-  htab = avalue(tab) = luaH_new(L, nvararg+1);  /* +1 for field 'n' */
+  htab = avalue(tab) = luaH_new(L, nvararg+1);  /* +1 for field `n' */
   ttype(tab) = LUA_T_ARRAY;
   for (i=0; i<nvararg; i++)
     luaH_setint(L, htab, i+1, firstelem+i);
-  luaV_setn(L, htab, nvararg);  /* store counter in field "n" */
+  luaV_setn(L, htab, nvararg);  /* store counter in field `n' */
 }
 
 
-static void adjust_varargs (lua_State *L, StkId first_extra_arg) {
+static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
   TObject arg;
-  luaV_pack(L, first_extra_arg,
-       (L->stack.top-L->stack.stack)-first_extra_arg, &arg);
-  luaD_adjusttop(L, first_extra_arg);
-  *L->stack.top++ = arg;
+  int nvararg = (L->top-base) - nfixargs;
+  if (nvararg < 0) {
+    luaV_pack(L, base, 0, &arg);
+    luaD_adjusttop(L, base, nfixargs);
+  }
+  else {
+    luaV_pack(L, base+nfixargs, nvararg, &arg);
+    L->top = base+nfixargs;
+  }
+  *L->top++ = arg;
 }
 
 
-
 /*
 ** Execute the given opcode, until a RET. Parameters are between
 ** [stack+base,top). Returns n such that the the results are between
@@ -301,25 +298,26 @@ static void adjust_varargs (lua_State *L, StkId first_extra_arg) {
 */
 StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
                     StkId base) {
-  struct Stack *S = &L->stack;  /* to optimize */
+  register StkId top;  /* keep top local, for performance */
   register const Byte *pc = tf->code;
   const TObject *consts = tf->consts;
   if (L->callhook)
     luaD_callHook(L, base, tf, 0);
   luaD_checkstack(L, (*pc++)+EXTRA_STACK);
   if (*pc < ZEROVARARG)
-    luaD_adjusttop(L, base+*(pc++));
+    luaD_adjusttop(L, base, *(pc++));
   else {  /* varargs */
+    adjust_varargs(L, base, (*pc++)-ZEROVARARG);
     luaC_checkGC(L);
-    adjust_varargs(L, base+(*pc++)-ZEROVARARG);
   }
+  top = L->top;
   for (;;) {
     register int aux = 0;
     switchentry:
     switch ((OpCode)*pc++) {
 
       case ENDCODE:
-        S->top = S->stack + base;
+        top = base;
         goto ret;
         
       case RETCODE:
@@ -327,238 +325,240 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
         goto ret;
 
       case CALL: aux = *pc++;
-        luaD_call(L, (S->stack+base) + *pc++, aux);
+        L->top = top;
+        luaD_call(L, base+(*pc++), aux);
+        top = L->top;
         break;
 
       case TAILCALL: aux = *pc++;
-        luaD_call(L, (S->stack+base) + *pc++, MULT_RET);
+        L->top = top;
+        luaD_call(L, base+(*pc++), MULT_RET);
+        top = L->top;
         base += aux;
         goto ret;
 
       case PUSHNIL: aux = *pc++;
         do {
-          ttype(S->top++) = LUA_T_NIL;
+          ttype(top++) = LUA_T_NIL;
         } while (aux--);
         break;
 
       case POP: aux = *pc++;
-        S->top -= aux;
+        top -= aux;
         break;
 
       case PUSHNUMBERW: aux += highbyte(L, *pc++);
       case PUSHNUMBER:  aux += *pc++;
-        ttype(S->top) = LUA_T_NUMBER;
-        nvalue(S->top) = aux;
-        S->top++;
+        ttype(top) = LUA_T_NUMBER;
+        nvalue(top) = aux;
+        top++;
         break;
 
       case PUSHNUMBERNEGW: aux += highbyte(L, *pc++);
       case PUSHNUMBERNEG:  aux += *pc++;
-        ttype(S->top) = LUA_T_NUMBER;
-        nvalue(S->top) = -aux;
-        S->top++;
+        ttype(top) = LUA_T_NUMBER;
+        nvalue(top) = -aux;
+        top++;
         break;
 
       case PUSHCONSTANTW: aux += highbyte(L, *pc++);
       case PUSHCONSTANT:  aux += *pc++;
-        *S->top++ = consts[aux];
+        *top++ = consts[aux];
         break;
 
       case PUSHUPVALUE: aux = *pc++;
-        *S->top++ = cl->consts[aux+1];
+        *top++ = cl->consts[aux+1];
         break;
 
       case PUSHLOCAL: aux = *pc++;
-        *S->top++ = *((S->stack+base) + aux);
+        *top++ = *(base+aux);
         break;
 
       case GETGLOBALW: aux += highbyte(L, *pc++);
       case GETGLOBAL:  aux += *pc++;
+        L->top = top;
         luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv);
+        top++;
         break;
 
       case GETTABLE:
+        L->top = top;
         luaV_gettable(L);
+        top--;
         break;
 
       case GETDOTTEDW: aux += highbyte(L, *pc++);
       case GETDOTTED:  aux += *pc++;
-        *S->top++ = consts[aux];
+        *top++ = consts[aux];
+        L->top = top;
         luaV_gettable(L);
+        top--;
         break;
 
       case PUSHSELFW: aux += highbyte(L, *pc++);
       case PUSHSELF:  aux += *pc++; {
         TObject receiver;
-        receiver = *(S->top-1);
-        *S->top++ = consts[aux];
+        receiver = *(top-1);
+        *top++ = consts[aux];
+        L->top = top;
         luaV_gettable(L);
-        *S->top++ = receiver;
+        *(top-1) = receiver;
         break;
       }
 
       case CREATEARRAYW: aux += highbyte(L, *pc++);
       case CREATEARRAY:  aux += *pc++;
+        L->top = top;
         luaC_checkGC(L);
-        avalue(S->top) = luaH_new(L, aux);
-        ttype(S->top) = LUA_T_ARRAY;
-        S->top++;
+        avalue(top) = luaH_new(L, aux);
+        ttype(top) = LUA_T_ARRAY;
+        top++;
         break;
 
       case SETLOCAL: aux = *pc++;
-        *((S->stack+base) + aux) = *(--S->top);
+        *(base+aux) = *(--top);
         break;
 
       case SETGLOBALW: aux += highbyte(L, *pc++);
       case SETGLOBAL:  aux += *pc++;
+        L->top = top;
         luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv);
+        top--;
         break;
 
       case SETTABLEPOP:
-        luaV_settable(L, S->top-3);
-        S->top -= 2;  /* pop table and index */
+        L->top = top;
+        luaV_settable(L, top-3);
+        top -= 3;  /* pop table, index, and value */
         break;
 
       case SETTABLE:
-        luaV_settable(L, S->top-3-(*pc++));
+        L->top = top;
+        luaV_settable(L, top-3-(*pc++));
+        top--;  /* pop value */
         break;
 
       case SETLISTW: aux += highbyte(L, *pc++);
       case SETLIST:  aux += *pc++; {
         int n = *(pc++);
-        Hash *arr = avalue(S->top-n-1);
+        Hash *arr = avalue(top-n-1);
         aux *= LFIELDS_PER_FLUSH;
         for (; n; n--)
-          luaH_setint(L, arr, n+aux, --S->top);
+          luaH_setint(L, arr, n+aux, --top);
         break;
       }
 
       case SETMAP:  aux = *pc++; {
-        Hash *arr = avalue(S->top-(2*aux)-3);
+        Hash *arr = avalue(top-(2*aux)-3);
         do {
-          luaH_set(L, arr, S->top-2, S->top-1);
-          S->top-=2;
+          luaH_set(L, arr, top-2, top-1);
+          top-=2;
         } while (aux--);
         break;
       }
 
       case NEQOP: aux = 1;
       case EQOP: {
-        int res = luaO_equalObj(S->top-2, S->top-1);
+        int res = luaO_equalObj(top-2, top-1);
         if (aux) res = !res;
-        S->top--;
-        ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
-        nvalue(S->top-1) = 1;
+        top--;
+        ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
+        nvalue(top-1) = 1;
         break;
       }
 
        case LTOP:
-         luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
+         luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
+         top--;
          break;
 
       case LEOP:
-        luaV_comparison(L, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
+        luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
+        top--;
         break;
 
       case GTOP:
-        luaV_comparison(L, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
+        luaV_comparison(L, top, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
+        top--;
         break;
 
       case GEOP:
-        luaV_comparison(L, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
+        luaV_comparison(L, top, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
+        top--;
         break;
 
-      case ADDOP: {
-        TObject *l = S->top-2;
-        TObject *r = S->top-1;
-        if (tonumber(r) || tonumber(l))
-          call_arith(L, IM_ADD);
-        else {
-          nvalue(l) += nvalue(r);
-          --S->top;
-        }
+      case ADDOP:
+        if (tonumber(top-1) || tonumber(top-2))
+          call_arith(L, top, IM_ADD);
+        else
+          nvalue(top-2) += nvalue(top-1);
+        top--;
         break;
-      }
 
-      case SUBOP: {
-        TObject *l = S->top-2;
-        TObject *r = S->top-1;
-        if (tonumber(r) || tonumber(l))
-          call_arith(L, IM_SUB);
-        else {
-          nvalue(l) -= nvalue(r);
-          --S->top;
-        }
+      case SUBOP:
+        if (tonumber(top-1) || tonumber(top-2))
+          call_arith(L, top, IM_SUB);
+        else
+          nvalue(top-2) -= nvalue(top-1);
+        top--;
         break;
-      }
 
-      case MULTOP: {
-        TObject *l = S->top-2;
-        TObject *r = S->top-1;
-        if (tonumber(r) || tonumber(l))
-          call_arith(L, IM_MUL);
-        else {
-          nvalue(l) *= nvalue(r);
-          --S->top;
-        }
+      case MULTOP:
+        if (tonumber(top-1) || tonumber(top-2))
+          call_arith(L, top, IM_MUL);
+        else
+          nvalue(top-2) *= nvalue(top-1);
+        top--;
         break;
-      }
 
-      case DIVOP: {
-        TObject *l = S->top-2;
-        TObject *r = S->top-1;
-        if (tonumber(r) || tonumber(l))
-          call_arith(L, IM_DIV);
-        else {
-          nvalue(l) /= nvalue(r);
-          --S->top;
-        }
+      case DIVOP:
+        if (tonumber(top-1) || tonumber(top-2))
+          call_arith(L, top, IM_DIV);
+        else
+          nvalue(top-2) /= nvalue(top-1);
+        top--;
         break;
-      }
 
       case POWOP:
-        call_binTM(L, IM_POW, "undefined operation");
+        call_binTM(L, top, IM_POW, "undefined operation");
+        top--;
         break;
 
-      case CONCOP: {
-        TObject *l = S->top-2;
-        TObject *r = S->top-1;
-        if (tostring(L, l) || tostring(L, r))
-          call_binTM(L, IM_CONCAT, "unexpected type for concatenation");
-        else {
-          tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r));
-          --S->top;
-        }
+      case CONCOP:
+        if (tostring(L, top-2) || tostring(L, top-1))
+          call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
+        else
+          tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1));
+        L->top = top;
         luaC_checkGC(L);
+        top--;
         break;
-      }
 
       case MINUSOP:
-        if (tonumber(S->top-1)) {
-          ttype(S->top) = LUA_T_NIL;
-          S->top++;
-          call_arith(L, IM_UNM);
+        if (tonumber(top-1)) {
+          ttype(top) = LUA_T_NIL;
+          call_arith(L, top+1, IM_UNM);
         }
         else
-          nvalue(S->top-1) = - nvalue(S->top-1);
+          nvalue(top-1) = - nvalue(top-1);
         break;
 
       case NOTOP:
-        ttype(S->top-1) =
-           (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
-        nvalue(S->top-1) = 1;
+        ttype(top-1) =
+           (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
+        nvalue(top-1) = 1;
         break;
 
       case ONTJMPW: aux += highbyte(L, *pc++);
       case ONTJMP:  aux += *pc++;
-        if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
-        else S->top--;
+        if (ttype(top-1) != LUA_T_NIL) pc += aux;
+        else top--;
         break;
 
       case ONFJMPW: aux += highbyte(L, *pc++);
       case ONFJMP:  aux += *pc++;
-        if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
-        else S->top--;
+        if (ttype(top-1) == LUA_T_NIL) pc += aux;
+        else top--;
         break;
 
       case JMPW: aux += highbyte(L, *pc++);
@@ -568,35 +568,40 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
 
       case IFFJMPW: aux += highbyte(L, *pc++);
       case IFFJMP:  aux += *pc++;
-        if (ttype(--S->top) == LUA_T_NIL) pc += aux;
+        if (ttype(--top) == LUA_T_NIL) pc += aux;
         break;
 
       case IFTUPJMPW: aux += highbyte(L, *pc++);
       case IFTUPJMP:  aux += *pc++;
-        if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
+        if (ttype(--top) != LUA_T_NIL) pc -= aux;
         break;
 
       case IFFUPJMPW: aux += highbyte(L, *pc++);
       case IFFUPJMP:  aux += *pc++;
-        if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
+        if (ttype(--top) == LUA_T_NIL) pc -= aux;
         break;
 
       case CLOSUREW: aux += highbyte(L, *pc++);
       case CLOSURE:  aux += *pc++;
-        *S->top++ = consts[aux];
-        luaV_closure(L, *pc++);
+        *top++ = consts[aux];
+        L->top = top;
+        aux = *pc++;
+        luaV_closure(L, aux);
         luaC_checkGC(L);
+        top -= aux;
         break;
 
       case SETLINEW: aux += highbyte(L, *pc++);
       case SETLINE:  aux += *pc++;
-        if ((S->stack+base-1)->ttype != LUA_T_LINE) {
+        L->top = top;
+        if ((base-1)->ttype != LUA_T_LINE) {
           /* open space for LINE value */
-          luaD_openstack(L, (S->top-S->stack)-base);
+          luaD_openstack(L, base);
+          base->ttype = LUA_T_LINE;
           base++;
-          (S->stack+base-1)->ttype = LUA_T_LINE;
+          top++;
         }
-        (S->stack+base-1)->value.i = aux;
+        (base-1)->value.i = aux;
         if (L->linehook)
           luaD_lineHook(L, aux);
         break;
@@ -608,8 +613,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
 
     }
   } ret:
+  L->top = top;
   if (L->callhook)
     luaD_callHook(L, 0, NULL, 1);
   return base;
 }
-

+ 5 - 5
lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 1.11 1999/11/04 17:22:26 roberto Exp roberto $
+** $Id: lvm.h,v 1.12 1999/11/22 13:12:07 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -22,13 +22,13 @@ int luaV_tonumber (TObject *obj);
 int luaV_tostring (lua_State *L, TObject *obj);
 void luaV_setn (lua_State *L, Hash *t, int val);
 void luaV_gettable (lua_State *L);
-void luaV_settable (lua_State *L, const TObject *t);
-void luaV_rawsettable (lua_State *L, const TObject *t);
+void luaV_settable (lua_State *L, StkId t);
+void luaV_rawsettable (lua_State *L, StkId t);
 void luaV_getglobal (lua_State *L, GlobalVar *gv);
 void luaV_setglobal (lua_State *L, GlobalVar *gv);
 StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base);
 void luaV_closure (lua_State *L, int nelems);
-void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
-                      lua_Type ttype_great, IMS op);
+void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
+                      lua_Type ttype_equal, lua_Type ttype_great, IMS op);
 
 #endif