Browse Source

better way to link callinfo's and stack

Roberto Ierusalimschy 24 years ago
parent
commit
6048c4f74d
11 changed files with 138 additions and 179 deletions
  1. 11 11
      lapi.c
  2. 2 2
      ldblib.c
  3. 75 99
      ldebug.c
  4. 20 27
      ldo.c
  5. 2 2
      ldo.h
  6. 3 6
      lgc.c
  7. 7 15
      lobject.h
  8. 3 1
      lstate.c
  9. 5 6
      lstate.h
  10. 2 2
      luadebug.h
  11. 8 8
      lvm.c

+ 11 - 11
lapi.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lapi.c,v 1.134 2001/02/23 17:28:12 roberto Exp roberto $
+** $Id: lapi.c,v 1.135 2001/03/02 17:27:50 roberto Exp roberto $
 ** Lua API
 ** Lua API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -31,7 +31,7 @@ const l_char lua_ident[] = l_s("$Lua: ") LUA_VERSION l_s(" ")
 #define api_check(L, o)		/* nothing */
 #define api_check(L, o)		/* nothing */
 #endif
 #endif
 
 
-#define api_checknelems(L, n)	api_check(L, (n) <= (L->top - L->Cbase))
+#define api_checknelems(L, n)	api_check(L, (n) <= (L->top - L->ci->base))
 
 
 #define api_incr_top(L)	incr_top
 #define api_incr_top(L)	incr_top
 
 
@@ -39,11 +39,11 @@ const l_char lua_ident[] = l_s("$Lua: ") LUA_VERSION l_s(" ")
 
 
 TObject *luaA_index (lua_State *L, int index) {
 TObject *luaA_index (lua_State *L, int index) {
   if (index > 0) {
   if (index > 0) {
-    api_check(L, index <= L->top - L->Cbase);
-    return L->Cbase+index-1;
+    api_check(L, index <= L->top - L->ci->base);
+    return L->ci->base+index-1;
   }
   }
   else {
   else {
-    api_check(L, index != 0 && -index <= L->top - L->Cbase);
+    api_check(L, index != 0 && -index <= L->top - L->ci->base);
     return L->top+index;
     return L->top+index;
   }
   }
 }
 }
@@ -51,13 +51,13 @@ TObject *luaA_index (lua_State *L, int index) {
 
 
 static TObject *luaA_indexAcceptable (lua_State *L, int index) {
 static TObject *luaA_indexAcceptable (lua_State *L, int index) {
   if (index > 0) {
   if (index > 0) {
-    TObject *o = L->Cbase+(index-1);
-    api_check(L, index <= L->stack_last - L->Cbase);
+    TObject *o = L->ci->base+(index-1);
+    api_check(L, index <= L->stack_last - L->ci->base);
     if (o >= L->top) return NULL;
     if (o >= L->top) return NULL;
     else return o;
     else return o;
   }
   }
   else {
   else {
-    api_check(L, index != 0 && -index <= L->top - L->Cbase);
+    api_check(L, index != 0 && -index <= L->top - L->ci->base);
     return L->top+index;
     return L->top+index;
   }
   }
 }
 }
@@ -86,7 +86,7 @@ LUA_API int lua_stackspace (lua_State *L) {
 LUA_API int lua_gettop (lua_State *L) {
 LUA_API int lua_gettop (lua_State *L) {
   int i;
   int i;
   lua_lock(L);
   lua_lock(L);
-  i = (L->top - L->Cbase);
+  i = (L->top - L->ci->base);
   lua_unlock(L);
   lua_unlock(L);
   return i;
   return i;
 }
 }
@@ -95,9 +95,9 @@ LUA_API int lua_gettop (lua_State *L) {
 LUA_API void lua_settop (lua_State *L, int index) {
 LUA_API void lua_settop (lua_State *L, int index) {
   lua_lock(L);
   lua_lock(L);
   if (index >= 0)
   if (index >= 0)
-    luaD_adjusttop(L, L->Cbase, index);
+    luaD_adjusttop(L, L->ci->base, index);
   else {
   else {
-    api_check(L, -(index+1) <= (L->top - L->Cbase));
+    api_check(L, -(index+1) <= (L->top - L->ci->base));
     L->top = L->top+index+1;  /* index is negative */
     L->top = L->top+index+1;  /* index is negative */
   }
   }
   lua_unlock(L);
   lua_unlock(L);

+ 2 - 2
ldblib.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldblib.c,v 1.33 2001/02/23 17:17:25 roberto Exp roberto $
+** $Id: ldblib.c,v 1.34 2001/03/06 20:09:38 roberto Exp roberto $
 ** Interface from Lua to its debug API
 ** Interface from Lua to its debug API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -121,7 +121,7 @@ static void hookf (lua_State *L, void *key) {
   lua_pushuserdata(L, key);
   lua_pushuserdata(L, key);
   lua_gettable(L, -2);
   lua_gettable(L, -2);
   if (lua_isfunction(L, -1)) {
   if (lua_isfunction(L, -1)) {
-    lua_pushvalue(L, 1);
+    lua_pushvalue(L, -3);  /* original argument (below table and function) */
     lua_rawcall(L, 1, 0);
     lua_rawcall(L, 1, 0);
   }
   }
   else
   else

+ 75 - 99
ldebug.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldebug.c,v 1.72 2001/03/06 14:46:54 roberto Exp roberto $
+** $Id: ldebug.c,v 1.73 2001/03/07 13:22:55 roberto Exp roberto $
 ** Debug Interface
 ** Debug Interface
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -24,19 +24,14 @@
 
 
 
 
 
 
-static const l_char *getfuncname (lua_State *L, StkId f, const l_char **name);
+static const l_char *getfuncname (lua_State *L, CallInfo *ci,
+                                  const l_char **name);
 
 
 
 
-static void setnormalized (TObject *d, const TObject *s) {
-  if (ttype(s) == LUA_TMARK) {
-    setclvalue(d, infovalue(s)->func);
-  }
-  else setobj(d, s);
-}
-
 
 
-static int isLmark (StkId o) {
-  return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC);
+static int isLmark (CallInfo *ci) {
+  lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION);
+  return (ci && ci->prev && !ci_func(ci)->isC);
 }
 }
 
 
 
 
@@ -60,27 +55,25 @@ LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
 }
 }
 
 
 
 
-static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
-  int i;
-  for (i = (top-1) - L->stack; i>=0; i--) {
-    if (is_T_MARK(&L->stack[i])) {
-      if (level == 0)
-        return L->stack+i;
-      level--;
-    }
-  }
-  return NULL;
+static CallInfo *ci_stack (lua_State *L, StkId obj) {
+  CallInfo *ci = L->ci;
+  while (ci->base > obj) ci = ci->prev;
+  return (ci != &L->basefunc) ? ci : NULL;
 }
 }
 
 
 
 
 LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
 LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
-  StkId f;
+  CallInfo *ci;
   int status;
   int status;
   lua_lock(L);
   lua_lock(L);
-  f = aux_stackedfunction(L, level, L->top);
-  if (f == NULL) status = 0;  /* there is no such level */
+  ci = L->ci;
+  while (level-- && ci != &L->basefunc) {
+    lua_assert(ci->base > ci->prev->base);
+    ci = ci->prev;
+  }
+  if (ci == &L->basefunc) status = 0;  /* there is no such level */
   else {
   else {
-    ar->_func = f;
+    ar->_ci = ci;
     status = 1;
     status = 1;
   }
   }
   lua_unlock(L);
   lua_unlock(L);
@@ -88,18 +81,6 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
 }
 }
 
 
 
 
-static int nups (StkId f) {
-  switch (ttype(f)) {
-    case LUA_TFUNCTION:
-      return clvalue(f)->nupvalues;
-    case LUA_TMARK:
-      return infovalue(f)->func->nupvalues;
-    default:
-      return 0;
-  }
-}
-
-
 int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
 int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
   int refi;
   int refi;
   if (lineinfo == NULL || pc == -1)
   if (lineinfo == NULL || pc == -1)
@@ -131,45 +112,43 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
 }
 }
 
 
 
 
-static int currentpc (StkId f) {
-  CallInfo *ci = infovalue(f);
-  lua_assert(isLmark(f));
+static int currentpc (CallInfo *ci) {
+  lua_assert(isLmark(ci));
   if (ci->pc)
   if (ci->pc)
-    return (*ci->pc - ci->func->f.l->code) - 1;
+    return (*ci->pc - ci_func(ci)->f.l->code) - 1;
   else
   else
     return -1;  /* function is not active */
     return -1;  /* function is not active */
 }
 }
 
 
 
 
-static int currentline (StkId f) {
-  if (!isLmark(f))
+static int currentline (CallInfo *ci) {
+  if (!isLmark(ci))
     return -1;  /* only active lua functions have current-line information */
     return -1;  /* only active lua functions have current-line information */
   else {
   else {
-    CallInfo *ci = infovalue(f);
-    int *lineinfo = ci->func->f.l->lineinfo;
-    return luaG_getline(lineinfo, currentpc(f), 1, NULL);
+    int *lineinfo = ci_func(ci)->f.l->lineinfo;
+    return luaG_getline(lineinfo, currentpc(ci), 1, NULL);
   }
   }
 }
 }
 
 
 
 
 
 
-static Proto *getluaproto (StkId f) {
-  return (isLmark(f) ?  infovalue(f)->func->f.l : NULL);
+static Proto *getluaproto (CallInfo *ci) {
+  return (isLmark(ci) ? ci_func(ci)->f.l : NULL);
 }
 }
 
 
 
 
 LUA_API const l_char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
 LUA_API const l_char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
   const l_char *name;
   const l_char *name;
-  StkId f;
+  CallInfo *ci;
   Proto *fp;
   Proto *fp;
   lua_lock(L);
   lua_lock(L);
   name = NULL;
   name = NULL;
-  f = ar->_func;
-  fp = getluaproto(f);
-  if (fp) {  /* `f' is a Lua function? */
-    name = luaF_getlocalname(fp, n, currentpc(f));
+  ci = ar->_ci;
+  fp = getluaproto(ci);
+  if (fp) {  /* is a Lua function? */
+    name = luaF_getlocalname(fp, n, currentpc(ci));
     if (name)
     if (name)
-      luaA_pushobject(L, (f+1)+(n-1));  /* push value */
+      luaA_pushobject(L, ci->base+(n-1));  /* push value */
   }
   }
   lua_unlock(L);
   lua_unlock(L);
   return name;
   return name;
@@ -178,19 +157,19 @@ LUA_API const l_char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
 
 
 LUA_API const l_char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
 LUA_API const l_char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
   const l_char *name;
   const l_char *name;
-  StkId f;
+  CallInfo *ci;
   Proto *fp;
   Proto *fp;
   lua_lock(L);
   lua_lock(L);
   name = NULL;
   name = NULL;
-  f = ar->_func;
-  fp = getluaproto(f);
+  ci = ar->_ci;
+  fp = getluaproto(ci);
   L->top--;  /* pop new value */
   L->top--;  /* pop new value */
-  if (fp) {  /* `f' is a Lua function? */
-    name = luaF_getlocalname(fp, n, currentpc(f));
+  if (fp) {  /* is a Lua function? */
+    name = luaF_getlocalname(fp, n, currentpc(ci));
     if (!name || name[0] == l_c('('))  /* `(' starts private locals */
     if (!name || name[0] == l_c('('))  /* `(' starts private locals */
       name = NULL;
       name = NULL;
     else
     else
-      setobj((f+1)+(n-1), L->top);
+      setobj(ci->base+(n-1), L->top);
   }
   }
   lua_unlock(L);
   lua_unlock(L);
   return name;
   return name;
@@ -205,16 +184,12 @@ static void infoLproto (lua_Debug *ar, Proto *f) {
 
 
 
 
 static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
 static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
-  Closure *cl = NULL;
-  switch (ttype(func)) {
-    case LUA_TFUNCTION:
-      cl = clvalue(func);
-      break;
-    case LUA_TMARK:
-      cl = infovalue(func)->func;
-      break;
-    default:
-      luaD_error(L, l_s("value for `lua_getinfo' is not a function"));
+  Closure *cl;
+  if (ttype(func) == LUA_TFUNCTION)
+    cl = clvalue(func);
+  else {
+    luaD_error(L, l_s("value for `lua_getinfo' is not a function"));
+    cl = NULL;  /* to avoid warnings */
   }
   }
   if (cl->isC) {
   if (cl->isC) {
     ar->source = l_s("=C");
     ar->source = l_s("=C");
@@ -255,60 +230,60 @@ static const l_char *travglobals (lua_State *L, const TObject *o) {
 }
 }
 
 
 
 
-static void getname (lua_State *L, StkId f, lua_Debug *ar) {
-  TObject o;
-  setnormalized(&o, f);
+static void getname (lua_State *L, const TObject *f, lua_Debug *ar) {
   /* try to find a name for given function */
   /* try to find a name for given function */
-  if ((ar->name = travglobals(L, &o)) != NULL)
+  if ((ar->name = travglobals(L, f)) != NULL)
     ar->namewhat = l_s("global");
     ar->namewhat = l_s("global");
   /* not found: try tag methods */
   /* not found: try tag methods */
-  else if ((ar->name = travtagmethods(G(L), &o)) != NULL)
+  else if ((ar->name = travtagmethods(G(L), f)) != NULL)
     ar->namewhat = l_s("tag-method");
     ar->namewhat = l_s("tag-method");
   else ar->namewhat = l_s("");  /* not found at all */
   else ar->namewhat = l_s("");  /* not found at all */
 }
 }
 
 
 
 
 LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) {
 LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) {
-  StkId func;
-  int isactive;
+  StkId f;
+  CallInfo *ci;
   int status = 1;
   int status = 1;
   lua_lock(L);
   lua_lock(L);
-  isactive = (*what != l_c('>'));
-  if (isactive)
-    func = ar->_func;
+  if (*what != l_c('>')) {  /* function is active? */
+    ci = ar->_ci;
+    f = ci->base - 1;
+  }
   else {
   else {
     what++;  /* skip the `>' */
     what++;  /* skip the `>' */
-    func = L->top - 1;
+    ci = NULL;
+    f = L->top - 1;
   }
   }
   for (; *what; what++) {
   for (; *what; what++) {
     switch (*what) {
     switch (*what) {
       case l_c('S'): {
       case l_c('S'): {
-        funcinfo(L, ar, func);
+        funcinfo(L, ar, f);
         break;
         break;
       }
       }
       case l_c('l'): {
       case l_c('l'): {
-        ar->currentline = currentline(func);
+        ar->currentline = currentline(ci);
         break;
         break;
       }
       }
       case l_c('u'): {
       case l_c('u'): {
-        ar->nups = nups(func);
+        ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->nupvalues : 0;
         break;
         break;
       }
       }
       case l_c('n'): {
       case l_c('n'): {
-        ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL;
+        ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
         if (ar->namewhat == NULL)
         if (ar->namewhat == NULL)
-          getname(L, func, ar);
+          getname(L, f, ar);
         break;
         break;
       }
       }
       case l_c('f'): {
       case l_c('f'): {
-        setnormalized(L->top, func);
+        setobj(L->top, f);
         incr_top;  /* push function */
         incr_top;  /* push function */
         break;
         break;
       }
       }
       default: status = 0;  /* invalid option */
       default: status = 0;  /* invalid option */
     }
     }
   }
   }
-  if (!isactive) L->top--;  /* pop function */
+  if (!ci) L->top--;  /* pop function */
   lua_unlock(L);
   lua_unlock(L);
   return status;
   return status;
 }
 }
@@ -539,13 +514,13 @@ int luaG_checkcode (lua_State *L, const Proto *pt) {
 
 
 
 
 static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
 static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
-  StkId func = aux_stackedfunction(L, 0, obj);
-  if (!isLmark(func))
+  CallInfo *ci = ci_stack(L, obj);
+  if (!isLmark(ci))
     return NULL;  /* not an active Lua function */
     return NULL;  /* not an active Lua function */
   else {
   else {
-    Proto *p = infovalue(func)->func->f.l;
-    int pc = currentpc(func);
-    int stackpos = obj - (func+1);  /* func+1 == function base */
+    Proto *p = ci_func(ci)->f.l;
+    int pc = currentpc(ci);
+    int stackpos = obj - ci->base;
     Instruction i = luaG_symbexec(L, p, pc, stackpos);
     Instruction i = luaG_symbexec(L, p, pc, stackpos);
     lua_assert(pc != -1);
     lua_assert(pc != -1);
     switch (GET_OPCODE(i)) {
     switch (GET_OPCODE(i)) {
@@ -570,18 +545,19 @@ static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
 }
 }
 
 
 
 
-static const l_char *getfuncname (lua_State *L, StkId f, const l_char **name) {
-  StkId func = aux_stackedfunction(L, 0, f);  /* calling function */
-  if (!isLmark(func))
+static const l_char *getfuncname (lua_State *L, CallInfo *ci,
+                                  const l_char **name) {
+  ci = ci->prev;  /* calling function */
+  if (ci == &L->basefunc || !isLmark(ci))
     return NULL;  /* not an active Lua function */
     return NULL;  /* not an active Lua function */
   else {
   else {
-    Proto *p = infovalue(func)->func->f.l;
-    int pc = currentpc(func);
+    Proto *p = ci_func(ci)->f.l;
+    int pc = currentpc(ci);
     Instruction i;
     Instruction i;
     if (pc == -1) return NULL;  /* function is not activated */
     if (pc == -1) return NULL;  /* function is not activated */
     i = p->code[pc];
     i = p->code[pc];
     return (GET_OPCODE(i) == OP_CALL
     return (GET_OPCODE(i) == OP_CALL
-             ? getobjname(L, (func+1)+GETARG_A(i), name)
+             ? getobjname(L, ci->base+GETARG_A(i), name)
              : NULL);  /* no useful name found */
              : NULL);  /* no useful name found */
   }
   }
 }
 }

+ 20 - 27
ldo.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.c,v 1.129 2001/02/23 17:28:12 roberto Exp roberto $
+** $Id: ldo.c,v 1.130 2001/03/02 17:27:50 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -42,7 +42,7 @@ void luaD_init (lua_State *L, int stacksize) {
   stacksize += EXTRA_STACK;
   stacksize += EXTRA_STACK;
   L->stack = luaM_newvector(L, stacksize, TObject);
   L->stack = luaM_newvector(L, stacksize, TObject);
   L->stacksize = stacksize;
   L->stacksize = stacksize;
-  L->Cbase = L->top = L->stack;
+  L->basefunc.base = L->top = L->stack;
   restore_stack_limit(L);
   restore_stack_limit(L);
 }
 }
 
 
@@ -90,8 +90,7 @@ static void luaD_openstack (lua_State *L, StkId pos) {
 
 
 
 
 static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
 static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
-  StkId old_Cbase = L->Cbase;
-  StkId old_top = L->Cbase = L->top;
+  StkId old_top = L->top;
   luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
   luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
   L->allowhooks = 0;  /* cannot call hooks inside a hook */
   L->allowhooks = 0;  /* cannot call hooks inside a hook */
   lua_unlock(L);
   lua_unlock(L);
@@ -100,45 +99,41 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
   lua_assert(L->allowhooks == 0);
   lua_assert(L->allowhooks == 0);
   L->allowhooks = 1;
   L->allowhooks = 1;
   L->top = old_top;
   L->top = old_top;
-  L->Cbase = old_Cbase;
 }
 }
 
 
 
 
-void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
+void luaD_lineHook (lua_State *L, int line, lua_Hook linehook) {
   if (L->allowhooks) {
   if (L->allowhooks) {
     lua_Debug ar;
     lua_Debug ar;
-    ar._func = func;
     ar.event = l_s("line");
     ar.event = l_s("line");
+    ar._ci = L->ci;
     ar.currentline = line;
     ar.currentline = line;
     dohook(L, &ar, linehook);
     dohook(L, &ar, linehook);
   }
   }
 }
 }
 
 
 
 
-static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
-                    const l_char *event) {
+static void luaD_callHook (lua_State *L, lua_Hook callhook,
+                           const l_char *event) {
   if (L->allowhooks) {
   if (L->allowhooks) {
     lua_Debug ar;
     lua_Debug ar;
-    ar._func = func;
     ar.event = event;
     ar.event = event;
-    infovalue(func)->pc = NULL;  /* function is not active */
+    ar._ci = L->ci;
+    L->ci->pc = NULL;  /* function is not active */
     dohook(L, &ar, callhook);
     dohook(L, &ar, callhook);
   }
   }
 }
 }
 
 
 
 
-static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
+static StkId callCclosure (lua_State *L, const struct Closure *cl) {
   int nup = cl->nupvalues;  /* number of upvalues */
   int nup = cl->nupvalues;  /* number of upvalues */
-  StkId old_Cbase = L->Cbase;
   int n;
   int n;
-  L->Cbase = base;       /* new base for C function */
   luaD_checkstack(L, nup+LUA_MINSTACK);  /* ensure minimum stack size */
   luaD_checkstack(L, nup+LUA_MINSTACK);  /* ensure minimum stack size */
   for (n=0; n<nup; n++)  /* copy upvalues as extra arguments */
   for (n=0; n<nup; n++)  /* copy upvalues as extra arguments */
     setobj(L->top++, &cl->upvalue[n]);
     setobj(L->top++, &cl->upvalue[n]);
   lua_unlock(L);
   lua_unlock(L);
   n = (*cl->f.c)(L);  /* do the actual call */
   n = (*cl->f.c)(L);  /* do the actual call */
   lua_lock(L);
   lua_lock(L);
-  L->Cbase = old_Cbase;  /* restore old C base */
   return L->top - n;  /* return index of first result */
   return L->top - n;  /* return index of first result */
 }
 }
 
 
@@ -154,7 +149,6 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
   lua_Hook callhook;
   lua_Hook callhook;
   StkId firstResult;
   StkId firstResult;
   CallInfo ci;
   CallInfo ci;
-  Closure *cl;
   if (ttype(func) != LUA_TFUNCTION) {
   if (ttype(func) != LUA_TFUNCTION) {
     /* `func' is not a function; check the `function' tag method */
     /* `func' is not a function; check the `function' tag method */
     Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION);
     Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION);
@@ -163,18 +157,17 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
     luaD_openstack(L, func);
     luaD_openstack(L, func);
     setclvalue(func, tm);  /* tag method is the new function to be called */
     setclvalue(func, tm);  /* tag method is the new function to be called */
   }
   }
-  cl = clvalue(func);
-  ci.func = cl;
-  setivalue(func, &ci);
+  ci.prev = L->ci;  /* chain new callinfo */
+  L->ci = &ci;
+  ci.base = func+1;
   callhook = L->callhook;
   callhook = L->callhook;
   if (callhook)
   if (callhook)
-    luaD_callHook(L, func, callhook, l_s("call"));
-  firstResult = (cl->isC ? callCclosure(L, cl, func+1) :
-                           luaV_execute(L, cl, func+1));
+    luaD_callHook(L, callhook, l_s("call"));
+  firstResult = (clvalue(func)->isC ? callCclosure(L, clvalue(func)) :
+                                      luaV_execute(L, clvalue(func), func+1));
   if (callhook)  /* same hook that was active at entry */
   if (callhook)  /* same hook that was active at entry */
-    luaD_callHook(L, func, callhook, l_s("return"));
-  lua_assert(ttype(func) == LUA_TMARK);
-  setnilvalue(func);  /* remove callinfo from the stack */
+    luaD_callHook(L, callhook, l_s("return"));
+  L->ci = ci.prev;  /* unchain callinfo */
   /* move results to `func' (to erase parameters and function) */
   /* move results to `func' (to erase parameters and function) */
   if (nResults == LUA_MULTRET) {
   if (nResults == LUA_MULTRET) {
     while (firstResult < L->top)  /* copy all results */
     while (firstResult < L->top)  /* copy all results */
@@ -368,7 +361,7 @@ void luaD_breakrun (lua_State *L, int errcode) {
 
 
 
 
 int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
 int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
-  StkId oldCbase = L->Cbase;
+  CallInfo *oldci = L->ci;
   StkId oldtop = L->top;
   StkId oldtop = L->top;
   struct lua_longjmp lj;
   struct lua_longjmp lj;
   int allowhooks = L->allowhooks;
   int allowhooks = L->allowhooks;
@@ -379,7 +372,7 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
     (*f)(L, ud);
     (*f)(L, ud);
   else {  /* an error occurred: restore the state */
   else {  /* an error occurred: restore the state */
     L->allowhooks = allowhooks;
     L->allowhooks = allowhooks;
-    L->Cbase = oldCbase;
+    L->ci = oldci;
     L->top = oldtop;
     L->top = oldtop;
     restore_stack_limit(L);
     restore_stack_limit(L);
   }
   }

+ 2 - 2
ldo.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.h,v 1.30 2001/02/07 18:13:49 roberto Exp roberto $
+** $Id: ldo.h,v 1.31 2001/02/23 17:17:25 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -21,7 +21,7 @@
 
 
 void luaD_init (lua_State *L, int stacksize);
 void luaD_init (lua_State *L, int stacksize);
 void luaD_adjusttop (lua_State *L, StkId base, int extra);
 void luaD_adjusttop (lua_State *L, StkId base, int extra);
-void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
+void luaD_lineHook (lua_State *L, int line, lua_Hook linehook);
 void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_checkstack (lua_State *L, int n);
 void luaD_checkstack (lua_State *L, int n);
 
 

+ 3 - 6
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 1.92 2001/02/23 17:17:25 roberto Exp roberto $
+** $Id: lgc.c,v 1.93 2001/03/02 17:27:50 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -85,9 +85,6 @@ static void markobject (GCState *st, TObject *o) {
     case LUA_TUSERDATA:  case LUA_TSTRING:
     case LUA_TUSERDATA:  case LUA_TSTRING:
       strmark(tsvalue(o));
       strmark(tsvalue(o));
       break;
       break;
-    case LUA_TMARK:
-      markclosure(st, infovalue(o)->func);
-      break;
     case LUA_TFUNCTION:
     case LUA_TFUNCTION:
       markclosure(st, clvalue(o));
       markclosure(st, clvalue(o));
       break;
       break;
@@ -107,8 +104,8 @@ static void markstacks (lua_State *L, GCState *st) {
     marktable(st, L1->gt);  /* mark table of globals */
     marktable(st, L1->gt);  /* mark table of globals */
     for (o=L1->stack; o<L1->top; o++)
     for (o=L1->stack; o<L1->top; o++)
       markobject(st, o);
       markobject(st, o);
-    lim = (L1->stack_last - L1->top > MAXSTACK) ? L1->top+MAXSTACK
-                                              : L1->stack_last;
+    lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK
+                                                     : L1->stack_last;
     for (; o<=lim; o++) setnilvalue(o);
     for (; o<=lim; o++) setnilvalue(o);
     lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
     lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
     L1 = L1->next;
     L1 = L1->next;

+ 7 - 15
lobject.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lobject.h,v 1.99 2001/02/23 20:32:32 roberto Exp roberto $
+** $Id: lobject.h,v 1.100 2001/03/02 17:27:50 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -22,24 +22,15 @@
 #endif
 #endif
 
 
 
 
-/* ttype for closures active in the stack */
-#define LUA_TMARK	6
-
 
 
 /* tags for values visible from Lua == first user-created tag */
 /* tags for values visible from Lua == first user-created tag */
 #define NUM_TAGS	6
 #define NUM_TAGS	6
 
 
 
 
-/* check whether `t' is a mark */
-#define is_T_MARK(t)	(ttype(t) == LUA_TMARK)
-
-
-
 typedef union {
 typedef union {
   struct TString *ts;
   struct TString *ts;
   struct Closure *cl;
   struct Closure *cl;
   struct Hash *h;
   struct Hash *h;
-  struct CallInfo *info;
   lua_Number n;		/* LUA_TNUMBER */
   lua_Number n;		/* LUA_TNUMBER */
 } Value;
 } Value;
 
 
@@ -56,7 +47,6 @@ typedef struct lua_TObject {
 #define tsvalue(o)      ((o)->value.ts)
 #define tsvalue(o)      ((o)->value.ts)
 #define clvalue(o)      ((o)->value.cl)
 #define clvalue(o)      ((o)->value.cl)
 #define hvalue(o)       ((o)->value.h)
 #define hvalue(o)       ((o)->value.h)
-#define infovalue(o)	((o)->value.info)
 
 
 
 
 /* Macros to set values */
 /* Macros to set values */
@@ -75,9 +65,6 @@ typedef struct lua_TObject {
 #define sethvalue(obj,x) \
 #define sethvalue(obj,x) \
   { TObject *_o=(obj); _o->tt=LUA_TTABLE; _o->value.h=(x); }
   { TObject *_o=(obj); _o->tt=LUA_TTABLE; _o->value.h=(x); }
 
 
-#define setivalue(obj,x) \
-  { TObject *_o=(obj); _o->tt=LUA_TMARK; _o->value.info=(x); }
-
 #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
 #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
 
 
 #define setobj(obj1,obj2) \
 #define setobj(obj1,obj2) \
@@ -85,6 +72,8 @@ typedef struct lua_TObject {
     o1->tt=o2->tt; o1->value = o2->value; }
     o1->tt=o2->tt; o1->value = o2->value; }
 
 
 
 
+typedef TObject *StkId;  /* index to stack elements */
+
 
 
 /*
 /*
 ** String headers for string table
 ** String headers for string table
@@ -209,13 +198,16 @@ typedef struct Hash {
 ** informations about a call (for debugging)
 ** informations about a call (for debugging)
 */
 */
 typedef struct CallInfo {
 typedef struct CallInfo {
-  struct Closure *func;  /* function being called */
+  struct CallInfo *prev;  /* linked list */
+  StkId base;  /* base for called function */
   const Instruction **pc;  /* current pc of called function */
   const Instruction **pc;  /* current pc of called function */
   int lastpc;  /* last pc traced */
   int lastpc;  /* last pc traced */
   int line;  /* current line */
   int line;  /* current line */
   int refi;  /* current index in `lineinfo' */
   int refi;  /* current index in `lineinfo' */
 } CallInfo;
 } CallInfo;
 
 
+#define ci_func(ci)	(clvalue((ci)->base - 1))
+
 
 
 extern const TObject luaO_nilobject;
 extern const TObject luaO_nilobject;
 
 

+ 3 - 1
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 1.57 2001/02/23 17:17:25 roberto Exp roberto $
+** $Id: lstate.c,v 1.58 2001/03/02 17:27:50 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -99,6 +99,8 @@ LUA_API lua_State *lua_open (lua_State *OL, int stacksize) {
     L->G = NULL;
     L->G = NULL;
     L->stack = NULL;
     L->stack = NULL;
     L->stacksize = 0;
     L->stacksize = 0;
+    L->ci = &L->basefunc;
+    L->basefunc.prev = NULL;
     L->errorJmp = NULL;
     L->errorJmp = NULL;
     L->callhook = NULL;
     L->callhook = NULL;
     L->linehook = NULL;
     L->linehook = NULL;

+ 5 - 6
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 1.53 2001/02/23 20:30:01 roberto Exp roberto $
+** $Id: lstate.h,v 1.54 2001/03/02 17:27:50 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -31,8 +31,6 @@
 #define LUA_USERSTATE
 #define LUA_USERSTATE
 #endif
 #endif
 
 
-typedef TObject *StkId;  /* index to stack elements */
-
 
 
 /*
 /*
 ** marks for Reference array
 ** marks for Reference array
@@ -90,18 +88,19 @@ typedef struct global_State {
 struct lua_State {
 struct lua_State {
   LUA_USERSTATE
   LUA_USERSTATE
   StkId top;  /* first free slot in the stack */
   StkId top;  /* first free slot in the stack */
-  StkId stack;  /* stack base */
+  CallInfo *ci;  /* call info for current function */
   StkId stack_last;  /* last free slot in the stack */
   StkId stack_last;  /* last free slot in the stack */
-  int stacksize;
-  StkId Cbase;  /* base for current C function */
   Hash *gt;  /* table for globals */
   Hash *gt;  /* table for globals */
   global_State *G;
   global_State *G;
+  StkId stack;  /* stack base */
+  int stacksize;
   lua_Hook callhook;
   lua_Hook callhook;
   lua_Hook linehook;
   lua_Hook linehook;
   int allowhooks;
   int allowhooks;
   struct lua_longjmp *errorJmp;  /* current error recover point */
   struct lua_longjmp *errorJmp;  /* current error recover point */
   lua_State *next;  /* circular double linked list of states */
   lua_State *next;  /* circular double linked list of states */
   lua_State *previous;
   lua_State *previous;
+  CallInfo basefunc;
 };
 };
 
 
 
 

+ 2 - 2
luadebug.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: luadebug.h,v 1.17 2000/10/30 12:38:50 roberto Exp roberto $
+** $Id: luadebug.h,v 1.18 2001/02/23 17:17:25 roberto Exp roberto $
 ** Debugging API
 ** Debugging API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -39,7 +39,7 @@ struct lua_Debug {
   const l_char *source;    /* (S) */
   const l_char *source;    /* (S) */
   l_char short_src[LUA_IDSIZE]; /* (S) */
   l_char short_src[LUA_IDSIZE]; /* (S) */
   /* private part */
   /* private part */
-  struct lua_TObject *_func;  /* active function */
+  struct CallInfo *_ci;  /* active function */
 };
 };
 
 
 
 

+ 8 - 8
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 1.173 2001/02/23 20:30:52 roberto Exp roberto $
+** $Id: lvm.c,v 1.174 2001/03/07 13:22:55 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -51,10 +51,10 @@ int luaV_tostring (lua_State *L, TObject *obj) {  /* LUA_NUMBER */
 }
 }
 
 
 
 
-static void traceexec (lua_State *L, StkId base, lua_Hook linehook) {
-  CallInfo *ci = infovalue(base-1);
-  int *lineinfo = ci->func->f.l->lineinfo;
-  int pc = (*ci->pc - ci->func->f.l->code) - 1;
+static void traceexec (lua_State *L, lua_Hook linehook) {
+  CallInfo *ci = L->ci;
+  int *lineinfo = ci_func(ci)->f.l->lineinfo;
+  int pc = (*ci->pc - ci_func(ci)->f.l->code) - 1;
   int newline;
   int newline;
   if (pc == 0) {  /* may be first time? */
   if (pc == 0) {  /* may be first time? */
     ci->line = 1;
     ci->line = 1;
@@ -65,7 +65,7 @@ static void traceexec (lua_State *L, StkId base, lua_Hook linehook) {
   /* calls linehook when enters a new line or jumps back (loop) */
   /* calls linehook when enters a new line or jumps back (loop) */
   if (newline != ci->line || pc <= ci->lastpc) {
   if (newline != ci->line || pc <= ci->lastpc) {
     ci->line = newline;
     ci->line = newline;
-    luaD_lineHook(L, base-2, newline, linehook);
+    luaD_lineHook(L, newline, linehook);
   }
   }
   ci->lastpc = pc;
   ci->lastpc = pc;
 }
 }
@@ -332,7 +332,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
   const Instruction *pc = tf->code;
   const Instruction *pc = tf->code;
   TString **const kstr = tf->kstr;
   TString **const kstr = tf->kstr;
   const lua_Hook linehook = L->linehook;
   const lua_Hook linehook = L->linehook;
-  infovalue(base-1)->pc = &pc;
+  L->ci->pc = &pc;
   if (tf->is_vararg)  /* varargs? */
   if (tf->is_vararg)  /* varargs? */
     adjust_varargs(L, base, tf->numparams);
     adjust_varargs(L, base, tf->numparams);
   luaD_adjusttop(L, base, tf->maxstacksize);
   luaD_adjusttop(L, base, tf->maxstacksize);
@@ -342,7 +342,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
     const Instruction i = *pc++;
     const Instruction i = *pc++;
     lua_assert(L->top == base+tf->maxstacksize);
     lua_assert(L->top == base+tf->maxstacksize);
     if (linehook)
     if (linehook)
-      traceexec(L, base, linehook);
+      traceexec(L, linehook);
     switch (GET_OPCODE(i)) {
     switch (GET_OPCODE(i)) {
       case OP_RETURN: {
       case OP_RETURN: {
         L->top = top;
         L->top = top;