diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-18 09:01:55 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-18 09:01:55 -0200 |
commit | 43013b39cc28e873e18207e8e7259b6b90fed06b (patch) | |
tree | 3c2a9c520a01086df28c8f0d1ef6d9b5069fa451 | |
parent | 94912d99fcdf61c1fc6dc8897c9d2b0e042e0d63 (diff) | |
download | lua-43013b39cc28e873e18207e8e7259b6b90fed06b.tar.gz lua-43013b39cc28e873e18207e8e7259b6b90fed06b.tar.bz2 lua-43013b39cc28e873e18207e8e7259b6b90fed06b.zip |
new representation for hooks (to allow asynchronous calls to sethook)
-rw-r--r-- | ldebug.c | 35 | ||||
-rw-r--r-- | ldebug.h | 8 | ||||
-rw-r--r-- | ldo.c | 20 | ||||
-rw-r--r-- | lgc.c | 8 | ||||
-rw-r--r-- | lstate.c | 7 | ||||
-rw-r--r-- | lstate.h | 7 | ||||
-rw-r--r-- | lua.h | 10 | ||||
-rw-r--r-- | lvm.c | 8 |
8 files changed, 59 insertions, 44 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.135 2002/10/16 20:40:58 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.136 2002/11/07 15:37:10 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -49,20 +49,29 @@ static int currentline (CallInfo *ci) { | |||
49 | } | 49 | } |
50 | 50 | ||
51 | 51 | ||
52 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, unsigned long mask) { | 52 | void luaG_inithooks (lua_State *L) { |
53 | int allow; | ||
54 | CallInfo *ci; | 53 | CallInfo *ci; |
55 | lua_lock(L); | ||
56 | allow = allowhook(L); | ||
57 | if (func == NULL) mask = 0; | ||
58 | else if (mask == 0) func = NULL; | ||
59 | L->hook = func; | ||
60 | L->hookmask = mask; | ||
61 | setallowhook(L, allow); | ||
62 | resethookcount(L); | ||
63 | for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */ | 54 | for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */ |
64 | currentpc(ci); | 55 | currentpc(ci); |
65 | lua_unlock(L); | 56 | L->hookinit = 1; |
57 | } | ||
58 | |||
59 | |||
60 | /* | ||
61 | ** this function can be called asynchronous (e.g. during a signal) | ||
62 | */ | ||
63 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, unsigned long mask) { | ||
64 | ls_count count = lua_getmaskcount(mask); | ||
65 | if (func == NULL || mask == 0) { /* turn off hooks? */ | ||
66 | mask = 0; | ||
67 | func = NULL; | ||
68 | } | ||
69 | else if (count > 0) mask |= (1<<LUA_HOOKCOUNT); | ||
70 | L->hook = func; | ||
71 | L->basehookcount = count; | ||
72 | resethookcount(L); | ||
73 | L->hookmask = cast(lu_byte, mask & 0xf); | ||
74 | L->hookinit = 0; | ||
66 | return 1; | 75 | return 1; |
67 | } | 76 | } |
68 | 77 | ||
@@ -73,7 +82,7 @@ LUA_API lua_Hook lua_gethook (lua_State *L) { | |||
73 | 82 | ||
74 | 83 | ||
75 | LUA_API unsigned long lua_gethookmask (lua_State *L) { | 84 | LUA_API unsigned long lua_gethookmask (lua_State *L) { |
76 | return L->hookmask; | 85 | return L->hookmask | LUA_MASKCOUNT(L->basehookcount); |
77 | } | 86 | } |
78 | 87 | ||
79 | 88 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.h,v 1.30 2002/08/12 17:23:12 roberto Exp roberto $ | 2 | ** $Id: ldebug.h,v 1.31 2002/08/20 20:03:05 roberto Exp roberto $ |
3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -15,12 +15,10 @@ | |||
15 | 15 | ||
16 | #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) | 16 | #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) |
17 | 17 | ||
18 | #define resethookcount(L) (L->hookcount = lua_getmaskcount(L->hookmask)) | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) |
19 | |||
20 | #define setallowhook(L,cond) ((L->hookmask) = ((L->hookmask) & ~1) | (cond)) | ||
21 | #define allowhook(L) ((L->hookmask) & 1) | ||
22 | 19 | ||
23 | 20 | ||
21 | void luaG_inithooks (lua_State *L); | ||
24 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); | 22 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); |
25 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); | 23 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); |
26 | void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); | 24 | void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.200 2002/11/13 11:31:39 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.201 2002/11/14 16:15:53 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -154,7 +154,7 @@ static void luaD_growCI (lua_State *L) { | |||
154 | 154 | ||
155 | void luaD_callhook (lua_State *L, int event, int line) { | 155 | void luaD_callhook (lua_State *L, int event, int line) { |
156 | lua_Hook hook = L->hook; | 156 | lua_Hook hook = L->hook; |
157 | if (hook && allowhook(L)) { | 157 | if (hook && L->allowhook) { |
158 | ptrdiff_t top = savestack(L, L->top); | 158 | ptrdiff_t top = savestack(L, L->top); |
159 | ptrdiff_t ci_top = savestack(L, L->ci->top); | 159 | ptrdiff_t ci_top = savestack(L, L->ci->top); |
160 | lua_Debug ar; | 160 | lua_Debug ar; |
@@ -163,12 +163,12 @@ void luaD_callhook (lua_State *L, int event, int line) { | |||
163 | ar.i_ci = L->ci - L->base_ci; | 163 | ar.i_ci = L->ci - L->base_ci; |
164 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 164 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
165 | L->ci->top = L->top + LUA_MINSTACK; | 165 | L->ci->top = L->top + LUA_MINSTACK; |
166 | setallowhook(L, 0); /* cannot call hooks inside a hook */ | 166 | L->allowhook = 0; /* cannot call hooks inside a hook */ |
167 | lua_unlock(L); | 167 | lua_unlock(L); |
168 | (*hook)(L, &ar); | 168 | (*hook)(L, &ar); |
169 | lua_lock(L); | 169 | lua_lock(L); |
170 | lua_assert(!allowhook(L)); | 170 | lua_assert(!L->allowhook); |
171 | setallowhook(L, 1); | 171 | L->allowhook = 1; |
172 | L->ci->top = restorestack(L, ci_top); | 172 | L->ci->top = restorestack(L, ci_top); |
173 | L->top = restorestack(L, top); | 173 | L->top = restorestack(L, top); |
174 | } | 174 | } |
@@ -328,16 +328,16 @@ static void resume (lua_State *L, void *ud) { | |||
328 | 328 | ||
329 | LUA_API int lua_resume (lua_State *L, int nargs) { | 329 | LUA_API int lua_resume (lua_State *L, int nargs) { |
330 | int status; | 330 | int status; |
331 | int old_allowhooks; | 331 | lu_byte old_allowhooks; |
332 | lua_lock(L); | 332 | lua_lock(L); |
333 | old_allowhooks = allowhook(L); | 333 | old_allowhooks = L->allowhook; |
334 | lua_assert(L->errfunc == 0); | 334 | lua_assert(L->errfunc == 0); |
335 | status = luaD_rawrunprotected(L, resume, &nargs); | 335 | status = luaD_rawrunprotected(L, resume, &nargs); |
336 | if (status != 0) { /* error? */ | 336 | if (status != 0) { /* error? */ |
337 | L->ci = L->base_ci; /* go back to initial level */ | 337 | L->ci = L->base_ci; /* go back to initial level */ |
338 | luaF_close(L, L->ci->base); /* close eventual pending closures */ | 338 | luaF_close(L, L->ci->base); /* close eventual pending closures */ |
339 | seterrorobj(L, status, L->ci->base); | 339 | seterrorobj(L, status, L->ci->base); |
340 | setallowhook(L, old_allowhooks); | 340 | L->allowhook = old_allowhooks; |
341 | restore_stack_limit(L); | 341 | restore_stack_limit(L); |
342 | } | 342 | } |
343 | lua_unlock(L); | 343 | lua_unlock(L); |
@@ -383,7 +383,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { | |||
383 | int status; | 383 | int status; |
384 | ptrdiff_t old_top = savestack(L, L->top); | 384 | ptrdiff_t old_top = savestack(L, L->top); |
385 | ptrdiff_t old_ci = saveci(L, L->ci); | 385 | ptrdiff_t old_ci = saveci(L, L->ci); |
386 | int old_allowhooks = allowhook(L); | 386 | lu_byte old_allowhooks = L->allowhook; |
387 | ptrdiff_t old_errfunc = L->errfunc; | 387 | ptrdiff_t old_errfunc = L->errfunc; |
388 | L->errfunc = errfunc; | 388 | L->errfunc = errfunc; |
389 | c.func = L->top - (nargs+1); /* function to be called */ | 389 | 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) { | |||
394 | luaF_close(L, oldtop); /* close eventual pending closures */ | 394 | luaF_close(L, oldtop); /* close eventual pending closures */ |
395 | seterrorobj(L, status, oldtop); | 395 | seterrorobj(L, status, oldtop); |
396 | L->ci = restoreci(L, old_ci); | 396 | L->ci = restoreci(L, old_ci); |
397 | setallowhook(L, old_allowhooks); | 397 | L->allowhook = old_allowhooks; |
398 | restore_stack_limit(L); | 398 | restore_stack_limit(L); |
399 | } | 399 | } |
400 | L->errfunc = old_errfunc; | 400 | L->errfunc = old_errfunc; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.157 2002/11/13 11:49:19 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.158 2002/11/14 11:51:50 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -404,8 +404,8 @@ static void do1gcTM (lua_State *L, Udata *udata) { | |||
404 | 404 | ||
405 | 405 | ||
406 | static void callGCTM (lua_State *L) { | 406 | static void callGCTM (lua_State *L) { |
407 | int oldah = allowhook(L); | 407 | lu_byte oldah = L->allowhook; |
408 | setallowhook(L, 0); /* stop debug hooks during GC tag methods */ | 408 | L->allowhook = 0; /* stop debug hooks during GC tag methods */ |
409 | L->top++; /* reserve space to keep udata while runs its gc method */ | 409 | L->top++; /* reserve space to keep udata while runs its gc method */ |
410 | while (G(L)->tmudata != NULL) { | 410 | while (G(L)->tmudata != NULL) { |
411 | GCObject *o = G(L)->tmudata; | 411 | GCObject *o = G(L)->tmudata; |
@@ -419,7 +419,7 @@ static void callGCTM (lua_State *L) { | |||
419 | do1gcTM(L, udata); | 419 | do1gcTM(L, udata); |
420 | } | 420 | } |
421 | L->top--; | 421 | L->top--; |
422 | setallowhook(L, oldah); /* restore hooks */ | 422 | L->allowhook = oldah; /* restore hooks */ |
423 | } | 423 | } |
424 | 424 | ||
425 | 425 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 1.110 2002/11/13 11:31:39 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.111 2002/11/14 16:15:53 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -112,8 +112,9 @@ static void preinit_state (lua_State *L) { | |||
112 | L->stacksize = 0; | 112 | L->stacksize = 0; |
113 | L->errorJmp = NULL; | 113 | L->errorJmp = NULL; |
114 | L->hook = NULL; | 114 | L->hook = NULL; |
115 | L->hookmask = 0; | 115 | L->hookmask = L->hookinit = 0; |
116 | setallowhook(L, 1); | 116 | L->basehookcount = 0; |
117 | L->allowhook = 1; | ||
117 | resethookcount(L); | 118 | resethookcount(L); |
118 | L->openupval = NULL; | 119 | L->openupval = NULL; |
119 | L->size_ci = 0; | 120 | L->size_ci = 0; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.100 2002/11/06 19:08:00 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.101 2002/11/13 11:31:39 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -139,7 +139,10 @@ struct lua_State { | |||
139 | CallInfo *end_ci; /* points after end of ci array*/ | 139 | CallInfo *end_ci; /* points after end of ci array*/ |
140 | CallInfo *base_ci; /* array of CallInfo's */ | 140 | CallInfo *base_ci; /* array of CallInfo's */ |
141 | int size_ci; /* size of array `base_ci' */ | 141 | int size_ci; /* size of array `base_ci' */ |
142 | unsigned long hookmask; | 142 | lu_byte hookmask; |
143 | lu_byte allowhook; | ||
144 | lu_byte hookinit; | ||
145 | ls_count basehookcount; | ||
143 | ls_count hookcount; | 146 | ls_count hookcount; |
144 | lua_Hook hook; | 147 | lua_Hook hook; |
145 | TObject _gt; /* table of globals */ | 148 | TObject _gt; /* table of globals */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.163 2002/11/07 15:39:23 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.164 2002/11/14 11:51:50 roberto Exp roberto $ |
3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
5 | ** http://www.lua.org mailto:info@lua.org | 5 | ** http://www.lua.org mailto:info@lua.org |
@@ -327,13 +327,13 @@ LUA_API int lua_pushupvalues (lua_State *L); | |||
327 | /* | 327 | /* |
328 | ** Event masks | 328 | ** Event masks |
329 | */ | 329 | */ |
330 | #define LUA_MASKCALL (2 << LUA_HOOKCALL) | 330 | #define LUA_MASKCALL (1 << LUA_HOOKCALL) |
331 | #define LUA_MASKRET (2 << LUA_HOOKRET) | 331 | #define LUA_MASKRET (1 << LUA_HOOKRET) |
332 | #define LUA_MASKLINE (2 << LUA_HOOKLINE) | 332 | #define LUA_MASKLINE (1 << LUA_HOOKLINE) |
333 | #define LUA_MASKCOUNT(count) ((unsigned long)(count) << 8) | 333 | #define LUA_MASKCOUNT(count) ((unsigned long)(count) << 8) |
334 | #define lua_getmaskcount(mask) ((mask) >> 8) | 334 | #define lua_getmaskcount(mask) ((mask) >> 8) |
335 | 335 | ||
336 | #define LUA_MAXCOUNT ((1<<24) - 1) | 336 | #define LUA_MAXCOUNT ((~(unsigned long)0) >> 8) |
337 | 337 | ||
338 | typedef struct lua_Debug lua_Debug; /* activation record */ | 338 | typedef struct lua_Debug lua_Debug; /* activation record */ |
339 | 339 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.260 2002/11/07 15:37:10 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.261 2002/11/14 16:15:53 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -70,7 +70,7 @@ int luaV_tostring (lua_State *L, StkId obj) { | |||
70 | 70 | ||
71 | 71 | ||
72 | static void traceexec (lua_State *L) { | 72 | static void traceexec (lua_State *L) { |
73 | unsigned long mask = L->hookmask; | 73 | lu_byte mask = L->hookmask; |
74 | if (mask > LUA_MASKLINE) { /* instruction-hook set? */ | 74 | if (mask > LUA_MASKLINE) { /* instruction-hook set? */ |
75 | if (L->hookcount == 0) { | 75 | if (L->hookcount == 0) { |
76 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | 76 | luaD_callhook(L, LUA_HOOKCOUNT, -1); |
@@ -82,6 +82,10 @@ static void traceexec (lua_State *L) { | |||
82 | CallInfo *ci = L->ci; | 82 | CallInfo *ci = L->ci; |
83 | Proto *p = ci_func(ci)->l.p; | 83 | Proto *p = ci_func(ci)->l.p; |
84 | int newline = getline(p, pcRel(*ci->u.l.pc, p)); | 84 | int newline = getline(p, pcRel(*ci->u.l.pc, p)); |
85 | if (!L->hookinit) { | ||
86 | luaG_inithooks(L); | ||
87 | return; | ||
88 | } | ||
85 | lua_assert(ci->state & CI_HASFRAME); | 89 | lua_assert(ci->state & CI_HASFRAME); |
86 | if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ | 90 | if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ |
87 | ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */ | 91 | ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */ |