new debug API (first version)

This commit is contained in:
Roberto Ierusalimschy 2000-01-19 10:00:45 -02:00
parent 27163f032e
commit 2877bad4c2
13 changed files with 286 additions and 308 deletions

32
lapi.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 1.67 1999/12/30 18:27:03 roberto Exp roberto $
** $Id: lapi.c,v 1.68 2000/01/13 15:56:03 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@ -30,29 +30,12 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
const lua_Type luaA_normtype[] = { /* ORDER LUA_T */
LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
LUA_T_LCLOSURE, LUA_T_CCLOSURE,
LUA_T_LCLOSURE, LUA_T_CCLOSURE, /* LUA_T_LCLMARK, LUA_T_CCLMARK */
LUA_T_LPROTO, LUA_T_CPROTO /* LUA_T_LMARK, LUA_T_CMARK */
};
void luaA_setnormalized (TObject *d, const TObject *s) {
d->value = s->value;
d->ttype = luaA_normalizedtype(s);
}
const TObject *luaA_protovalue (const TObject *o) {
switch (luaA_normalizedtype(o)) {
switch (ttype(o)) {
case LUA_T_CCLOSURE: case LUA_T_LCLOSURE:
return protovalue(o);
default:
LUA_ASSERT(L, luaA_normalizedtype(o) == LUA_T_LPROTO ||
luaA_normalizedtype(o) == LUA_T_CPROTO,
"invalid `function'");
return o;
}
}
@ -107,7 +90,7 @@ int lua_callfunction (lua_State *L, lua_Object function) {
return 1;
else {
luaD_openstack(L, L->Cstack.base);
luaA_setnormalized(L->Cstack.base, function);
*L->Cstack.base = *function;
return luaD_protectedrun(L);
}
}
@ -248,12 +231,7 @@ int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) {
UNUSED(L);
if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
return (o1 == o2);
else {
TObject obj1, obj2;
luaA_setnormalized(&obj1, o1);
luaA_setnormalized(&obj2, o2);
return luaO_equalObj(&obj1, &obj2);
}
else return luaO_equalObj(o1, o2);
}
@ -344,7 +322,7 @@ void luaA_pushobject (lua_State *L, const TObject *o) {
void lua_pushobject (lua_State *L, lua_Object o) {
if (o == LUA_NOOBJECT)
lua_error(L, "API error - attempt to push a NOOBJECT");
luaA_setnormalized(L->top, o);
*L->top = *o;
incr_top;
}

8
lapi.h
View File

@ -1,5 +1,5 @@
/*
** $Id: lapi.h,v 1.11 1999/12/14 18:33:29 roberto Exp roberto $
** $Id: lapi.h,v 1.12 1999/12/23 18:19:57 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@ -11,12 +11,6 @@
#include "lobject.h"
extern const lua_Type luaA_normtype[];
#define luaA_normalizedtype(o) (luaA_normtype[-ttype(o)])
void luaA_setnormalized (TObject *d, const TObject *s);
void luaA_checkCparams (lua_State *L, int nParams);
const TObject *luaA_protovalue (const TObject *o);
void luaA_pushobject (lua_State *L, const TObject *o);

View File

@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.23 1999/12/27 17:33:22 roberto Exp roberto $
** $Id: lauxlib.c,v 1.24 1999/12/28 11:52:49 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@ -31,14 +31,14 @@ int luaL_findstring (const char *name, const char *const list[]) {
}
void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
lua_Function f = lua_stackedfunction(L, 0);
const char *funcname;
lua_getobjname(L, f, &funcname);
narg -= lua_nups(L, f);
if (funcname == NULL)
funcname = "?";
lua_Dbgactreg ar;
lua_getstack(L, 0, &ar);
lua_getinfo(L, "nu", &ar);
narg -= ar.nups;
if (ar.name == NULL)
ar.name = "?";
luaL_verror(L, "bad argument #%d to `%.50s' (%.100s)",
narg, funcname, extramsg);
narg, ar.name, extramsg);
}

155
ldblib.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldblib.c,v 1.8 1999/11/22 17:39:51 roberto Exp roberto $
** $Id: ldblib.c,v 1.9 1999/12/21 18:04:41 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@ -33,113 +33,73 @@ static void settabsi (lua_State *L, lua_Object t, const char *i, int v) {
}
static lua_Object getfuncinfo (lua_State *L, lua_Object func) {
lua_Object result = lua_createtable(L);
const char *str;
int line;
lua_funcinfo(L, func, &str, &line);
if (line == -1) /* C function? */
settabss(L, result, "kind", "C");
else if (line == 0) { /* "main"? */
settabss(L, result, "kind", "chunk");
settabss(L, result, "source", str);
}
else { /* Lua function */
settabss(L, result, "kind", "Lua");
settabsi(L, result, "def_line", line);
settabss(L, result, "source", str);
}
if (line != 0) { /* is it not a "main"? */
const char *kind = lua_getobjname(L, func, &str);
if (*kind) {
settabss(L, result, "name", str);
settabss(L, result, "where", kind);
}
}
return result;
static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) {
lua_pushobject(L, t);
lua_pushstring(L, i);
lua_pushobject(L, v);
lua_settable(L);
}
static void getstack (lua_State *L) {
lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
if (func == LUA_NOOBJECT) /* level out of range? */
lua_Dbgactreg ar;
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
return;
else {
lua_Object result = getfuncinfo(L, func);
int currline = lua_currentline(L, func);
if (currline > 0)
settabsi(L, result, "current", currline);
lua_pushobject(L, result);
lua_pushstring(L, "func");
lua_pushobject(L, func);
lua_settable(L); /* result.func = func */
lua_pushobject(L, result);
}
}
const char *options = luaL_check_string(L, 2);
lua_Object res = lua_createtable(L);
if (!lua_getinfo(L, options, &ar))
luaL_argerror(L, 2, "invalid option");
for ( ;*options; options++) {
switch (*options) {
case 'S':
settabss(L, res, "source", ar.source);
settabsi(L, res, "linedefined", ar.linedefined);
settabss(L, res, "what", ar.what);
break;
case 'l':
settabsi(L, res, "currentline", ar.currentline);
break;
case 'u':
settabsi(L, res, "nups", ar.nups);
break;
case 'n':
settabss(L, res, "name", ar.name);
settabss(L, res, "namewhat", ar.namewhat);
break;
case 'f':
settabso(L, res, "func", ar.func);
break;
static void funcinfo (lua_State *L) {
lua_pushobject(L, getfuncinfo(L, luaL_functionarg(L, 1)));
}
static int findlocal (lua_State *L, lua_Object func, int arg) {
lua_Object v = lua_getparam(L, arg);
if (lua_isnumber(L, v))
return (int)lua_getnumber(L, v);
else {
const char *name = luaL_check_string(L, arg);
int i = 0;
int result = -1;
const char *vname;
while (lua_getlocal(L, func, ++i, &vname) != LUA_NOOBJECT) {
if (strcmp(name, vname) == 0)
result = i; /* keep looping to get the last var with this name */
}
}
if (result == -1)
luaL_verror(L, "no local variable `%.50s' at given level", name);
return result;
lua_pushobject(L, res);
}
}
static void getlocal (lua_State *L) {
lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
lua_Object val;
const char *name;
if (func == LUA_NOOBJECT) /* level out of range? */
return; /* return nil */
else if (lua_getparam(L, 2) != LUA_NOOBJECT) { /* 2nd argument? */
if ((val = lua_getlocal(L, func, findlocal(L, func, 2), &name)) != LUA_NOOBJECT) {
lua_pushobject(L, val);
lua_pushstring(L, name);
}
/* else return nil */
}
else { /* collect all locals in a table */
lua_Object result = lua_createtable(L);
int i;
for (i=1; ;i++) {
if ((val = lua_getlocal(L, func, i, &name)) == LUA_NOOBJECT)
break;
lua_pushobject(L, result);
lua_pushstring(L, name);
lua_pushobject(L, val);
lua_settable(L); /* result[name] = value */
}
lua_pushobject(L, result);
lua_Dbgactreg ar;
lua_Dbglocvar lvar;
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
luaL_argerror(L, 1, "level out of range");
lvar.index = luaL_check_int(L, 2);
if (lua_getlocal(L, &ar, &lvar)) {
lua_pushstring(L, lvar.name);
lua_pushobject(L, lvar.value);
}
}
static void setlocal (lua_State *L) {
lua_Object func = lua_stackedfunction(L, luaL_check_int(L, 1));
int numvar;
luaL_arg_check(L, func != LUA_NOOBJECT, 1, "level out of range");
numvar = findlocal(L, func, 2);
lua_pushobject(L, luaL_nonnullarg(L, 3));
if (!lua_setlocal(L, func, numvar))
lua_error(L, "no such local variable");
lua_Dbgactreg ar;
lua_Dbglocvar lvar;
if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
luaL_argerror(L, 1, "level out of range");
lvar.index = luaL_check_int(L, 2);
lvar.value = luaL_nonnullarg(L, 3);
if (lua_setlocal(L, &ar, &lvar))
lua_pushstring(L, lvar.name);
}
@ -149,21 +109,17 @@ static int callhook = LUA_NOREF; /* Lua reference to call hook function */
static void linef (lua_State *L, int line) {
static void linef (lua_State *L, lua_Dbgactreg *ar) {
if (linehook != LUA_NOREF) {
lua_pushnumber(L, line);
lua_pushnumber(L, ar->currentline);
lua_callfunction(L, lua_getref(L, linehook));
}
}
static void callf (lua_State *L, lua_Function f, const char *file, int line) {
static void callf (lua_State *L, lua_Dbgactreg *ar) {
if (callhook != LUA_NOREF) {
if (f != LUA_NOOBJECT) {
lua_pushobject(L, f);
lua_pushstring(L, file);
lua_pushnumber(L, line);
}
lua_pushstring(L, ar->event);
lua_callfunction(L, lua_getref(L, callhook));
}
}
@ -200,7 +156,6 @@ static void setlinehook (lua_State *L) {
static const struct luaL_reg dblib[] = {
{"funcinfo", funcinfo},
{"getlocal", getlocal},
{"getstack", getstack},
{"setcallhook", setcallhook},

213
ldebug.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.3 1999/12/29 16:31:15 roberto Exp roberto $
** $Id: ldebug.c,v 1.4 1999/12/30 18:28:40 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -10,6 +10,7 @@
#include "lapi.h"
#include "lauxlib.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lobject.h"
#include "lstate.h"
@ -19,22 +20,38 @@
#include "luadebug.h"
static int hasdebuginfo (lua_State *L, lua_Function f) {
static const lua_Type normtype[] = { /* ORDER LUA_T */
LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
LUA_T_LCLOSURE, LUA_T_CCLOSURE,
LUA_T_LCLOSURE, LUA_T_CCLOSURE, /* LUA_T_LCLMARK, LUA_T_CCLMARK */
LUA_T_LPROTO, LUA_T_CPROTO /* LUA_T_LMARK, LUA_T_CMARK */
};
static void setnormalized (TObject *d, const TObject *s) {
d->value = s->value;
d->ttype = normtype[-ttype(s)];
}
static int hasdebuginfo (lua_State *L, StkId f) {
return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE);
}
lua_LHFunction lua_setlinehook (lua_State *L, lua_LHFunction func) {
lua_LHFunction old = L->linehook;
L->linehook = func;
return old;
lua_Dbghook lua_setcallhook (lua_State *L, lua_Dbghook func) {
lua_Dbghook oldhook = L->callhook;
L->callhook = func;
return oldhook;
}
lua_CHFunction lua_setcallhook (lua_State *L, lua_CHFunction func) {
lua_CHFunction old = L->callhook;
L->callhook = func;
return old;
lua_Dbghook lua_setlinehook (lua_State *L, lua_Dbghook func) {
lua_Dbghook oldhook = L->linehook;
L->linehook = func;
return oldhook;
}
@ -45,7 +62,7 @@ int lua_setdebug (lua_State *L, int debug) {
}
static lua_Function aux_stackedfunction (lua_State *L, int level, StkId top) {
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].ttype)) {
@ -54,18 +71,23 @@ static lua_Function aux_stackedfunction (lua_State *L, int level, StkId top) {
level--;
}
}
return LUA_NOOBJECT;
return NULL;
}
lua_Function lua_stackedfunction (lua_State *L, int level) {
return aux_stackedfunction(L, level, L->top);
int lua_getstack (lua_State *L, int level, lua_Dbgactreg *ar) {
StkId f = aux_stackedfunction(L, level, L->top);
if (f == NULL) return 0; /* there is no such level */
else {
ar->_func = f;
return 1;
}
}
static const char *luaG_getname (lua_State *L, const char **name, StkId top) {
lua_Function f = aux_stackedfunction(L, 0, top);
if (f == LUA_NOOBJECT || !hasdebuginfo(L, f) || ttype(f+2) == LUA_T_NIL)
StkId f = aux_stackedfunction(L, 0, top);
if (f == NULL || !hasdebuginfo(L, f) || ttype(f+2) == LUA_T_NIL)
return ""; /* no name available */
else {
int i = (f+2)->value.i;
@ -79,10 +101,10 @@ static const char *luaG_getname (lua_State *L, const char **name, StkId top) {
}
int lua_nups (lua_State *L, lua_Function f) {
UNUSED(L);
switch (luaA_normalizedtype(f)) {
static int lua_nups (StkId f) {
switch (ttype(f)) {
case LUA_T_LCLOSURE: case LUA_T_CCLOSURE:
case LUA_T_LCLMARK: case LUA_T_CCLMARK:
return f->value.cl->nelems;
default:
return 0;
@ -90,67 +112,66 @@ int lua_nups (lua_State *L, lua_Function f) {
}
int lua_currentline (lua_State *L, lua_Function f) {
static int lua_currentline (lua_State *L, StkId f) {
return hasdebuginfo(L, f) ? (f+1)->value.i : -1;
}
lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
const char **name) {
/* check whether `f' is a Lua function */
if (lua_tag(L, f) != LUA_T_LPROTO)
return LUA_NOOBJECT;
else {
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
*name = luaF_getlocalname(fp, local_number, lua_currentline(L, f));
if (*name) {
/* if "*name", there must be a LUA_T_LINE and a NAME */
/* therefore, f+3 points to function base */
LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, "");
return luaA_putluaObject(L, (f+3)+(local_number-1));
}
else
return LUA_NOOBJECT;
}
static TProtoFunc *getluaproto (StkId f) {
if (ttype(f) == LUA_T_LMARK)
return f->value.tf;
else if (ttype(f) == LUA_T_LCLMARK)
return protovalue(f)->value.tf;
else return NULL;
}
int lua_setlocal (lua_State *L, lua_Function f, int local_number) {
/* check whether `f' is a Lua function */
if (lua_tag(L, f) != LUA_T_LPROTO)
return 0;
else {
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
const char *name = luaF_getlocalname(fp, local_number,
lua_currentline(L, f));
luaA_checkCparams(L, 1);
--L->top;
if (name) {
LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, "");
*((f+3)+(local_number-1)) = *L->top;
return 1;
}
else
return 0;
}
int lua_getlocal (lua_State *L, const lua_Dbgactreg *ar, lua_Dbglocvar *v) {
StkId f = ar->_func;
TProtoFunc *fp = getluaproto(f);
if (!fp) return 0; /* `f' is not a Lua function? */
v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f));
if (!v->name) return 0;
/* if `name', there must be a LUA_T_LINE and a NAME */
/* therefore, f+3 points to function base */
LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, "");
v->value = luaA_putluaObject(L, (f+3)+(v->index-1));
return 1;
}
void lua_funcinfo (lua_State *L, lua_Object func,
const char **source, int *linedefined) {
if (!lua_isfunction(L, func))
lua_error(L, "API error - `funcinfo' called with a non-function value");
else {
const TObject *f = luaA_protovalue(func);
if (luaA_normalizedtype(f) == LUA_T_LPROTO) {
*source = tfvalue(f)->source->str;
*linedefined = tfvalue(f)->lineDefined;
}
else {
*source = "(C)";
*linedefined = -1;
}
int lua_setlocal (lua_State *L, const lua_Dbgactreg *ar, lua_Dbglocvar *v) {
StkId f = ar->_func;
TProtoFunc *fp = getluaproto(f);
if (!fp) return 0; /* `f' is not a Lua function? */
v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f));
if (!v->name) return 0;
LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, "");
*((f+3)+(v->index-1)) = *v->value;
return 1;
}
static void lua_funcinfo (lua_Dbgactreg *ar) {
StkId func = ar->_func;
switch (ttype(func)) {
case LUA_T_LPROTO: case LUA_T_LMARK:
ar->source = tfvalue(func)->source->str;
ar->linedefined = tfvalue(func)->lineDefined;
ar->what = "Lua";
break;
case LUA_T_LCLOSURE: case LUA_T_LCLMARK:
ar->source = tfvalue(protovalue(func))->source->str;
ar->linedefined = tfvalue(protovalue(func))->lineDefined;
ar->what = "Lua";
break;
default:
ar->source = "(C)";
ar->linedefined = -1;
ar->what = "C";
}
if (ar->linedefined == 0)
ar->what = "main";
}
@ -159,28 +180,56 @@ static int checkfunc (lua_State *L, TObject *o) {
}
const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) {
static void lua_getobjname (lua_State *L, StkId f, lua_Dbgactreg *ar) {
GlobalVar *g;
if (is_T_MARK(ttype(o))) { /* `o' is an active function? */
/* look for caller debug information */
const char *kind = luaG_getname(L, name, o);
if (*kind) return kind;
/* else go through */
}
ar->namewhat = luaG_getname(L, &ar->name, f); /* caller debug information */
if (*ar->namewhat) return;
/* try to find a name for given function */
luaA_setnormalized(L->top, o); /* to be used by `checkfunc' */
setnormalized(L->top, f); /* to be used by `checkfunc' */
for (g=L->rootglobal; g; g=g->next) {
if (checkfunc(L, &g->value)) {
*name = g->name->str;
return "global";
ar->name = g->name->str;
ar->namewhat = "global";
return;
}
}
/* not found: try tag methods */
if ((*name = luaT_travtagmethods(L, checkfunc)) != NULL)
return "tag-method";
else return ""; /* not found at all */
if ((ar->name = luaT_travtagmethods(L, checkfunc)) != NULL)
ar->namewhat = "tag-method";
else ar->namewhat = ""; /* not found at all */
}
int lua_getinfo (lua_State *L, const char *what, lua_Dbgactreg *ar) {
StkId func = ar->_func;
LUA_ASSERT(L, is_T_MARK(ttype(func)), "invalid activation record");
for ( ;*what; what++) {
switch (*what) {
case 'S':
lua_funcinfo(ar);
break;
case 'l':
ar->currentline = lua_currentline(L, func);
break;
case 'u':
ar->nups = lua_nups(func);
break;
case 'n':
lua_getobjname(L, func, ar);
break;
case 'f':
setnormalized(L->top, func);
incr_top;
ar->func = luaA_putObjectOnTop(L);
break;
default: return 0; /* invalid option */
}
}
return 1;
}
static void call_index_error (lua_State *L, TObject *o, const char *tp,
const char *v) {
const char *name;

43
ldo.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.64 1999/12/30 18:40:57 roberto Exp roberto $
** $Id: ldo.c,v 1.65 2000/01/13 15:56:03 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -55,8 +55,9 @@ void luaD_checkstack (lua_State *L, int n) {
lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!");
}
else {
lua_Dbgactreg dummy;
L->stack_last += EXTRA_STACK; /* to be used by error message */
if (lua_stackedfunction(L, L->stacksize/SLOTS_PER_F) == LUA_NOOBJECT) {
if (lua_getstack(L, L->stacksize/SLOTS_PER_F, &dummy) == 0) {
/* too few funcs on stack: doesn't look like a recursion loop */
lua_error(L, "Lua2C - C2Lua overflow");
}
@ -100,13 +101,17 @@ void luaD_openstack (lua_State *L, StkId pos) {
}
void luaD_lineHook (lua_State *L, int line) {
void luaD_lineHook (lua_State *L, StkId func, int line) {
if (L->allowhooks) {
lua_Dbgactreg ar;
struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
L->Cstack.num = 0;
ar._func = func;
ar.event = "line";
ar.currentline = line;
L->allowhooks = 0; /* cannot call hooks inside a hook */
(*L->linehook)(L, line);
(*L->linehook)(L, &ar);
L->allowhooks = 1;
L->top = old_top;
L->Cstack = oldCLS;
@ -114,29 +119,17 @@ void luaD_lineHook (lua_State *L, int line) {
}
void luaD_callHook (lua_State *L, StkId func, lua_CHFunction callhook,
int isreturn) {
void luaD_callHook (lua_State *L, StkId func, lua_Dbghook callhook,
const char *event) {
if (L->allowhooks) {
lua_Dbgactreg ar;
struct C_Lua_Stack oldCLS = L->Cstack;
StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
L->Cstack.num = 0;
ar._func = func;
ar.event = event;
L->allowhooks = 0; /* cannot call hooks inside a hook */
if (isreturn)
callhook(L, LUA_NOOBJECT, "(return)", 0);
else {
switch (ttype(func)) {
case LUA_T_LPROTO:
callhook(L, func, tfvalue(func)->source->str,
tfvalue(func)->lineDefined);
break;
case LUA_T_LCLOSURE:
callhook(L, func, tfvalue(protovalue(func))->source->str,
tfvalue(protovalue(func))->lineDefined);
break;
default:
callhook(L, func, "(C)", -1);
}
}
callhook(L, &ar);
L->allowhooks = 1;
L->top = old_top;
L->Cstack = oldCLS;
@ -157,7 +150,7 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
L->Cstack.lua2C = base;
L->Cstack.base = L->top;
if (L->callhook)
luaD_callHook(L, base-1, L->callhook, 0);
luaD_callHook(L, base-1, L->callhook, "call");
(*f)(L); /* do the actual call */
firstResult = L->Cstack.base;
L->Cstack = oldCLS;
@ -195,7 +188,7 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
StkId firstResult;
lua_CHFunction callhook = L->callhook;
lua_Dbghook callhook = L->callhook;
retry: /* for `function' tag method */
switch (ttype(func)) {
case LUA_T_CPROTO:
@ -228,7 +221,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
}
}
if (callhook) /* same hook that was active at entry */
luaD_callHook(L, NULL, callhook, 1); /* `return' hook */
luaD_callHook(L, func, callhook, "return");
/* adjust the number of results */
if (nResults == MULT_RET)
nResults = L->top - firstResult;

8
ldo.h
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 1.15 1999/12/21 18:04:41 roberto Exp roberto $
** $Id: ldo.h,v 1.16 1999/12/30 18:28:40 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -26,9 +26,9 @@
void luaD_init (lua_State *L, int stacksize);
void luaD_adjusttop (lua_State *L, StkId base, int extra);
void luaD_openstack (lua_State *L, StkId pos);
void luaD_callHook (lua_State *L, StkId func, lua_CHFunction callhook,
int isreturn);
void luaD_lineHook (lua_State *L, int line);
void luaD_callHook (lua_State *L, StkId func, lua_Dbghook callhook,
const char *event);
void luaD_lineHook (lua_State *L, StkId func, int line);
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);

View File

@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 1.54 1999/12/28 11:52:49 roberto Exp roberto $
** $Id: liolib.c,v 1.55 1999/12/30 18:28:40 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@ -529,53 +529,49 @@ static void io_debug (lua_State *L) {
static void errorfb (lua_State *L) {
char buff[MAXMESSAGE];
int level = 1; /* skip level 0 (it's this function) */
lua_Object func;
lua_Dbgactreg ar;
lua_Object alertfunc = lua_rawgetglobal(L, "_ALERT");
sprintf(buff, "error: %.200s\n", lua_getstring(L, lua_getparam(L, 1)));
while ((func = lua_stackedfunction(L, level++)) != LUA_NOOBJECT) {
const char *name;
int currentline;
const char *chunkname;
while (lua_getstack(L, level++, &ar)) {
char buffchunk[MAXSRC];
int linedefined;
lua_funcinfo(L, func, &chunkname, &linedefined);
luaL_chunkid(buffchunk, chunkname, sizeof(buffchunk));
lua_getinfo(L, "Snl", &ar);
luaL_chunkid(buffchunk, ar.source, sizeof(buffchunk));
if (level == 2) strcat(buff, "Active Stack:\n");
strcat(buff, " ");
if (strlen(buff) > MAXMESSAGE-MESSAGESIZE) {
strcat(buff, "...\n");
break; /* buffer is full */
}
switch (*lua_getobjname(L, func, &name)) {
case 'g': case 'l':
sprintf(buff+strlen(buff), "function `%.50s'", name);
switch (*ar.namewhat) {
case 'g': case 'l': /* global, local */
sprintf(buff+strlen(buff), "function `%.50s'", ar.name);
break;
case 'f':
sprintf(buff+strlen(buff), "method `%.50s'", name);
case 'f': /* field */
sprintf(buff+strlen(buff), "method `%.50s'", ar.name);
break;
case 't':
sprintf(buff+strlen(buff), "`%.50s' tag method", name);
case 't': /* tag method */
sprintf(buff+strlen(buff), "`%.50s' tag method", ar.name);
break;
default: {
if (linedefined == 0)
if (*ar.what == 'm') /* main? */
sprintf(buff+strlen(buff), "main of %.70s", buffchunk);
else if (linedefined < 0)
else if (*ar.what == 'C') /* C function? */
sprintf(buff+strlen(buff), "%.70s", buffchunk);
else
sprintf(buff+strlen(buff), "function <%d:%.70s>",
linedefined, buffchunk);
chunkname = NULL;
ar.linedefined, buffchunk);
ar.source = NULL;
}
}
if ((currentline = lua_currentline(L, func)) > 0)
sprintf(buff+strlen(buff), " at line %d", currentline);
if (chunkname)
if (ar.currentline > 0)
sprintf(buff+strlen(buff), " at line %d", ar.currentline);
if (ar.source)
sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
strcat(buff, "\n");
}
func = lua_rawgetglobal(L, "_ALERT");
if (lua_isfunction(L, func)) { /* avoid error loop if _ALERT is not defined */
if (lua_isfunction(L, alertfunc)) { /* avoid loop if _ALERT is not defined */
lua_pushstring(L, buff);
lua_callfunction(L, func);
lua_callfunction(L, alertfunc);
}
}

View File

@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.26 1999/12/21 18:04:41 roberto Exp roberto $
** $Id: lstate.h,v 1.27 1999/12/27 17:33:22 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@ -76,8 +76,8 @@ struct lua_State {
unsigned long GCthreshold;
unsigned long nblocks; /* number of `blocks' currently allocated */
int debug;
lua_CHFunction callhook;
lua_LHFunction linehook;
lua_Dbghook callhook;
lua_Dbghook linehook;
int allowhooks;
};

View File

@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 1.3 1999/12/27 17:33:22 roberto Exp roberto $
** $Id: ltests.c,v 1.4 2000/01/13 16:30:47 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@ -230,10 +230,6 @@ static void testC (lua_State *L) {
int n = getreg(L, &pc);
lua_settagmethod(L, (int)lua_getnumber(L, reg[n]), getname(&pc));
}
else if EQ("getfunc") {
int n = getreg(L, &pc);
reg[n] = lua_stackedfunction(L, getnum(&pc));
}
else if EQ("beginblock") {
lua_beginblock(L);
}

4
ltm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 1.29 1999/11/22 13:12:07 roberto Exp roberto $
** $Id: ltm.c,v 1.30 1999/12/23 18:19:57 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@ -108,8 +108,6 @@ int luaT_effectivetag (const TObject *o) {
LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
LUA_T_LPROTO, LUA_T_CPROTO, /* LUA_T_LCLOSURE, LUA_T_CCLOSURE */
LUA_T_LPROTO, LUA_T_CPROTO, /* LUA_T_LCLMARK, LUA_T_CCLMARK */
LUA_T_LPROTO, LUA_T_CPROTO /* LUA_T_LMARK, LUA_T_CMARK */
};
int t;
switch (t = ttype(o)) {

View File

@ -1,5 +1,5 @@
/*
** $Id: luadebug.h,v 1.7 1999/08/16 20:52:00 roberto Exp roberto $
** $Id: luadebug.h,v 1.8 1999/11/22 13:12:07 roberto Exp roberto $
** Debugging API
** See Copyright Notice in lua.h
*/
@ -11,25 +11,44 @@
#include "lua.h"
typedef lua_Object lua_Function;
typedef struct lua_Dbgactreg lua_Dbgactreg; /* activation record */
typedef struct lua_Dbglocvar lua_Dbglocvar; /* local variable */
typedef void (*lua_LHFunction) (lua_State *L, int line);
typedef void (*lua_CHFunction) (lua_State *L, lua_Function func, const char *file, int line);
typedef void (*lua_Dbghook) (lua_State *L, lua_Dbgactreg *ar);
lua_Function lua_stackedfunction (lua_State *L, int level);
void lua_funcinfo (lua_State *L, lua_Object func, const char **source, int *linedefined);
int lua_currentline (lua_State *L, lua_Function func);
const char *lua_getobjname (lua_State *L, lua_Object o, const char **name);
lua_Object lua_getlocal (lua_State *L, lua_Function func, int local_number,
const char **name);
int lua_setlocal (lua_State *L, lua_Function func, int local_number);
int lua_getstack (lua_State *L, int level, lua_Dbgactreg *ar);
int lua_getinfo (lua_State *L, const char *what, lua_Dbgactreg *ar);
int lua_getlocal (lua_State *L, const lua_Dbgactreg *ar, lua_Dbglocvar *v);
int lua_setlocal (lua_State *L, const lua_Dbgactreg *ar, lua_Dbglocvar *v);
int lua_nups (lua_State *L, lua_Function func);
lua_LHFunction lua_setlinehook (lua_State *L, lua_LHFunction func);
lua_CHFunction lua_setcallhook (lua_State *L, lua_CHFunction func);
int lua_setdebug (lua_State *L, int debug);
lua_Dbghook lua_setcallhook (lua_State *L, lua_Dbghook func);
lua_Dbghook lua_setlinehook (lua_State *L, lua_Dbghook func);
struct lua_Dbgactreg {
const char *event; /* `call', `return' */
const char *source; /* (S) */
int linedefined; /* (S) */
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
int currentline; /* (l) */
const char *name; /* (n) */
const char *namewhat; /* (n) global, tag method, local, field */
int nups; /* (u) number of upvalues */
lua_Object func; /* (f) function being executed */
/* private part */
lua_Object _func; /* active function */
};
struct lua_Dbglocvar {
int index;
const char *name;
lua_Object value;
};
#endif

6
lvm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.78 1999/12/30 18:28:40 roberto Exp roberto $
** $Id: lvm.c,v 1.79 2000/01/13 15:56:03 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -308,7 +308,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
register const Byte *pc = tf->code;
const TObject *consts = tf->consts;
if (L->callhook)
luaD_callHook(L, base-1, L->callhook, 0);
luaD_callHook(L, base-1, L->callhook, "call");
luaD_checkstack(L, (*pc++)+EXTRA_STACK);
if (*pc < ZEROVARARG)
luaD_adjusttop(L, base, *(pc++));
@ -617,7 +617,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
(base-2)->value.i = aux;
if (L->linehook) {
L->top = top;
luaD_lineHook(L, aux);
luaD_lineHook(L, base-3, aux);
}
break;