mirror of
https://github.com/lua/lua
synced 2024-12-24 03:16:50 +03:00
new representation for hooks (to allow asynchronous calls to sethook)
This commit is contained in:
parent
94912d99fc
commit
43013b39cc
35
ldebug.c
35
ldebug.c
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
8
ldebug.h
8
ldebug.h
@ -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
20
ldo.c
@ -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
8
lgc.c
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
7
lstate.c
7
lstate.c
@ -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;
|
||||
|
7
lstate.h
7
lstate.h
@ -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
10
lua.h
@ -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
8
lvm.c
@ -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' */
|
||||
|
Loading…
Reference in New Issue
Block a user