aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-21 16:04:41 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-12-21 16:04:41 -0200
commit6c79a0a80d517354dcc19a1ef64569fba9b19365 (patch)
tree3e5bd168c460c32dc198ef06fbae4c4b917e7341
parent3daeabb60667adc8d4b9c570631704548099a7bf (diff)
downloadlua-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.c38
-rw-r--r--ldo.c73
-rw-r--r--ldo.h4
-rw-r--r--lgc.c5
-rw-r--r--lstate.c9
-rw-r--r--lstate.h9
-rw-r--r--lvm.c21
7 files changed, 82 insertions, 77 deletions
diff --git a/ldblib.c b/ldblib.c
index 3c3dd468..028f6210 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -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
147static int linehook = -1; /* Lua reference to line hook function */ 147static int linehook = LUA_NOREF; /* Lua reference to line hook function */
148static int callhook = -1; /* Lua reference to call hook function */ 148static int callhook = LUA_NOREF; /* Lua reference to call hook function */
149 149
150 150
151static 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
160static void linef (lua_State *L, int line) { 152static 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
166static void callf (lua_State *L, lua_Function func, const char *file, int line) { 160static 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 {
diff --git a/ldo.c b/ldo.c
index 384bd244..60b9b354 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
101void luaD_lineHook (lua_State *L, int line) { 101void 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
111void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, 115static 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*/
180void luaD_call (lua_State *L, StkId func, int nResults) { 189void 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;
diff --git a/ldo.h b/ldo.h
index f03bbd0a..0193b797 100644
--- a/ldo.h
+++ b/ldo.h
@@ -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);
27void luaD_adjusttop (lua_State *L, StkId base, int extra); 27void luaD_adjusttop (lua_State *L, StkId base, int extra);
28void luaD_openstack (lua_State *L, StkId pos); 28void luaD_openstack (lua_State *L, StkId pos);
29void luaD_lineHook (lua_State *L, int line); 29void luaD_lineHook (lua_State *L, int line);
30void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf,
31 int isreturn);
32void luaD_call (lua_State *L, StkId func, int nResults); 30void luaD_call (lua_State *L, StkId func, int nResults);
33void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); 31void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
34int luaD_protectedrun (lua_State *L); 32int luaD_protectedrun (lua_State *L);
diff --git a/lgc.c b/lgc.c
index ceade0a4..2e9aa590 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
242void luaC_collect (lua_State *L, int all) { 242void 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
diff --git a/lstate.c b/lstate.c
index 37b6f2a3..e82ca950 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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);
diff --git a/lstate.h b/lstate.h
index cd4020be..8364dc45 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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
diff --git a/lvm.c b/lvm.c
index 026b089a..12afff68 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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}