mirror of
https://github.com/lua/lua.git
synced 2025-01-28 06:03:00 +08:00
new interface for debug hooks
This commit is contained in:
parent
d2d24f0971
commit
39b2d58c39
89
ldblib.c
89
ldblib.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldblib.c,v 1.60 2002/06/18 17:42:52 roberto Exp roberto $
|
** $Id: ldblib.c,v 1.61 2002/06/25 19:16:44 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
|
||||||
*/
|
*/
|
||||||
@ -108,65 +108,70 @@ static int setlocal (lua_State *L) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char KEY_CALLHOOK = 'c';
|
static const char KEY_HOOK = 'h';
|
||||||
static const char KEY_LINEHOOK = 'l';
|
|
||||||
|
|
||||||
|
|
||||||
static void hookf (lua_State *L, void *key) {
|
static void hookf (lua_State *L, lua_Debug *ar) {
|
||||||
lua_pushudataval(L, key);
|
static const char *const hooknames[] = {"call", "return", "line", "count"};
|
||||||
|
lua_pushudataval(L, (void *)&KEY_HOOK);
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||||
if (lua_isfunction(L, -1)) {
|
if (lua_isfunction(L, -1)) {
|
||||||
lua_pushvalue(L, -2); /* original argument (below function) */
|
lua_pushstring(L, hooknames[(int)ar->event]);
|
||||||
lua_call(L, 1, 0);
|
if (ar->currentline >= 0) lua_pushnumber(L, ar->currentline);
|
||||||
|
else lua_pushnil(L);
|
||||||
|
lua_assert(lua_getinfo(L, "lS", ar));
|
||||||
|
lua_call(L, 2, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
lua_pop(L, 1); /* pop result from gettable */
|
lua_pop(L, 1); /* pop result from gettable */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void callf (lua_State *L, lua_Debug *ar) {
|
static int makemask (const char *smask, int count) {
|
||||||
lua_pushstring(L, ar->event);
|
int mask = 0;
|
||||||
lua_assert(lua_getinfo(L, "lS", ar) && ar->currentline == -1);
|
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
|
||||||
hookf(L, (void *)&KEY_CALLHOOK);
|
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
|
||||||
|
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
|
||||||
|
return mask | lua_maskcount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void linef (lua_State *L, lua_Debug *ar) {
|
static char *unmakemask (int mask, char *smask) {
|
||||||
lua_pushnumber(L, ar->currentline);
|
int i = 0;
|
||||||
lua_assert((ar->currentline = ar->linedefined = -1,
|
if (mask & LUA_MASKCALL) smask[i++] = 'c';
|
||||||
lua_getinfo(L, "lS", ar) &&
|
if (mask & LUA_MASKRET) smask[i++] = 'r';
|
||||||
ar->currentline == lua_tonumber(L, -1) &&
|
if (mask & LUA_MASKLINE) smask[i++] = 'l';
|
||||||
ar->linedefined >= 0));
|
smask[i] = '\0';
|
||||||
hookf(L, (void *)&KEY_LINEHOOK);
|
return smask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sethook (lua_State *L, void *key, lua_Hook hook,
|
static int sethook (lua_State *L) {
|
||||||
lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) {
|
if (lua_isnoneornil(L, 1)) {
|
||||||
lua_settop(L, 1);
|
lua_settop(L, 1);
|
||||||
if (lua_isnoneornil(L, 1))
|
lua_sethook(L, NULL, 0); /* turn off hooks */
|
||||||
(*sethookf)(L, NULL);
|
}
|
||||||
else if (lua_isfunction(L, 1))
|
else {
|
||||||
(*sethookf)(L, hook);
|
const char *smask = luaL_check_string(L, 2);
|
||||||
else
|
int count = luaL_opt_int(L, 3, 0);
|
||||||
luaL_argerror(L, 1, "function expected");
|
luaL_check_type(L, 1, LUA_TFUNCTION);
|
||||||
lua_pushudataval(L, key);
|
lua_sethook(L, hookf, makemask(smask, count));
|
||||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get old value */
|
}
|
||||||
lua_pushudataval(L, key);
|
lua_pushudataval(L, (void *)&KEY_HOOK);
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_rawset(L, LUA_REGISTRYINDEX); /* set new value */
|
lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int setcallhook (lua_State *L) {
|
static int gethook (lua_State *L) {
|
||||||
sethook(L, (void *)&KEY_CALLHOOK, callf, lua_setcallhook);
|
char buff[5];
|
||||||
return 1;
|
int mask = lua_gethookmask(L);
|
||||||
}
|
lua_pushudataval(L, (void *)&KEY_HOOK);
|
||||||
|
lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
|
||||||
|
lua_pushstring(L, unmakemask(mask, buff));
|
||||||
static int setlinehook (lua_State *L) {
|
lua_pushnumber(L, lua_getmaskcount(mask));
|
||||||
sethook(L, (void *)&KEY_LINEHOOK, linef, lua_setlinehook);
|
return 3;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -245,8 +250,8 @@ static int errorfb (lua_State *L) {
|
|||||||
static const luaL_reg dblib[] = {
|
static const luaL_reg dblib[] = {
|
||||||
{"getlocal", getlocal},
|
{"getlocal", getlocal},
|
||||||
{"getinfo", getinfo},
|
{"getinfo", getinfo},
|
||||||
{"setcallhook", setcallhook},
|
{"gethook", gethook},
|
||||||
{"setlinehook", setlinehook},
|
{"sethook", sethook},
|
||||||
{"setlocal", setlocal},
|
{"setlocal", setlocal},
|
||||||
{"debug", debug},
|
{"debug", debug},
|
||||||
{"traceback", errorfb},
|
{"traceback", errorfb},
|
||||||
|
41
ldebug.c
41
ldebug.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 1.122 2002/06/20 20:39:44 roberto Exp roberto $
|
** $Id: ldebug.c,v 1.123 2002/06/24 15:07:21 roberto Exp roberto $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -53,26 +53,31 @@ static int currentline (lua_State *L, CallInfo *ci) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
|
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) {
|
||||||
lua_Hook oldhook;
|
|
||||||
lua_lock(L);
|
|
||||||
oldhook = L->callhook;
|
|
||||||
L->callhook = func;
|
|
||||||
lua_unlock(L);
|
|
||||||
return oldhook;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
|
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
lua_Hook oldhook;
|
int allow;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
oldhook = L->linehook;
|
allow = allowhook(L);
|
||||||
L->linehook = func;
|
if (func == NULL) mask = 0;
|
||||||
|
else if (mask == 0) func = NULL;
|
||||||
|
L->hook = func;
|
||||||
|
L->hookmask = mask;
|
||||||
|
setallowhook(L, allow);
|
||||||
|
resethookcount(L);
|
||||||
for (ci = L->base_ci; ci <= L->ci; ci++)
|
for (ci = L->base_ci; ci <= L->ci; ci++)
|
||||||
currentpc(L, ci); /* update `savedpc' */
|
currentpc(L, ci); /* update `savedpc' */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return oldhook;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LUA_API lua_Hook lua_gethook (lua_State *L) {
|
||||||
|
return L->hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LUA_API int lua_gethookmask (lua_State *L) {
|
||||||
|
return L->hookmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -396,6 +401,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
|
|||||||
return pt->code[last];
|
return pt->code[last];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef check
|
||||||
|
#undef checkjump
|
||||||
|
#undef checkreg
|
||||||
|
|
||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
9
ldebug.h
9
ldebug.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.h,v 1.22 2002/06/18 15:19:27 roberto Exp roberto $
|
** $Id: ldebug.h,v 1.23 2002/06/24 15:07:21 roberto Exp roberto $
|
||||||
** Auxiliary functions from Debug Interface module
|
** Auxiliary functions from Debug Interface module
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -16,6 +16,13 @@
|
|||||||
|
|
||||||
#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
|
#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
|
||||||
|
|
||||||
|
#define resethookcount(L) \
|
||||||
|
(L->hookcount = (1 << lua_getmaskcount(L->hookmask)) >> 1)
|
||||||
|
|
||||||
|
#define setallowhook(L,cond) ((L->hookmask) = ((L->hookmask) & ~1) | (cond))
|
||||||
|
#define allowhook(L) ((L->hookmask) & 1)
|
||||||
|
|
||||||
|
|
||||||
void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
|
void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
|
||||||
void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
|
void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
|
||||||
void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
|
void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
|
||||||
|
67
ldo.c
67
ldo.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 1.184 2002/06/26 16:37:23 roberto Exp roberto $
|
** $Id: ldo.c,v 1.185 2002/07/04 12:29:32 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
|
||||||
*/
|
*/
|
||||||
@ -135,40 +135,29 @@ static void luaD_openstack (lua_State *L, StkId pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
|
void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
|
||||||
ptrdiff_t top = savestack(L, L->top);
|
lua_Hook hook = L->hook;
|
||||||
ptrdiff_t ci_top = savestack(L, L->ci->top);
|
if (hook && allowhook(L)) {
|
||||||
ar->i_ci = L->ci - L->base_ci;
|
ptrdiff_t top = savestack(L, L->top);
|
||||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
ptrdiff_t ci_top = savestack(L, L->ci->top);
|
||||||
L->ci->top = L->top + LUA_MINSTACK;
|
|
||||||
L->allowhooks = 0; /* cannot call hooks inside a hook */
|
|
||||||
lua_unlock(L);
|
|
||||||
(*hook)(L, ar);
|
|
||||||
lua_lock(L);
|
|
||||||
lua_assert(L->allowhooks == 0);
|
|
||||||
L->allowhooks = 1;
|
|
||||||
L->ci->top = restorestack(L, ci_top);
|
|
||||||
L->top = restorestack(L, top);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaD_lineHook (lua_State *L, int line) {
|
|
||||||
if (L->allowhooks) {
|
|
||||||
lua_Debug ar;
|
|
||||||
ar.event = "line";
|
|
||||||
ar.currentline = line;
|
|
||||||
dohook(L, &ar, L->linehook);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
|
|
||||||
if (L->allowhooks) {
|
|
||||||
lua_Debug ar;
|
lua_Debug ar;
|
||||||
ar.event = event;
|
ar.event = event;
|
||||||
L->ci->pc = NULL; /* function is not active */
|
ar.currentline = line;
|
||||||
L->ci->top = L->ci->base; /* `top' may not have a valid value yet */
|
ar.i_ci = L->ci - L->base_ci;
|
||||||
dohook(L, &ar, callhook);
|
if (event <= LUA_HOOKRET) { /* `call' or `return' event? */
|
||||||
|
L->ci->pc = NULL; /* function is not active */
|
||||||
|
L->ci->top = L->ci->base; /* `top' may not have a valid value yet */
|
||||||
|
}
|
||||||
|
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
|
L->ci->top = L->top + LUA_MINSTACK;
|
||||||
|
setallowhook(L, 0); /* cannot call hooks inside a hook */
|
||||||
|
lua_unlock(L);
|
||||||
|
(*hook)(L, &ar);
|
||||||
|
lua_lock(L);
|
||||||
|
lua_assert(!allowhook(L));
|
||||||
|
setallowhook(L, 1);
|
||||||
|
L->ci->top = restorestack(L, ci_top);
|
||||||
|
L->top = restorestack(L, top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,8 +208,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
|
|||||||
if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
|
if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
|
||||||
func = tryfuncTM(L, func); /* check the `function' tag method */
|
func = tryfuncTM(L, func); /* check the `function' tag method */
|
||||||
cl = &clvalue(func)->l;
|
cl = &clvalue(func)->l;
|
||||||
if (L->callhook) {
|
if (L->hookmask & LUA_MASKCALL) {
|
||||||
luaD_callHook(L, L->callhook, "call");
|
luaD_callhook(L, LUA_HOOKCALL, -1);
|
||||||
ci = L->ci; /* previous call may realocate `ci' */
|
ci = L->ci; /* previous call may realocate `ci' */
|
||||||
}
|
}
|
||||||
if (!cl->isC) { /* Lua function? prepare its call */
|
if (!cl->isC) { /* Lua function? prepare its call */
|
||||||
@ -252,9 +241,9 @@ StkId luaD_precall (lua_State *L, StkId func) {
|
|||||||
|
|
||||||
void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
|
void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
|
||||||
StkId res;
|
StkId res;
|
||||||
if (L->callhook) {
|
if (L->hookmask & LUA_MASKRET) {
|
||||||
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
|
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
|
||||||
luaD_callHook(L, L->callhook, "return");
|
luaD_callhook(L, LUA_HOOKRET, -1);
|
||||||
firstResult = restorestack(L, fr);
|
firstResult = restorestack(L, fr);
|
||||||
}
|
}
|
||||||
res = L->ci->base - 1; /* res == final position of 1st result */
|
res = L->ci->base - 1; /* res == final position of 1st result */
|
||||||
@ -483,7 +472,7 @@ int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) {
|
|||||||
struct lua_longjmp lj;
|
struct lua_longjmp lj;
|
||||||
lj.ci = L->ci;
|
lj.ci = L->ci;
|
||||||
lj.top = L->top;
|
lj.top = L->top;
|
||||||
lj.allowhooks = L->allowhooks;
|
lj.allowhooks = allowhook(L);
|
||||||
lj.status = 0;
|
lj.status = 0;
|
||||||
lj.err = ud;
|
lj.err = ud;
|
||||||
lj.previous = L->errorJmp; /* chain new error handler */
|
lj.previous = L->errorJmp; /* chain new error handler */
|
||||||
@ -493,7 +482,7 @@ int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) {
|
|||||||
else { /* an error occurred */
|
else { /* an error occurred */
|
||||||
L->ci = lj.ci; /* restore the state */
|
L->ci = lj.ci; /* restore the state */
|
||||||
L->top = lj.top;
|
L->top = lj.top;
|
||||||
L->allowhooks = lj.allowhooks;
|
setallowhook(L, lj.allowhooks);
|
||||||
restore_stack_limit(L);
|
restore_stack_limit(L);
|
||||||
}
|
}
|
||||||
L->errorJmp = lj.previous; /* restore old error handler */
|
L->errorJmp = lj.previous; /* restore old error handler */
|
||||||
|
4
ldo.h
4
ldo.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 1.46 2002/06/18 15:19:27 roberto Exp roberto $
|
** $Id: ldo.h,v 1.47 2002/06/18 17:10:43 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
|
||||||
*/
|
*/
|
||||||
@ -32,7 +32,7 @@
|
|||||||
typedef void (*Pfunc) (lua_State *L, void *v);
|
typedef void (*Pfunc) (lua_State *L, void *v);
|
||||||
|
|
||||||
int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
|
int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
|
||||||
void luaD_lineHook (lua_State *L, int line);
|
void luaD_callhook (lua_State *L, lua_Hookevent event, int line);
|
||||||
StkId luaD_precall (lua_State *L, StkId func);
|
StkId luaD_precall (lua_State *L, StkId func);
|
||||||
void luaD_call (lua_State *L, StkId func, int nResults);
|
void luaD_call (lua_State *L, StkId func, int nResults);
|
||||||
int luaD_pcall (lua_State *L, int nargs, int nresults);
|
int luaD_pcall (lua_State *L, int nargs, int nresults);
|
||||||
|
8
lgc.c
8
lgc.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.140 2002/07/01 17:06:58 roberto Exp roberto $
|
** $Id: lgc.c,v 1.141 2002/07/04 17:57:42 roberto Exp $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -451,8 +451,8 @@ static void do1gcTM (lua_State *L, Udata *udata) {
|
|||||||
|
|
||||||
|
|
||||||
static void callGCTM (lua_State *L) {
|
static void callGCTM (lua_State *L) {
|
||||||
int oldah = L->allowhooks;
|
int oldah = allowhook(L);
|
||||||
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
|
setallowhook(L, 0); /* stop debug hooks during GC tag methods */
|
||||||
L->top++; /* reserve space to keep udata while runs its gc method */
|
L->top++; /* reserve space to keep udata while runs its gc method */
|
||||||
while (G(L)->tmudata != NULL) {
|
while (G(L)->tmudata != NULL) {
|
||||||
Udata *udata = G(L)->tmudata;
|
Udata *udata = G(L)->tmudata;
|
||||||
@ -465,7 +465,7 @@ static void callGCTM (lua_State *L) {
|
|||||||
do1gcTM(L, udata);
|
do1gcTM(L, udata);
|
||||||
}
|
}
|
||||||
L->top--;
|
L->top--;
|
||||||
L->allowhooks = oldah; /* restore hooks */
|
setallowhook(L, oldah); /* restore hooks */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
9
lstate.c
9
lstate.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 1.96 2002/06/06 18:17:33 roberto Exp roberto $
|
** $Id: lstate.c,v 1.97 2002/06/18 15:19:27 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -92,12 +92,13 @@ static void preinit_state (lua_State *L) {
|
|||||||
L->stack = NULL;
|
L->stack = NULL;
|
||||||
L->stacksize = 0;
|
L->stacksize = 0;
|
||||||
L->errorJmp = NULL;
|
L->errorJmp = NULL;
|
||||||
L->callhook = NULL;
|
L->hook = NULL;
|
||||||
L->linehook = NULL;
|
L->hookmask = 0;
|
||||||
|
setallowhook(L, 1);
|
||||||
|
resethookcount(L);
|
||||||
L->openupval = NULL;
|
L->openupval = NULL;
|
||||||
L->size_ci = 0;
|
L->size_ci = 0;
|
||||||
L->base_ci = NULL;
|
L->base_ci = NULL;
|
||||||
L->allowhooks = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
8
lstate.h
8
lstate.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 1.85 2002/05/08 17:34:23 roberto Exp roberto $
|
** $Id: lstate.h,v 1.86 2002/07/02 16:43:28 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -130,8 +130,9 @@ struct lua_State {
|
|||||||
CallInfo *end_ci; /* points after end of ci array*/
|
CallInfo *end_ci; /* points after end of ci array*/
|
||||||
CallInfo *base_ci; /* array of CallInfo's */
|
CallInfo *base_ci; /* array of CallInfo's */
|
||||||
global_State *l_G;
|
global_State *l_G;
|
||||||
lua_Hook linehook;
|
int hookmask;
|
||||||
lua_Hook callhook;
|
int hookcount;
|
||||||
|
lua_Hook hook;
|
||||||
TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */
|
TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
UpVal *openupval; /* list of open upvalues in this stack */
|
UpVal *openupval; /* list of open upvalues in this stack */
|
||||||
@ -139,7 +140,6 @@ struct lua_State {
|
|||||||
lua_State *previous;
|
lua_State *previous;
|
||||||
int stacksize;
|
int stacksize;
|
||||||
int size_ci; /* size of array `base_ci' */
|
int size_ci; /* size of array `base_ci' */
|
||||||
int allowhooks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
21
luadebug.h
21
luadebug.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: luadebug.h,v 1.27 2002/04/04 17:21:31 roberto Exp roberto $
|
** $Id: luadebug.h,v 1.28 2002/06/18 17:10:43 roberto Exp roberto $
|
||||||
** Debugging API
|
** Debugging API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -11,6 +11,18 @@
|
|||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
typedef enum lua_Hookevent {
|
||||||
|
LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKLINE, LUA_HOOKCOUNT
|
||||||
|
} lua_Hookevent;
|
||||||
|
|
||||||
|
|
||||||
|
#define LUA_MASKCALL (2 << LUA_HOOKCALL)
|
||||||
|
#define LUA_MASKRET (2 << LUA_HOOKRET)
|
||||||
|
#define LUA_MASKLINE (2 << LUA_HOOKLINE)
|
||||||
|
#define lua_maskcount(count) ((count) << (LUA_HOOKCOUNT+1))
|
||||||
|
#define lua_getmaskcount(mask) ((mask) >> (LUA_HOOKCOUNT+1))
|
||||||
|
#define LUA_MASKCOUNT (lua_maskcount(1))
|
||||||
|
|
||||||
typedef struct lua_Debug lua_Debug; /* activation record */
|
typedef struct lua_Debug lua_Debug; /* activation record */
|
||||||
|
|
||||||
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
||||||
@ -21,14 +33,15 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
|||||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||||
|
|
||||||
LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
|
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask);
|
||||||
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
|
LUA_API lua_Hook lua_gethook (lua_State *L);
|
||||||
|
LUA_API int lua_gethookmask (lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
#define LUA_IDSIZE 60
|
#define LUA_IDSIZE 60
|
||||||
|
|
||||||
struct lua_Debug {
|
struct lua_Debug {
|
||||||
const char *event; /* `call', `return', `line' */
|
lua_Hookevent event;
|
||||||
const char *name; /* (n) */
|
const char *name; /* (n) */
|
||||||
const char *namewhat; /* (n) `global', `local', `field', `method' */
|
const char *namewhat; /* (n) `global', `local', `field', `method' */
|
||||||
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
|
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
|
||||||
|
38
lvm.c
38
lvm.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 1.243 2002/06/24 15:07:21 roberto Exp roberto $
|
** $Id: lvm.c,v 1.244 2002/07/05 18:27:39 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -69,17 +69,28 @@ int luaV_tostring (lua_State *L, TObject *obj) {
|
|||||||
|
|
||||||
|
|
||||||
static void traceexec (lua_State *L) {
|
static void traceexec (lua_State *L) {
|
||||||
CallInfo *ci = L->ci;
|
int mask = L->hookmask;
|
||||||
Proto *p = ci_func(ci)->l.p;
|
if (mask >= LUA_MASKCOUNT) { /* instruction hook set? */
|
||||||
int newline = getline(p, pcRel(*ci->pc, p));
|
if (L->hookcount == 0) {
|
||||||
if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */
|
luaD_callhook(L, LUA_HOOKCOUNT, -1);
|
||||||
ci->savedpc = *ci->pc; /* initialize `savedpc' */
|
resethookcount(L);
|
||||||
/* calls linehook when enters a new line or jumps back (loop) */
|
return;
|
||||||
if (*ci->pc <= ci->savedpc || newline != getline(p, pcRel(ci->savedpc, p))) {
|
}
|
||||||
luaD_lineHook(L, newline);
|
}
|
||||||
ci = L->ci; /* previous call may reallocate `ci' */
|
if (mask & LUA_MASKLINE) {
|
||||||
|
CallInfo *ci = L->ci;
|
||||||
|
Proto *p = ci_func(ci)->l.p;
|
||||||
|
int newline = getline(p, pcRel(*ci->pc, p));
|
||||||
|
if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */
|
||||||
|
ci->savedpc = *ci->pc; /* initialize `savedpc' */
|
||||||
|
/* calls linehook when enters a new line or jumps back (loop) */
|
||||||
|
if (*ci->pc <= ci->savedpc ||
|
||||||
|
newline != getline(p, pcRel(ci->savedpc, p))) {
|
||||||
|
luaD_callhook(L, LUA_HOOKLINE, newline);
|
||||||
|
ci = L->ci; /* previous call may reallocate `ci' */
|
||||||
|
}
|
||||||
|
ci->savedpc = *ci->pc;
|
||||||
}
|
}
|
||||||
ci->savedpc = *ci->pc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -370,8 +381,9 @@ StkId luaV_execute (lua_State *L) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
const Instruction i = *pc++;
|
const Instruction i = *pc++;
|
||||||
StkId ra;
|
StkId ra;
|
||||||
if (L->linehook)
|
if (L->hookmask >= LUA_MASKLINE &&
|
||||||
traceexec(L);
|
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE))
|
||||||
|
traceexec(L);
|
||||||
ra = RA(i);
|
ra = RA(i);
|
||||||
lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base);
|
lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base);
|
||||||
lua_assert(L->top == L->ci->top ||
|
lua_assert(L->top == L->ci->top ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user