summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-18 09:01:55 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-18 09:01:55 -0200
commit43013b39cc28e873e18207e8e7259b6b90fed06b (patch)
tree3c2a9c520a01086df28c8f0d1ef6d9b5069fa451
parent94912d99fcdf61c1fc6dc8897c9d2b0e042e0d63 (diff)
downloadlua-43013b39cc28e873e18207e8e7259b6b90fed06b.tar.gz
lua-43013b39cc28e873e18207e8e7259b6b90fed06b.tar.bz2
lua-43013b39cc28e873e18207e8e7259b6b90fed06b.zip
new representation for hooks (to allow asynchronous calls to sethook)
-rw-r--r--ldebug.c35
-rw-r--r--ldebug.h8
-rw-r--r--ldo.c20
-rw-r--r--lgc.c8
-rw-r--r--lstate.c7
-rw-r--r--lstate.h7
-rw-r--r--lua.h10
-rw-r--r--lvm.c8
8 files changed, 59 insertions, 44 deletions
diff --git a/ldebug.c b/ldebug.c
index 91a3fc95..798d7eea 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
52LUA_API int lua_sethook (lua_State *L, lua_Hook func, unsigned long mask) { 52void 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*/
63LUA_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
75LUA_API unsigned long lua_gethookmask (lua_State *L) { 84LUA_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
diff --git a/ldebug.h b/ldebug.h
index e0d0a097..417bd47d 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -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
21void luaG_inithooks (lua_State *L);
24void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); 22void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
25void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 23void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
26void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); 24void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
diff --git a/ldo.c b/ldo.c
index ae752ece..176cf0da 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
155void luaD_callhook (lua_State *L, int event, int line) { 155void 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
329LUA_API int lua_resume (lua_State *L, int nargs) { 329LUA_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;
diff --git a/lgc.c b/lgc.c
index 87ec40c9..15338987 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
406static void callGCTM (lua_State *L) { 406static 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
diff --git a/lstate.c b/lstate.c
index 2d19405d..12a771e2 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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;
diff --git a/lstate.h b/lstate.h
index e8bdb32b..6d1deb18 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 */
diff --git a/lua.h b/lua.h
index b36f975c..c3abafa7 100644
--- a/lua.h
+++ b/lua.h
@@ -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
338typedef struct lua_Debug lua_Debug; /* activation record */ 338typedef struct lua_Debug lua_Debug; /* activation record */
339 339
diff --git a/lvm.c b/lvm.c
index 03ef02fe..e9f122d0 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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
72static void traceexec (lua_State *L) { 72static 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' */