new representation for hooks (to allow asynchronous calls to sethook)

This commit is contained in:
Roberto Ierusalimschy 2002-11-18 09:01:55 -02:00
parent 94912d99fc
commit 43013b39cc
8 changed files with 59 additions and 44 deletions

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.135 2002/10/16 20:40:58 roberto Exp roberto $
** $Id: ldebug.c,v 1.136 2002/11/07 15:37:10 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -49,20 +49,29 @@ static int currentline (CallInfo *ci) {
}
LUA_API int lua_sethook (lua_State *L, lua_Hook func, unsigned long mask) {
int allow;
void luaG_inithooks (lua_State *L) {
CallInfo *ci;
lua_lock(L);
allow = allowhook(L);
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->ci; ci != L->base_ci; ci--) /* update all `savedpc's */
currentpc(ci);
lua_unlock(L);
L->hookinit = 1;
}
/*
** this function can be called asynchronous (e.g. during a signal)
*/
LUA_API int lua_sethook (lua_State *L, lua_Hook func, unsigned long mask) {
ls_count count = lua_getmaskcount(mask);
if (func == NULL || mask == 0) { /* turn off hooks? */
mask = 0;
func = NULL;
}
else if (count > 0) mask |= (1<<LUA_HOOKCOUNT);
L->hook = func;
L->basehookcount = count;
resethookcount(L);
L->hookmask = cast(lu_byte, mask & 0xf);
L->hookinit = 0;
return 1;
}
@ -73,7 +82,7 @@ LUA_API lua_Hook lua_gethook (lua_State *L) {
LUA_API unsigned long lua_gethookmask (lua_State *L) {
return L->hookmask;
return L->hookmask | LUA_MASKCOUNT(L->basehookcount);
}

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 1.30 2002/08/12 17:23:12 roberto Exp roberto $
** $Id: ldebug.h,v 1.31 2002/08/20 20:03:05 roberto Exp roberto $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@ -15,12 +15,10 @@
#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
#define resethookcount(L) (L->hookcount = lua_getmaskcount(L->hookmask))
#define setallowhook(L,cond) ((L->hookmask) = ((L->hookmask) & ~1) | (cond))
#define allowhook(L) ((L->hookmask) & 1)
#define resethookcount(L) (L->hookcount = L->basehookcount)
void luaG_inithooks (lua_State *L);
void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);

20
ldo.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.200 2002/11/13 11:31:39 roberto Exp roberto $
** $Id: ldo.c,v 1.201 2002/11/14 16:15:53 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -154,7 +154,7 @@ static void luaD_growCI (lua_State *L) {
void luaD_callhook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && allowhook(L)) {
if (hook && L->allowhook) {
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, L->ci->top);
lua_Debug ar;
@ -163,12 +163,12 @@ void luaD_callhook (lua_State *L, int event, int line) {
ar.i_ci = L->ci - L->base_ci;
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 */
L->allowhook = 0; /* cannot call hooks inside a hook */
lua_unlock(L);
(*hook)(L, &ar);
lua_lock(L);
lua_assert(!allowhook(L));
setallowhook(L, 1);
lua_assert(!L->allowhook);
L->allowhook = 1;
L->ci->top = restorestack(L, ci_top);
L->top = restorestack(L, top);
}
@ -328,16 +328,16 @@ static void resume (lua_State *L, void *ud) {
LUA_API int lua_resume (lua_State *L, int nargs) {
int status;
int old_allowhooks;
lu_byte old_allowhooks;
lua_lock(L);
old_allowhooks = allowhook(L);
old_allowhooks = L->allowhook;
lua_assert(L->errfunc == 0);
status = luaD_rawrunprotected(L, resume, &nargs);
if (status != 0) { /* error? */
L->ci = L->base_ci; /* go back to initial level */
luaF_close(L, L->ci->base); /* close eventual pending closures */
seterrorobj(L, status, L->ci->base);
setallowhook(L, old_allowhooks);
L->allowhook = old_allowhooks;
restore_stack_limit(L);
}
lua_unlock(L);
@ -383,7 +383,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) {
int status;
ptrdiff_t old_top = savestack(L, L->top);
ptrdiff_t old_ci = saveci(L, L->ci);
int old_allowhooks = allowhook(L);
lu_byte old_allowhooks = L->allowhook;
ptrdiff_t old_errfunc = L->errfunc;
L->errfunc = errfunc;
c.func = L->top - (nargs+1); /* function to be called */
@ -394,7 +394,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) {
luaF_close(L, oldtop); /* close eventual pending closures */
seterrorobj(L, status, oldtop);
L->ci = restoreci(L, old_ci);
setallowhook(L, old_allowhooks);
L->allowhook = old_allowhooks;
restore_stack_limit(L);
}
L->errfunc = old_errfunc;

8
lgc.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.157 2002/11/13 11:49:19 roberto Exp roberto $
** $Id: lgc.c,v 1.158 2002/11/14 11:51:50 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -404,8 +404,8 @@ static void do1gcTM (lua_State *L, Udata *udata) {
static void callGCTM (lua_State *L) {
int oldah = allowhook(L);
setallowhook(L, 0); /* stop debug hooks during GC tag methods */
lu_byte oldah = L->allowhook;
L->allowhook = 0; /* stop debug hooks during GC tag methods */
L->top++; /* reserve space to keep udata while runs its gc method */
while (G(L)->tmudata != NULL) {
GCObject *o = G(L)->tmudata;
@ -419,7 +419,7 @@ static void callGCTM (lua_State *L) {
do1gcTM(L, udata);
}
L->top--;
setallowhook(L, oldah); /* restore hooks */
L->allowhook = oldah; /* restore hooks */
}

View File

@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 1.110 2002/11/13 11:31:39 roberto Exp roberto $
** $Id: lstate.c,v 1.111 2002/11/14 16:15:53 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@ -112,8 +112,9 @@ static void preinit_state (lua_State *L) {
L->stacksize = 0;
L->errorJmp = NULL;
L->hook = NULL;
L->hookmask = 0;
setallowhook(L, 1);
L->hookmask = L->hookinit = 0;
L->basehookcount = 0;
L->allowhook = 1;
resethookcount(L);
L->openupval = NULL;
L->size_ci = 0;

View File

@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.100 2002/11/06 19:08:00 roberto Exp roberto $
** $Id: lstate.h,v 1.101 2002/11/13 11:31:39 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@ -139,7 +139,10 @@ struct lua_State {
CallInfo *end_ci; /* points after end of ci array*/
CallInfo *base_ci; /* array of CallInfo's */
int size_ci; /* size of array `base_ci' */
unsigned long hookmask;
lu_byte hookmask;
lu_byte allowhook;
lu_byte hookinit;
ls_count basehookcount;
ls_count hookcount;
lua_Hook hook;
TObject _gt; /* table of globals */

10
lua.h
View File

@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.163 2002/11/07 15:39:23 roberto Exp roberto $
** $Id: lua.h,v 1.164 2002/11/14 11:51:50 roberto Exp roberto $
** Lua - An Extensible Extension Language
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
** http://www.lua.org mailto:info@lua.org
@ -327,13 +327,13 @@ LUA_API int lua_pushupvalues (lua_State *L);
/*
** Event masks
*/
#define LUA_MASKCALL (2 << LUA_HOOKCALL)
#define LUA_MASKRET (2 << LUA_HOOKRET)
#define LUA_MASKLINE (2 << LUA_HOOKLINE)
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
#define LUA_MASKRET (1 << LUA_HOOKRET)
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
#define LUA_MASKCOUNT(count) ((unsigned long)(count) << 8)
#define lua_getmaskcount(mask) ((mask) >> 8)
#define LUA_MAXCOUNT ((1<<24) - 1)
#define LUA_MAXCOUNT ((~(unsigned long)0) >> 8)
typedef struct lua_Debug lua_Debug; /* activation record */

8
lvm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.260 2002/11/07 15:37:10 roberto Exp roberto $
** $Id: lvm.c,v 1.261 2002/11/14 16:15:53 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -70,7 +70,7 @@ int luaV_tostring (lua_State *L, StkId obj) {
static void traceexec (lua_State *L) {
unsigned long mask = L->hookmask;
lu_byte mask = L->hookmask;
if (mask > LUA_MASKLINE) { /* instruction-hook set? */
if (L->hookcount == 0) {
luaD_callhook(L, LUA_HOOKCOUNT, -1);
@ -82,6 +82,10 @@ static void traceexec (lua_State *L) {
CallInfo *ci = L->ci;
Proto *p = ci_func(ci)->l.p;
int newline = getline(p, pcRel(*ci->u.l.pc, p));
if (!L->hookinit) {
luaG_inithooks(L);
return;
}
lua_assert(ci->state & CI_HASFRAME);
if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */