summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldblib.c89
-rw-r--r--ldebug.c41
-rw-r--r--ldebug.h9
-rw-r--r--ldo.c67
-rw-r--r--ldo.h4
-rw-r--r--lgc.c8
-rw-r--r--lstate.c9
-rw-r--r--lstate.h8
-rw-r--r--luadebug.h21
-rw-r--r--lvm.c38
10 files changed, 165 insertions, 129 deletions
diff --git a/ldblib.c b/ldblib.c
index a0601b14..b6c78588 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.60 2002/06/18 17:42:52 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.61 2002/06/25 19:16:44 roberto Exp roberto $
3** Interface from Lua to its debug API 3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -108,65 +108,70 @@ static int setlocal (lua_State *L) {
108 108
109 109
110 110
111static const char KEY_CALLHOOK = 'c'; 111static const char KEY_HOOK = 'h';
112static const char KEY_LINEHOOK = 'l';
113 112
114 113
115static void hookf (lua_State *L, void *key) { 114static void hookf (lua_State *L, lua_Debug *ar) {
116 lua_pushudataval(L, key); 115 static const char *const hooknames[] = {"call", "return", "line", "count"};
116 lua_pushudataval(L, (void *)&KEY_HOOK);
117 lua_rawget(L, LUA_REGISTRYINDEX); 117 lua_rawget(L, LUA_REGISTRYINDEX);
118 if (lua_isfunction(L, -1)) { 118 if (lua_isfunction(L, -1)) {
119 lua_pushvalue(L, -2); /* original argument (below function) */ 119 lua_pushstring(L, hooknames[(int)ar->event]);
120 lua_call(L, 1, 0); 120 if (ar->currentline >= 0) lua_pushnumber(L, ar->currentline);
121 else lua_pushnil(L);
122 lua_assert(lua_getinfo(L, "lS", ar));
123 lua_call(L, 2, 0);
121 } 124 }
122 else 125 else
123 lua_pop(L, 1); /* pop result from gettable */ 126 lua_pop(L, 1); /* pop result from gettable */
124} 127}
125 128
126 129
127static void callf (lua_State *L, lua_Debug *ar) { 130static int makemask (const char *smask, int count) {
128 lua_pushstring(L, ar->event); 131 int mask = 0;
129 lua_assert(lua_getinfo(L, "lS", ar) && ar->currentline == -1); 132 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
130 hookf(L, (void *)&KEY_CALLHOOK); 133 if (strchr(smask, 'r')) mask |= LUA_MASKRET;
134 if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
135 return mask | lua_maskcount(count);
131} 136}
132 137
133 138
134static void linef (lua_State *L, lua_Debug *ar) { 139static char *unmakemask (int mask, char *smask) {
135 lua_pushnumber(L, ar->currentline); 140 int i = 0;
136 lua_assert((ar->currentline = ar->linedefined = -1, 141 if (mask & LUA_MASKCALL) smask[i++] = 'c';
137 lua_getinfo(L, "lS", ar) && 142 if (mask & LUA_MASKRET) smask[i++] = 'r';
138 ar->currentline == lua_tonumber(L, -1) && 143 if (mask & LUA_MASKLINE) smask[i++] = 'l';
139 ar->linedefined >= 0)); 144 smask[i] = '\0';
140 hookf(L, (void *)&KEY_LINEHOOK); 145 return smask;
141} 146}
142 147
143 148
144static void sethook (lua_State *L, void *key, lua_Hook hook, 149static int sethook (lua_State *L) {
145 lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { 150 if (lua_isnoneornil(L, 1)) {
146 lua_settop(L, 1); 151 lua_settop(L, 1);
147 if (lua_isnoneornil(L, 1)) 152 lua_sethook(L, NULL, 0); /* turn off hooks */
148 (*sethookf)(L, NULL); 153 }
149 else if (lua_isfunction(L, 1)) 154 else {
150 (*sethookf)(L, hook); 155 const char *smask = luaL_check_string(L, 2);
151 else 156 int count = luaL_opt_int(L, 3, 0);
152 luaL_argerror(L, 1, "function expected"); 157 luaL_check_type(L, 1, LUA_TFUNCTION);
153 lua_pushudataval(L, key); 158 lua_sethook(L, hookf, makemask(smask, count));
154 lua_rawget(L, LUA_REGISTRYINDEX); /* get old value */ 159 }
155 lua_pushudataval(L, key); 160 lua_pushudataval(L, (void *)&KEY_HOOK);
156 lua_pushvalue(L, 1); 161 lua_pushvalue(L, 1);
157 lua_rawset(L, LUA_REGISTRYINDEX); /* set new value */ 162 lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */
158} 163 return 0;
159
160
161static int setcallhook (lua_State *L) {
162 sethook(L, (void *)&KEY_CALLHOOK, callf, lua_setcallhook);
163 return 1;
164} 164}
165 165
166 166
167static int setlinehook (lua_State *L) { 167static int gethook (lua_State *L) {
168 sethook(L, (void *)&KEY_LINEHOOK, linef, lua_setlinehook); 168 char buff[5];
169 return 1; 169 int mask = lua_gethookmask(L);
170 lua_pushudataval(L, (void *)&KEY_HOOK);
171 lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
172 lua_pushstring(L, unmakemask(mask, buff));
173 lua_pushnumber(L, lua_getmaskcount(mask));
174 return 3;
170} 175}
171 176
172 177
@@ -245,8 +250,8 @@ static int errorfb (lua_State *L) {
245static const luaL_reg dblib[] = { 250static const luaL_reg dblib[] = {
246 {"getlocal", getlocal}, 251 {"getlocal", getlocal},
247 {"getinfo", getinfo}, 252 {"getinfo", getinfo},
248 {"setcallhook", setcallhook}, 253 {"gethook", gethook},
249 {"setlinehook", setlinehook}, 254 {"sethook", sethook},
250 {"setlocal", setlocal}, 255 {"setlocal", setlocal},
251 {"debug", debug}, 256 {"debug", debug},
252 {"traceback", errorfb}, 257 {"traceback", errorfb},
diff --git a/ldebug.c b/ldebug.c
index 5123f77d..73029a5d 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.122 2002/06/20 20:39:44 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.123 2002/06/24 15:07:21 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*/
@@ -53,26 +53,31 @@ static int currentline (lua_State *L, CallInfo *ci) {
53} 53}
54 54
55 55
56LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) { 56LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) {
57 lua_Hook oldhook;
58 lua_lock(L);
59 oldhook = L->callhook;
60 L->callhook = func;
61 lua_unlock(L);
62 return oldhook;
63}
64
65
66LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
67 CallInfo *ci; 57 CallInfo *ci;
68 lua_Hook oldhook; 58 int allow;
69 lua_lock(L); 59 lua_lock(L);
70 oldhook = L->linehook; 60 allow = allowhook(L);
71 L->linehook = func; 61 if (func == NULL) mask = 0;
62 else if (mask == 0) func = NULL;
63 L->hook = func;
64 L->hookmask = mask;
65 setallowhook(L, allow);
66 resethookcount(L);
72 for (ci = L->base_ci; ci <= L->ci; ci++) 67 for (ci = L->base_ci; ci <= L->ci; ci++)
73 currentpc(L, ci); /* update `savedpc' */ 68 currentpc(L, ci); /* update `savedpc' */
74 lua_unlock(L); 69 lua_unlock(L);
75 return oldhook; 70 return 1;
71}
72
73
74LUA_API lua_Hook lua_gethook (lua_State *L) {
75 return L->hook;
76}
77
78
79LUA_API int lua_gethookmask (lua_State *L) {
80 return L->hookmask;
76} 81}
77 82
78 83
@@ -396,6 +401,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
396 return pt->code[last]; 401 return pt->code[last];
397} 402}
398 403
404#undef check
405#undef checkjump
406#undef checkreg
407
399/* }====================================================== */ 408/* }====================================================== */
400 409
401 410
diff --git a/ldebug.h b/ldebug.h
index 764b39a9..0849a302 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.h,v 1.22 2002/06/18 15:19:27 roberto Exp roberto $ 2** $Id: ldebug.h,v 1.23 2002/06/24 15:07:21 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*/
@@ -16,6 +16,13 @@
16 16
17#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 17#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
18 18
19#define resethookcount(L) \
20 (L->hookcount = (1 << lua_getmaskcount(L->hookmask)) >> 1)
21
22#define setallowhook(L,cond) ((L->hookmask) = ((L->hookmask) & ~1) | (cond))
23#define allowhook(L) ((L->hookmask) & 1)
24
25
19void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); 26void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
20void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 27void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
21void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); 28void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
diff --git a/ldo.c b/ldo.c
index 5ff1c068..d52506b4 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.184 2002/06/26 16:37:23 roberto Exp roberto $ 2** $Id: ldo.c,v 1.185 2002/07/04 12:29:32 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*/
@@ -135,40 +135,29 @@ static void luaD_openstack (lua_State *L, StkId pos) {
135} 135}
136 136
137 137
138static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { 138void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
139 ptrdiff_t top = savestack(L, L->top); 139 lua_Hook hook = L->hook;
140 ptrdiff_t ci_top = savestack(L, L->ci->top); 140 if (hook && allowhook(L)) {
141 ar->i_ci = L->ci - L->base_ci; 141 ptrdiff_t top = savestack(L, L->top);
142 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 142 ptrdiff_t ci_top = savestack(L, L->ci->top);
143 L->ci->top = L->top + LUA_MINSTACK;
144 L->allowhooks = 0; /* cannot call hooks inside a hook */
145 lua_unlock(L);
146 (*hook)(L, ar);
147 lua_lock(L);
148 lua_assert(L->allowhooks == 0);
149 L->allowhooks = 1;
150 L->ci->top = restorestack(L, ci_top);
151 L->top = restorestack(L, top);
152}
153
154
155void luaD_lineHook (lua_State *L, int line) {
156 if (L->allowhooks) {
157 lua_Debug ar;
158 ar.event = "line";
159 ar.currentline = line;
160 dohook(L, &ar, L->linehook);
161 }
162}
163
164
165static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
166 if (L->allowhooks) {
167 lua_Debug ar; 143 lua_Debug ar;
168 ar.event = event; 144 ar.event = event;
169 L->ci->pc = NULL; /* function is not active */ 145 ar.currentline = line;
170 L->ci->top = L->ci->base; /* `top' may not have a valid value yet */ 146 ar.i_ci = L->ci - L->base_ci;
171 dohook(L, &ar, callhook); 147 if (event <= LUA_HOOKRET) { /* `call' or `return' event? */
148 L->ci->pc = NULL; /* function is not active */
149 L->ci->top = L->ci->base; /* `top' may not have a valid value yet */
150 }
151 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
152 L->ci->top = L->top + LUA_MINSTACK;
153 setallowhook(L, 0); /* cannot call hooks inside a hook */
154 lua_unlock(L);
155 (*hook)(L, &ar);
156 lua_lock(L);
157 lua_assert(!allowhook(L));
158 setallowhook(L, 1);
159 L->ci->top = restorestack(L, ci_top);
160 L->top = restorestack(L, top);
172 } 161 }
173} 162}
174 163
@@ -219,8 +208,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
219 if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ 208 if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
220 func = tryfuncTM(L, func); /* check the `function' tag method */ 209 func = tryfuncTM(L, func); /* check the `function' tag method */
221 cl = &clvalue(func)->l; 210 cl = &clvalue(func)->l;
222 if (L->callhook) { 211 if (L->hookmask & LUA_MASKCALL) {
223 luaD_callHook(L, L->callhook, "call"); 212 luaD_callhook(L, LUA_HOOKCALL, -1);
224 ci = L->ci; /* previous call may realocate `ci' */ 213 ci = L->ci; /* previous call may realocate `ci' */
225 } 214 }
226 if (!cl->isC) { /* Lua function? prepare its call */ 215 if (!cl->isC) { /* Lua function? prepare its call */
@@ -252,9 +241,9 @@ StkId luaD_precall (lua_State *L, StkId func) {
252 241
253void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { 242void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
254 StkId res; 243 StkId res;
255 if (L->callhook) { 244 if (L->hookmask & LUA_MASKRET) {
256 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 245 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
257 luaD_callHook(L, L->callhook, "return"); 246 luaD_callhook(L, LUA_HOOKRET, -1);
258 firstResult = restorestack(L, fr); 247 firstResult = restorestack(L, fr);
259 } 248 }
260 res = L->ci->base - 1; /* res == final position of 1st result */ 249 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) {
483 struct lua_longjmp lj; 472 struct lua_longjmp lj;
484 lj.ci = L->ci; 473 lj.ci = L->ci;
485 lj.top = L->top; 474 lj.top = L->top;
486 lj.allowhooks = L->allowhooks; 475 lj.allowhooks = allowhook(L);
487 lj.status = 0; 476 lj.status = 0;
488 lj.err = ud; 477 lj.err = ud;
489 lj.previous = L->errorJmp; /* chain new error handler */ 478 lj.previous = L->errorJmp; /* chain new error handler */
@@ -493,7 +482,7 @@ int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) {
493 else { /* an error occurred */ 482 else { /* an error occurred */
494 L->ci = lj.ci; /* restore the state */ 483 L->ci = lj.ci; /* restore the state */
495 L->top = lj.top; 484 L->top = lj.top;
496 L->allowhooks = lj.allowhooks; 485 setallowhook(L, lj.allowhooks);
497 restore_stack_limit(L); 486 restore_stack_limit(L);
498 } 487 }
499 L->errorJmp = lj.previous; /* restore old error handler */ 488 L->errorJmp = lj.previous; /* restore old error handler */
diff --git a/ldo.h b/ldo.h
index dc856bf6..c18193d1 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.46 2002/06/18 15:19:27 roberto Exp roberto $ 2** $Id: ldo.h,v 1.47 2002/06/18 17:10:43 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*/
@@ -32,7 +32,7 @@
32typedef void (*Pfunc) (lua_State *L, void *v); 32typedef void (*Pfunc) (lua_State *L, void *v);
33 33
34int luaD_protectedparser (lua_State *L, ZIO *z, int bin); 34int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
35void luaD_lineHook (lua_State *L, int line); 35void luaD_callhook (lua_State *L, lua_Hookevent event, int line);
36StkId luaD_precall (lua_State *L, StkId func); 36StkId luaD_precall (lua_State *L, StkId func);
37void luaD_call (lua_State *L, StkId func, int nResults); 37void luaD_call (lua_State *L, StkId func, int nResults);
38int luaD_pcall (lua_State *L, int nargs, int nresults); 38int luaD_pcall (lua_State *L, int nargs, int nresults);
diff --git a/lgc.c b/lgc.c
index c9bcf666..991ff51d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.140 2002/07/01 17:06:58 roberto Exp roberto $ 2** $Id: lgc.c,v 1.141 2002/07/04 17:57:42 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -451,8 +451,8 @@ static void do1gcTM (lua_State *L, Udata *udata) {
451 451
452 452
453static void callGCTM (lua_State *L) { 453static void callGCTM (lua_State *L) {
454 int oldah = L->allowhooks; 454 int oldah = allowhook(L);
455 L->allowhooks = 0; /* stop debug hooks during GC tag methods */ 455 setallowhook(L, 0); /* stop debug hooks during GC tag methods */
456 L->top++; /* reserve space to keep udata while runs its gc method */ 456 L->top++; /* reserve space to keep udata while runs its gc method */
457 while (G(L)->tmudata != NULL) { 457 while (G(L)->tmudata != NULL) {
458 Udata *udata = G(L)->tmudata; 458 Udata *udata = G(L)->tmudata;
@@ -465,7 +465,7 @@ static void callGCTM (lua_State *L) {
465 do1gcTM(L, udata); 465 do1gcTM(L, udata);
466 } 466 }
467 L->top--; 467 L->top--;
468 L->allowhooks = oldah; /* restore hooks */ 468 setallowhook(L, oldah); /* restore hooks */
469} 469}
470 470
471 471
diff --git a/lstate.c b/lstate.c
index 2d4bc94c..241c177b 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.96 2002/06/06 18:17:33 roberto Exp roberto $ 2** $Id: lstate.c,v 1.97 2002/06/18 15:19:27 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*/
@@ -92,12 +92,13 @@ static void preinit_state (lua_State *L) {
92 L->stack = NULL; 92 L->stack = NULL;
93 L->stacksize = 0; 93 L->stacksize = 0;
94 L->errorJmp = NULL; 94 L->errorJmp = NULL;
95 L->callhook = NULL; 95 L->hook = NULL;
96 L->linehook = NULL; 96 L->hookmask = 0;
97 setallowhook(L, 1);
98 resethookcount(L);
97 L->openupval = NULL; 99 L->openupval = NULL;
98 L->size_ci = 0; 100 L->size_ci = 0;
99 L->base_ci = NULL; 101 L->base_ci = NULL;
100 L->allowhooks = 1;
101} 102}
102 103
103 104
diff --git a/lstate.h b/lstate.h
index 4a379e2c..4f3290ef 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.85 2002/05/08 17:34:23 roberto Exp roberto $ 2** $Id: lstate.h,v 1.86 2002/07/02 16:43:28 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*/
@@ -130,8 +130,9 @@ struct lua_State {
130 CallInfo *end_ci; /* points after end of ci array*/ 130 CallInfo *end_ci; /* points after end of ci array*/
131 CallInfo *base_ci; /* array of CallInfo's */ 131 CallInfo *base_ci; /* array of CallInfo's */
132 global_State *l_G; 132 global_State *l_G;
133 lua_Hook linehook; 133 int hookmask;
134 lua_Hook callhook; 134 int hookcount;
135 lua_Hook hook;
135 TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */ 136 TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */
136 struct lua_longjmp *errorJmp; /* current error recover point */ 137 struct lua_longjmp *errorJmp; /* current error recover point */
137 UpVal *openupval; /* list of open upvalues in this stack */ 138 UpVal *openupval; /* list of open upvalues in this stack */
@@ -139,7 +140,6 @@ struct lua_State {
139 lua_State *previous; 140 lua_State *previous;
140 int stacksize; 141 int stacksize;
141 int size_ci; /* size of array `base_ci' */ 142 int size_ci; /* size of array `base_ci' */
142 int allowhooks;
143}; 143};
144 144
145 145
diff --git a/luadebug.h b/luadebug.h
index c7ea3da4..d8c82c2d 100644
--- a/luadebug.h
+++ b/luadebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luadebug.h,v 1.27 2002/04/04 17:21:31 roberto Exp roberto $ 2** $Id: luadebug.h,v 1.28 2002/06/18 17:10:43 roberto Exp roberto $
3** Debugging API 3** Debugging API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,6 +11,18 @@
11 11
12#include "lua.h" 12#include "lua.h"
13 13
14typedef enum lua_Hookevent {
15 LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKLINE, LUA_HOOKCOUNT
16} lua_Hookevent;
17
18
19#define LUA_MASKCALL (2 << LUA_HOOKCALL)
20#define LUA_MASKRET (2 << LUA_HOOKRET)
21#define LUA_MASKLINE (2 << LUA_HOOKLINE)
22#define lua_maskcount(count) ((count) << (LUA_HOOKCOUNT+1))
23#define lua_getmaskcount(mask) ((mask) >> (LUA_HOOKCOUNT+1))
24#define LUA_MASKCOUNT (lua_maskcount(1))
25
14typedef struct lua_Debug lua_Debug; /* activation record */ 26typedef struct lua_Debug lua_Debug; /* activation record */
15 27
16typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); 28typedef 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);
21LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); 33LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
22LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); 34LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
23 35
24LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); 36LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask);
25LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); 37LUA_API lua_Hook lua_gethook (lua_State *L);
38LUA_API int lua_gethookmask (lua_State *L);
26 39
27 40
28#define LUA_IDSIZE 60 41#define LUA_IDSIZE 60
29 42
30struct lua_Debug { 43struct lua_Debug {
31 const char *event; /* `call', `return', `line' */ 44 lua_Hookevent event;
32 const char *name; /* (n) */ 45 const char *name; /* (n) */
33 const char *namewhat; /* (n) `global', `local', `field', `method' */ 46 const char *namewhat; /* (n) `global', `local', `field', `method' */
34 const char *what; /* (S) `Lua' function, `C' function, Lua `main' */ 47 const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
diff --git a/lvm.c b/lvm.c
index 0e643f7f..20674c61 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.243 2002/06/24 15:07:21 roberto Exp roberto $ 2** $Id: lvm.c,v 1.244 2002/07/05 18:27:39 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*/
@@ -69,17 +69,28 @@ int luaV_tostring (lua_State *L, TObject *obj) {
69 69
70 70
71static void traceexec (lua_State *L) { 71static void traceexec (lua_State *L) {
72 CallInfo *ci = L->ci; 72 int mask = L->hookmask;
73 Proto *p = ci_func(ci)->l.p; 73 if (mask >= LUA_MASKCOUNT) { /* instruction hook set? */
74 int newline = getline(p, pcRel(*ci->pc, p)); 74 if (L->hookcount == 0) {
75 if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ 75 luaD_callhook(L, LUA_HOOKCOUNT, -1);
76 ci->savedpc = *ci->pc; /* initialize `savedpc' */ 76 resethookcount(L);
77 /* calls linehook when enters a new line or jumps back (loop) */ 77 return;
78 if (*ci->pc <= ci->savedpc || newline != getline(p, pcRel(ci->savedpc, p))) { 78 }
79 luaD_lineHook(L, newline); 79 }
80 ci = L->ci; /* previous call may reallocate `ci' */ 80 if (mask & LUA_MASKLINE) {
81 CallInfo *ci = L->ci;
82 Proto *p = ci_func(ci)->l.p;
83 int newline = getline(p, pcRel(*ci->pc, p));
84 if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */
85 ci->savedpc = *ci->pc; /* initialize `savedpc' */
86 /* calls linehook when enters a new line or jumps back (loop) */
87 if (*ci->pc <= ci->savedpc ||
88 newline != getline(p, pcRel(ci->savedpc, p))) {
89 luaD_callhook(L, LUA_HOOKLINE, newline);
90 ci = L->ci; /* previous call may reallocate `ci' */
91 }
92 ci->savedpc = *ci->pc;
81 } 93 }
82 ci->savedpc = *ci->pc;
83} 94}
84 95
85 96
@@ -370,8 +381,9 @@ StkId luaV_execute (lua_State *L) {
370 for (;;) { 381 for (;;) {
371 const Instruction i = *pc++; 382 const Instruction i = *pc++;
372 StkId ra; 383 StkId ra;
373 if (L->linehook) 384 if (L->hookmask >= LUA_MASKLINE &&
374 traceexec(L); 385 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE))
386 traceexec(L);
375 ra = RA(i); 387 ra = RA(i);
376 lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base); 388 lua_assert(L->top <= L->stack + L->stacksize && L->top >= L->ci->base);
377 lua_assert(L->top == L->ci->top || 389 lua_assert(L->top == L->ci->top ||