mirror of
https://github.com/lua/lua
synced 2024-11-29 08:03:13 +03:00
new debug API (first version)
This commit is contained in:
parent
27163f032e
commit
2877bad4c2
32
lapi.c
32
lapi.c
@ -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
8
lapi.h
@ -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);
|
||||
|
16
lauxlib.c
16
lauxlib.c
@ -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
155
ldblib.c
@ -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
213
ldebug.c
@ -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
43
ldo.c
@ -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
8
ldo.h
@ -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);
|
||||
|
48
liolib.c
48
liolib.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
6
lstate.h
6
lstate.h
@ -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;
|
||||
};
|
||||
|
||||
|
6
ltests.c
6
ltests.c
@ -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
4
ltm.c
@ -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)) {
|
||||
|
49
luadebug.h
49
luadebug.h
@ -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
6
lvm.c
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user