diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-21 16:04:41 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-21 16:04:41 -0200 |
commit | 6c79a0a80d517354dcc19a1ef64569fba9b19365 (patch) | |
tree | 3e5bd168c460c32dc198ef06fbae4c4b917e7341 | |
parent | 3daeabb60667adc8d4b9c570631704548099a7bf (diff) | |
download | lua-6c79a0a80d517354dcc19a1ef64569fba9b19365.tar.gz lua-6c79a0a80d517354dcc19a1ef64569fba9b19365.tar.bz2 lua-6c79a0a80d517354dcc19a1ef64569fba9b19365.zip |
new way to control hooks inside hooks (now the control is done inside Lua)
-rw-r--r-- | ldblib.c | 38 | ||||
-rw-r--r-- | ldo.c | 73 | ||||
-rw-r--r-- | ldo.h | 4 | ||||
-rw-r--r-- | lgc.c | 5 | ||||
-rw-r--r-- | lstate.c | 9 | ||||
-rw-r--r-- | lstate.h | 9 | ||||
-rw-r--r-- | lvm.c | 21 |
7 files changed, 82 insertions, 77 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.7 1999/11/22 13:12:07 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.8 1999/11/22 17:39:51 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 | */ |
@@ -144,32 +144,28 @@ static void setlocal (lua_State *L) { | |||
144 | 144 | ||
145 | 145 | ||
146 | 146 | ||
147 | static int linehook = -1; /* Lua reference to line hook function */ | 147 | static int linehook = LUA_NOREF; /* Lua reference to line hook function */ |
148 | static int callhook = -1; /* Lua reference to call hook function */ | 148 | static int callhook = LUA_NOREF; /* Lua reference to call hook function */ |
149 | 149 | ||
150 | 150 | ||
151 | static void dohook (lua_State *L, int ref) { | ||
152 | lua_LHFunction oldlinehook = lua_setlinehook(L, NULL); | ||
153 | lua_CHFunction oldcallhook = lua_setcallhook(L, NULL); | ||
154 | lua_callfunction(L, lua_getref(L, ref)); | ||
155 | lua_setlinehook(L, oldlinehook); | ||
156 | lua_setcallhook(L, oldcallhook); | ||
157 | } | ||
158 | |||
159 | 151 | ||
160 | static void linef (lua_State *L, int line) { | 152 | static void linef (lua_State *L, int line) { |
161 | lua_pushnumber(L, line); | 153 | if (linehook != LUA_NOREF) { |
162 | dohook(L, linehook); | 154 | lua_pushnumber(L, line); |
155 | lua_callfunction(L, lua_getref(L, linehook)); | ||
156 | } | ||
163 | } | 157 | } |
164 | 158 | ||
165 | 159 | ||
166 | static void callf (lua_State *L, lua_Function func, const char *file, int line) { | 160 | static void callf (lua_State *L, lua_Function f, const char *file, int line) { |
167 | if (func != LUA_NOOBJECT) { | 161 | if (callhook != LUA_NOREF) { |
168 | lua_pushobject(L, func); | 162 | if (f != LUA_NOOBJECT) { |
169 | lua_pushstring(L, file); | 163 | lua_pushobject(L, f); |
170 | lua_pushnumber(L, line); | 164 | lua_pushstring(L, file); |
165 | lua_pushnumber(L, line); | ||
166 | } | ||
167 | lua_callfunction(L, lua_getref(L, callhook)); | ||
171 | } | 168 | } |
172 | dohook(L, callhook); | ||
173 | } | 169 | } |
174 | 170 | ||
175 | 171 | ||
@@ -177,7 +173,7 @@ static void setcallhook (lua_State *L) { | |||
177 | lua_Object f = lua_getparam(L, 1); | 173 | lua_Object f = lua_getparam(L, 1); |
178 | lua_unref(L, callhook); | 174 | lua_unref(L, callhook); |
179 | if (f == LUA_NOOBJECT) { | 175 | if (f == LUA_NOOBJECT) { |
180 | callhook = -1; | 176 | callhook = LUA_NOREF; |
181 | lua_setcallhook(L, NULL); | 177 | lua_setcallhook(L, NULL); |
182 | } | 178 | } |
183 | else { | 179 | else { |
@@ -192,7 +188,7 @@ static void setlinehook (lua_State *L) { | |||
192 | lua_Object f = lua_getparam(L, 1); | 188 | lua_Object f = lua_getparam(L, 1); |
193 | lua_unref(L, linehook); | 189 | lua_unref(L, linehook); |
194 | if (f == LUA_NOOBJECT) { | 190 | if (f == LUA_NOOBJECT) { |
195 | linehook = -1; | 191 | linehook = LUA_NOREF; |
196 | lua_setlinehook(L, NULL); | 192 | lua_setlinehook(L, NULL); |
197 | } | 193 | } |
198 | else { | 194 | else { |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.57 1999/12/06 11:43:58 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.58 1999/12/06 12:03:45 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 | */ |
@@ -99,30 +99,43 @@ void luaD_openstack (lua_State *L, StkId pos) { | |||
99 | 99 | ||
100 | 100 | ||
101 | void luaD_lineHook (lua_State *L, int line) { | 101 | void luaD_lineHook (lua_State *L, int line) { |
102 | struct C_Lua_Stack oldCLS = L->Cstack; | 102 | if (L->allowhooks) { |
103 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; | 103 | struct C_Lua_Stack oldCLS = L->Cstack; |
104 | L->Cstack.num = 0; | 104 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; |
105 | (*L->linehook)(L, line); | 105 | L->Cstack.num = 0; |
106 | L->top = old_top; | 106 | L->allowhooks = 0; /* cannot call hooks inside a hook */ |
107 | L->Cstack = oldCLS; | 107 | (*L->linehook)(L, line); |
108 | L->allowhooks = 1; | ||
109 | L->top = old_top; | ||
110 | L->Cstack = oldCLS; | ||
111 | } | ||
108 | } | 112 | } |
109 | 113 | ||
110 | 114 | ||
111 | void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, | 115 | static void luaD_callHook (lua_State *L, StkId func, lua_CHFunction callhook, |
112 | int isreturn) { | 116 | int isreturn) { |
113 | struct C_Lua_Stack oldCLS = L->Cstack; | 117 | if (L->allowhooks) { |
114 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; | 118 | struct C_Lua_Stack oldCLS = L->Cstack; |
115 | L->Cstack.num = 0; | 119 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; |
116 | if (isreturn) | 120 | L->Cstack.num = 0; |
117 | (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0); | 121 | L->allowhooks = 0; /* cannot call hooks inside a hook */ |
118 | else { | 122 | if (isreturn) |
119 | TObject *f = base-1; | 123 | callhook(L, LUA_NOOBJECT, "(return)", 0); |
120 | if (tf) | 124 | else { |
121 | v 1.3 1997/10/16, f, tf->source->str, tf->lineDefined); | 125 | if (ttype(func) == LUA_T_PROTO) |
122 | else (*L->callhook)(L, f, "(C)", -1); | 126 | callhook(L, func, tfvalue(func)->source->str, |
127 | tfvalue(func)->lineDefined); | ||
128 | else if (ttype(func) == LUA_T_CLOSURE && | ||
129 | ttype(clvalue(func)->consts) == LUA_T_PROTO) | ||
130 | callhook(L, func, tfvalue(protovalue(func))->source->str, | ||
131 | tfvalue(protovalue(func))->lineDefined); | ||
132 | else | ||
133 | callhook(L, func, "(C)", -1); | ||
134 | } | ||
135 | L->allowhooks = 1; | ||
136 | L->top = old_top; | ||
137 | L->Cstack = oldCLS; | ||
123 | } | 138 | } |
124 | L->top = old_top; | ||
125 | L->Cstack = oldCLS; | ||
126 | } | 139 | } |
127 | 140 | ||
128 | 141 | ||
@@ -138,11 +151,7 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) { | |||
138 | L->Cstack.num = numarg; | 151 | L->Cstack.num = numarg; |
139 | L->Cstack.lua2C = base; | 152 | L->Cstack.lua2C = base; |
140 | L->Cstack.base = L->top; | 153 | L->Cstack.base = L->top; |
141 | if (L->callhook) | ||
142 | luaD_callHook(L, base, NULL, 0); | ||
143 | (*f)(L); /* do the actual call */ | 154 | (*f)(L); /* do the actual call */ |
144 | if (L->callhook) /* test again: `func' may change callhook */ | ||
145 | luaD_callHook(L, base, NULL, 1); | ||
146 | firstResult = L->Cstack.base; | 155 | firstResult = L->Cstack.base; |
147 | L->Cstack = oldCLS; | 156 | L->Cstack = oldCLS; |
148 | return firstResult; | 157 | return firstResult; |
@@ -179,6 +188,10 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) { | |||
179 | */ | 188 | */ |
180 | void luaD_call (lua_State *L, StkId func, int nResults) { | 189 | void luaD_call (lua_State *L, StkId func, int nResults) { |
181 | StkId firstResult; | 190 | StkId firstResult; |
191 | lua_CHFunction callhook = L->callhook; | ||
192 | if (callhook) | ||
193 | luaD_callHook(L, func, callhook, 0); | ||
194 | retry: /* for `function' tag method */ | ||
182 | switch (ttype(func)) { | 195 | switch (ttype(func)) { |
183 | case LUA_T_CPROTO: | 196 | case LUA_T_CPROTO: |
184 | ttype(func) = LUA_T_CMARK; | 197 | ttype(func) = LUA_T_CMARK; |
@@ -197,15 +210,17 @@ void luaD_call (lua_State *L, StkId func, int nResults) { | |||
197 | luaV_execute(L, c, tfvalue(proto), func+1); | 210 | luaV_execute(L, c, tfvalue(proto), func+1); |
198 | break; | 211 | break; |
199 | } | 212 | } |
200 | default: { /* `func' is not a function */ | 213 | default: { /* `func' is not a function; check the `function' tag method */ |
201 | /* Check the tag method for invalid functions */ | ||
202 | const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); | 214 | const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); |
203 | if (ttype(im) == LUA_T_NIL) | 215 | if (ttype(im) == LUA_T_NIL) |
204 | lua_error(L, "call expression not a function"); | 216 | lua_error(L, "call expression not a function"); |
205 | luaD_callTM(L, im, L->top-func, nResults); | 217 | luaD_openstack(L, func); |
206 | return; | 218 | *func = *im; /* tag method is the new function to be called */ |
219 | goto retry; /* retry the call (without calling callhook again) */ | ||
207 | } | 220 | } |
208 | } | 221 | } |
222 | if (callhook) /* same hook that was used at entry */ | ||
223 | luaD_callHook(L, NULL, callhook, 1); /* `return' hook */ | ||
209 | /* adjust the number of results */ | 224 | /* adjust the number of results */ |
210 | if (nResults == MULT_RET) | 225 | if (nResults == MULT_RET) |
211 | nResults = L->top - firstResult; | 226 | nResults = L->top - firstResult; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 1.13 1999/12/02 16:24:45 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 1.14 1999/12/06 11:41:28 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 | */ |
@@ -27,8 +27,6 @@ void luaD_init (lua_State *L, int stacksize); | |||
27 | void luaD_adjusttop (lua_State *L, StkId base, int extra); | 27 | void luaD_adjusttop (lua_State *L, StkId base, int extra); |
28 | void luaD_openstack (lua_State *L, StkId pos); | 28 | void luaD_openstack (lua_State *L, StkId pos); |
29 | void luaD_lineHook (lua_State *L, int line); | 29 | void luaD_lineHook (lua_State *L, int line); |
30 | void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, | ||
31 | int isreturn); | ||
32 | void luaD_call (lua_State *L, StkId func, int nResults); | 30 | void luaD_call (lua_State *L, StkId func, int nResults); |
33 | void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); | 31 | void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); |
34 | int luaD_protectedrun (lua_State *L); | 32 | int luaD_protectedrun (lua_State *L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.35 1999/12/01 19:50:08 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.36 1999/12/14 18:31:20 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 | */ |
@@ -240,12 +240,15 @@ static void markall (lua_State *L) { | |||
240 | 240 | ||
241 | 241 | ||
242 | void luaC_collect (lua_State *L, int all) { | 242 | void luaC_collect (lua_State *L, int all) { |
243 | int oldah = L->allowhooks; | ||
244 | L->allowhooks = 0; /* stop debug hooks during GC */ | ||
243 | L->GCthreshold *= 4; /* to avoid GC during GC */ | 245 | L->GCthreshold *= 4; /* to avoid GC during GC */ |
244 | tableTM(L); /* call TM for tables (if LUA_COMPAT_GC) */ | 246 | tableTM(L); /* call TM for tables (if LUA_COMPAT_GC) */ |
245 | collecttable(L); | 247 | collecttable(L); |
246 | collectstring(L, all?MAX_INT:1); | 248 | collectstring(L, all?MAX_INT:1); |
247 | collectproto(L); | 249 | collectproto(L); |
248 | collectclosure(L); | 250 | collectclosure(L); |
251 | L->allowhooks = oldah; /* restore hooks */ | ||
249 | } | 252 | } |
250 | 253 | ||
251 | 254 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 1.21 1999/12/06 12:03:45 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.22 1999/12/07 11:42:54 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 | */ |
@@ -38,9 +38,6 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) { | |||
38 | L->Mbuffnext = 0; | 38 | L->Mbuffnext = 0; |
39 | L->Cblocks = NULL; | 39 | L->Cblocks = NULL; |
40 | L->numCblocks = 0; | 40 | L->numCblocks = 0; |
41 | L->debug = 0; | ||
42 | L->callhook = NULL; | ||
43 | L->linehook = NULL; | ||
44 | L->rootproto = NULL; | 41 | L->rootproto = NULL; |
45 | L->rootcl = NULL; | 42 | L->rootcl = NULL; |
46 | L->rootglobal = NULL; | 43 | L->rootglobal = NULL; |
@@ -51,6 +48,10 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) { | |||
51 | L->refFree = NONEXT; | 48 | L->refFree = NONEXT; |
52 | L->nblocks = 0; | 49 | L->nblocks = 0; |
53 | L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */ | 50 | L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */ |
51 | L->debug = 0; | ||
52 | L->callhook = NULL; | ||
53 | L->linehook = NULL; | ||
54 | L->allowhooks = 1; | ||
54 | luaD_init(L, stacksize); | 55 | luaD_init(L, stacksize); |
55 | luaS_init(L); | 56 | luaS_init(L); |
56 | luaX_init(L); | 57 | luaX_init(L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.24 1999/12/01 19:50:08 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.25 1999/12/06 11:41: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 | */ |
@@ -62,9 +62,6 @@ struct lua_State { | |||
62 | int Mbuffnext; /* next position to fill in Mbuffer */ | 62 | int Mbuffnext; /* next position to fill in Mbuffer */ |
63 | struct C_Lua_Stack *Cblocks; | 63 | struct C_Lua_Stack *Cblocks; |
64 | int numCblocks; /* number of nested Cblocks */ | 64 | int numCblocks; /* number of nested Cblocks */ |
65 | int debug; | ||
66 | lua_CHFunction callhook; | ||
67 | lua_LHFunction linehook; | ||
68 | /* global state */ | 65 | /* global state */ |
69 | TProtoFunc *rootproto; /* list of all prototypes */ | 66 | TProtoFunc *rootproto; /* list of all prototypes */ |
70 | Closure *rootcl; /* list of all closures */ | 67 | Closure *rootcl; /* list of all closures */ |
@@ -78,6 +75,10 @@ struct lua_State { | |||
78 | int refFree; /* list of free positions in refArray */ | 75 | int refFree; /* list of free positions in refArray */ |
79 | unsigned long GCthreshold; | 76 | unsigned long GCthreshold; |
80 | unsigned long nblocks; /* number of 'blocks' currently allocated */ | 77 | unsigned long nblocks; /* number of 'blocks' currently allocated */ |
78 | int debug; | ||
79 | lua_CHFunction callhook; | ||
80 | lua_LHFunction linehook; | ||
81 | int allowhooks; | ||
81 | }; | 82 | }; |
82 | 83 | ||
83 | 84 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.72 1999/12/09 20:01:48 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.73 1999/12/14 18:31:20 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 | */ |
@@ -294,8 +294,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
294 | register StkId top; /* keep top local, for performance */ | 294 | register StkId top; /* keep top local, for performance */ |
295 | register const Byte *pc = tf->code; | 295 | register const Byte *pc = tf->code; |
296 | const TObject *consts = tf->consts; | 296 | const TObject *consts = tf->consts; |
297 | if (L->callhook) | ||
298 | luaD_callHook(L, base, tf, 0); | ||
299 | luaD_checkstack(L, (*pc++)+EXTRA_STACK); | 297 | luaD_checkstack(L, (*pc++)+EXTRA_STACK); |
300 | if (*pc < ZEROVARARG) | 298 | if (*pc < ZEROVARARG) |
301 | luaD_adjusttop(L, base, *(pc++)); | 299 | luaD_adjusttop(L, base, *(pc++)); |
@@ -310,12 +308,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
310 | switch ((OpCode)*pc++) { | 308 | switch ((OpCode)*pc++) { |
311 | 309 | ||
312 | case ENDCODE: | 310 | case ENDCODE: |
313 | top = base; | 311 | return L->top; /* no results */ |
314 | goto ret; | ||
315 | 312 | ||
316 | case RETCODE: | 313 | case RETCODE: |
317 | base += *pc++; | 314 | L->top = top; |
318 | goto ret; | 315 | return base+(*pc++); |
319 | 316 | ||
320 | case CALL: aux = *pc++; | 317 | case CALL: aux = *pc++; |
321 | L->top = top; | 318 | L->top = top; |
@@ -326,9 +323,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
326 | case TAILCALL: aux = *pc++; | 323 | case TAILCALL: aux = *pc++; |
327 | L->top = top; | 324 | L->top = top; |
328 | luaD_call(L, base+(*pc++), MULT_RET); | 325 | luaD_call(L, base+(*pc++), MULT_RET); |
329 | top = L->top; | 326 | return base+aux; |
330 | base += aux; | ||
331 | goto ret; | ||
332 | 327 | ||
333 | case PUSHNIL: aux = *pc++; | 328 | case PUSHNIL: aux = *pc++; |
334 | do { | 329 | do { |
@@ -608,9 +603,5 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
608 | goto switchentry; /* do not reset "aux" */ | 603 | goto switchentry; /* do not reset "aux" */ |
609 | 604 | ||
610 | } | 605 | } |
611 | } ret: | 606 | } |
612 | L->top = top; | ||
613 | if (L->callhook) | ||
614 | luaD_callHook(L, 0, NULL, 1); | ||
615 | return base; | ||
616 | } | 607 | } |