diff options
-rw-r--r-- | ldblib.c | 89 | ||||
-rw-r--r-- | ldebug.c | 41 | ||||
-rw-r--r-- | ldebug.h | 9 | ||||
-rw-r--r-- | ldo.c | 67 | ||||
-rw-r--r-- | ldo.h | 4 | ||||
-rw-r--r-- | lgc.c | 8 | ||||
-rw-r--r-- | lstate.c | 9 | ||||
-rw-r--r-- | lstate.h | 8 | ||||
-rw-r--r-- | luadebug.h | 21 | ||||
-rw-r--r-- | lvm.c | 38 |
10 files changed, 165 insertions, 129 deletions
@@ -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 | ||
111 | static const char KEY_CALLHOOK = 'c'; | 111 | static const char KEY_HOOK = 'h'; |
112 | static const char KEY_LINEHOOK = 'l'; | ||
113 | 112 | ||
114 | 113 | ||
115 | static void hookf (lua_State *L, void *key) { | 114 | static 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 | ||
127 | static void callf (lua_State *L, lua_Debug *ar) { | 130 | static 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 | ||
134 | static void linef (lua_State *L, lua_Debug *ar) { | 139 | static 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 | ||
144 | static void sethook (lua_State *L, void *key, lua_Hook hook, | 149 | static 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 | |||
161 | static int setcallhook (lua_State *L) { | ||
162 | sethook(L, (void *)&KEY_CALLHOOK, callf, lua_setcallhook); | ||
163 | return 1; | ||
164 | } | 164 | } |
165 | 165 | ||
166 | 166 | ||
167 | static int setlinehook (lua_State *L) { | 167 | static 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) { | |||
245 | static const luaL_reg dblib[] = { | 250 | static 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}, |
@@ -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 | ||
56 | LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) { | 56 | LUA_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 | |||
66 | LUA_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 | |||
74 | LUA_API lua_Hook lua_gethook (lua_State *L) { | ||
75 | return L->hook; | ||
76 | } | ||
77 | |||
78 | |||
79 | LUA_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 | ||
@@ -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 | |||
19 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); | 26 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); |
20 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); | 27 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); |
21 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); | 28 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); |
@@ -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 | ||
138 | static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { | 138 | void 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 | |||
155 | void 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 | |||
165 | static 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 | ||
253 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | 242 | void 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 */ |
@@ -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 @@ | |||
32 | typedef void (*Pfunc) (lua_State *L, void *v); | 32 | typedef void (*Pfunc) (lua_State *L, void *v); |
33 | 33 | ||
34 | int luaD_protectedparser (lua_State *L, ZIO *z, int bin); | 34 | int luaD_protectedparser (lua_State *L, ZIO *z, int bin); |
35 | void luaD_lineHook (lua_State *L, int line); | 35 | void luaD_callhook (lua_State *L, lua_Hookevent event, int line); |
36 | StkId luaD_precall (lua_State *L, StkId func); | 36 | StkId luaD_precall (lua_State *L, StkId func); |
37 | void luaD_call (lua_State *L, StkId func, int nResults); | 37 | void luaD_call (lua_State *L, StkId func, int nResults); |
38 | int luaD_pcall (lua_State *L, int nargs, int nresults); | 38 | int luaD_pcall (lua_State *L, int nargs, int nresults); |
@@ -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 | ||
453 | static void callGCTM (lua_State *L) { | 453 | static 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 | ||
@@ -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 | ||
@@ -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 | ||
@@ -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 | ||
14 | typedef 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 | |||
14 | typedef struct lua_Debug lua_Debug; /* activation record */ | 26 | typedef struct lua_Debug lua_Debug; /* activation record */ |
15 | 27 | ||
16 | typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); | 28 | typedef 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); | |||
21 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); | 33 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); |
22 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); | 34 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); |
23 | 35 | ||
24 | LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); | 36 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask); |
25 | LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); | 37 | LUA_API lua_Hook lua_gethook (lua_State *L); |
38 | LUA_API int lua_gethookmask (lua_State *L); | ||
26 | 39 | ||
27 | 40 | ||
28 | #define LUA_IDSIZE 60 | 41 | #define LUA_IDSIZE 60 |
29 | 42 | ||
30 | struct lua_Debug { | 43 | struct 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' */ |
@@ -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 | ||
71 | static void traceexec (lua_State *L) { | 71 | static 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 || |