|
@@ -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
|
|
|
** 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) {
|
|
|
- StkId f;
|
|
|
+ CallInfo *ci;
|
|
|
int status;
|
|
|
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 {
|
|
|
- ar->_func = f;
|
|
|
+ ar->_ci = ci;
|
|
|
status = 1;
|
|
|
}
|
|
|
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 refi;
|
|
|
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)
|
|
|
- return (*ci->pc - ci->func->f.l->code) - 1;
|
|
|
+ return (*ci->pc - ci_func(ci)->f.l->code) - 1;
|
|
|
else
|
|
|
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 */
|
|
|
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) {
|
|
|
const l_char *name;
|
|
|
- StkId f;
|
|
|
+ CallInfo *ci;
|
|
|
Proto *fp;
|
|
|
lua_lock(L);
|
|
|
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)
|
|
|
- luaA_pushobject(L, (f+1)+(n-1)); /* push value */
|
|
|
+ luaA_pushobject(L, ci->base+(n-1)); /* push value */
|
|
|
}
|
|
|
lua_unlock(L);
|
|
|
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) {
|
|
|
const l_char *name;
|
|
|
- StkId f;
|
|
|
+ CallInfo *ci;
|
|
|
Proto *fp;
|
|
|
lua_lock(L);
|
|
|
name = NULL;
|
|
|
- f = ar->_func;
|
|
|
- fp = getluaproto(f);
|
|
|
+ ci = ar->_ci;
|
|
|
+ fp = getluaproto(ci);
|
|
|
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 */
|
|
|
name = NULL;
|
|
|
else
|
|
|
- setobj((f+1)+(n-1), L->top);
|
|
|
+ setobj(ci->base+(n-1), L->top);
|
|
|
}
|
|
|
lua_unlock(L);
|
|
|
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) {
|
|
|
- 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) {
|
|
|
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 */
|
|
|
- if ((ar->name = travglobals(L, &o)) != NULL)
|
|
|
+ if ((ar->name = travglobals(L, f)) != NULL)
|
|
|
ar->namewhat = l_s("global");
|
|
|
/* 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");
|
|
|
else ar->namewhat = l_s(""); /* not found at all */
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
|
|
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 {
|
|
|
what++; /* skip the `>' */
|
|
|
- func = L->top - 1;
|
|
|
+ ci = NULL;
|
|
|
+ f = L->top - 1;
|
|
|
}
|
|
|
for (; *what; what++) {
|
|
|
switch (*what) {
|
|
|
case l_c('S'): {
|
|
|
- funcinfo(L, ar, func);
|
|
|
+ funcinfo(L, ar, f);
|
|
|
break;
|
|
|
}
|
|
|
case l_c('l'): {
|
|
|
- ar->currentline = currentline(func);
|
|
|
+ ar->currentline = currentline(ci);
|
|
|
break;
|
|
|
}
|
|
|
case l_c('u'): {
|
|
|
- ar->nups = nups(func);
|
|
|
+ ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->nupvalues : 0;
|
|
|
break;
|
|
|
}
|
|
|
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)
|
|
|
- getname(L, func, ar);
|
|
|
+ getname(L, f, ar);
|
|
|
break;
|
|
|
}
|
|
|
case l_c('f'): {
|
|
|
- setnormalized(L->top, func);
|
|
|
+ setobj(L->top, f);
|
|
|
incr_top; /* push function */
|
|
|
break;
|
|
|
}
|
|
|
default: status = 0; /* invalid option */
|
|
|
}
|
|
|
}
|
|
|
- if (!isactive) L->top--; /* pop function */
|
|
|
+ if (!ci) L->top--; /* pop function */
|
|
|
lua_unlock(L);
|
|
|
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) {
|
|
|
- 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 */
|
|
|
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);
|
|
|
lua_assert(pc != -1);
|
|
|
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 */
|
|
|
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;
|
|
|
if (pc == -1) return NULL; /* function is not activated */
|
|
|
i = p->code[pc];
|
|
|
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 */
|
|
|
}
|
|
|
}
|