فهرست منبع

fixed stack; first version.

Roberto Ierusalimschy 26 سال پیش
والد
کامیت
fe237ad808
10فایلهای تغییر یافته به همراه400 افزوده شده و 402 حذف شده
  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