summaryrefslogtreecommitdiff
path: root/ldblib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-07-07 10:37:08 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-07-07 10:37:08 -0300
commit79fee990241bc29c9306d7cee655653ff88b3d0c (patch)
tree9679215722d4b70f51be8593b3dd488d591fb813 /ldblib.c
parenta73ded21535c79a081cae16b12482e3e70441e6c (diff)
downloadlua-79fee990241bc29c9306d7cee655653ff88b3d0c.tar.gz
lua-79fee990241bc29c9306d7cee655653ff88b3d0c.tar.bz2
lua-79fee990241bc29c9306d7cee655653ff88b3d0c.zip
`debug' library can operate over other threads
Diffstat (limited to 'ldblib.c')
-rw-r--r--ldblib.c134
1 files changed, 92 insertions, 42 deletions
diff --git a/ldblib.c b/ldblib.c
index a4d2d66b..ad6a448a 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.79 2003/03/11 12:24:34 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.80 2003/04/03 13:35:34 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*/
@@ -32,24 +32,39 @@ static void settabsi (lua_State *L, const char *i, int v) {
32} 32}
33 33
34 34
35static lua_State *getthread (lua_State *L, int *arg) {
36 if (lua_isthread(L, 1)) {
37 *arg = 1;
38 return lua_tothread(L, 1);
39 }
40 else {
41 *arg = 0;
42 return L;
43 }
44}
45
46
35static int getinfo (lua_State *L) { 47static int getinfo (lua_State *L) {
36 lua_Debug ar; 48 lua_Debug ar;
37 const char *options = luaL_optstring(L, 2, "flnSu"); 49 int arg;
38 if (lua_isnumber(L, 1)) { 50 lua_State *L1 = getthread(L, &arg);
39 if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) { 51 const char *options = luaL_optstring(L, arg+2, "flnSu");
52 if (lua_isnumber(L, arg+1)) {
53 if (!lua_getstack(L1, (int)(lua_tonumber(L, arg+1)), &ar)) {
40 lua_pushnil(L); /* level out of range */ 54 lua_pushnil(L); /* level out of range */
41 return 1; 55 return 1;
42 } 56 }
43 } 57 }
44 else if (lua_isfunction(L, 1)) { 58 else if (lua_isfunction(L, arg+1)) {
45 lua_pushfstring(L, ">%s", options); 59 lua_pushfstring(L, ">%s", options);
46 options = lua_tostring(L, -1); 60 options = lua_tostring(L, -1);
47 lua_pushvalue(L, 1); 61 lua_pushvalue(L, arg+1);
62 lua_xmove(L, L1, 1);
48 } 63 }
49 else 64 else
50 return luaL_argerror(L, 1, "function or level expected"); 65 return luaL_argerror(L, arg+1, "function or level expected");
51 if (!lua_getinfo(L, options, &ar)) 66 if (!lua_getinfo(L1, options, &ar))
52 return luaL_argerror(L, 2, "invalid option"); 67 return luaL_argerror(L, arg+2, "invalid option");
53 lua_newtable(L); 68 lua_newtable(L);
54 for (; *options; options++) { 69 for (; *options; options++) {
55 switch (*options) { 70 switch (*options) {
@@ -71,7 +86,10 @@ static int getinfo (lua_State *L) {
71 break; 86 break;
72 case 'f': 87 case 'f':
73 lua_pushliteral(L, "func"); 88 lua_pushliteral(L, "func");
74 lua_pushvalue(L, -3); 89 if (L == L1)
90 lua_pushvalue(L, -3);
91 else
92 lua_xmove(L1, L, 1);
75 lua_rawset(L, -3); 93 lua_rawset(L, -3);
76 break; 94 break;
77 } 95 }
@@ -81,12 +99,15 @@ static int getinfo (lua_State *L) {
81 99
82 100
83static int getlocal (lua_State *L) { 101static int getlocal (lua_State *L) {
102 int arg;
103 lua_State *L1 = getthread(L, &arg);
84 lua_Debug ar; 104 lua_Debug ar;
85 const char *name; 105 const char *name;
86 if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ 106 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
87 return luaL_argerror(L, 1, "level out of range"); 107 return luaL_argerror(L, arg+1, "level out of range");
88 name = lua_getlocal(L, &ar, luaL_checkint(L, 2)); 108 name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
89 if (name) { 109 if (name) {
110 lua_xmove(L1, L, 1);
90 lua_pushstring(L, name); 111 lua_pushstring(L, name);
91 lua_pushvalue(L, -2); 112 lua_pushvalue(L, -2);
92 return 2; 113 return 2;
@@ -99,11 +120,15 @@ static int getlocal (lua_State *L) {
99 120
100 121
101static int setlocal (lua_State *L) { 122static int setlocal (lua_State *L) {
123 int arg;
124 lua_State *L1 = getthread(L, &arg);
102 lua_Debug ar; 125 lua_Debug ar;
103 if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ 126 if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
104 return luaL_argerror(L, 1, "level out of range"); 127 return luaL_argerror(L, arg+1, "level out of range");
105 luaL_checkany(L, 3); 128 luaL_checkany(L, arg+3);
106 lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2))); 129 lua_settop(L, arg+3);
130 lua_xmove(L, L1, 1);
131 lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
107 return 1; 132 return 1;
108} 133}
109 134
@@ -141,6 +166,8 @@ static void hookf (lua_State *L, lua_Debug *ar) {
141 {"call", "return", "line", "count", "tail return"}; 166 {"call", "return", "line", "count", "tail return"};
142 lua_pushlightuserdata(L, (void *)&KEY_HOOK); 167 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
143 lua_rawget(L, LUA_REGISTRYINDEX); 168 lua_rawget(L, LUA_REGISTRYINDEX);
169 lua_pushlightuserdata(L, L);
170 lua_rawget(L, -2);
144 if (lua_isfunction(L, -1)) { 171 if (lua_isfunction(L, -1)) {
145 lua_pushstring(L, hooknames[(int)ar->event]); 172 lua_pushstring(L, hooknames[(int)ar->event]);
146 if (ar->currentline >= 0) 173 if (ar->currentline >= 0)
@@ -149,8 +176,6 @@ static void hookf (lua_State *L, lua_Debug *ar) {
149 lua_assert(lua_getinfo(L, "lS", ar)); 176 lua_assert(lua_getinfo(L, "lS", ar));
150 lua_call(L, 2, 0); 177 lua_call(L, 2, 0);
151 } 178 }
152 else
153 lua_pop(L, 1); /* pop result from gettable */
154} 179}
155 180
156 181
@@ -174,36 +199,59 @@ static char *unmakemask (int mask, char *smask) {
174} 199}
175 200
176 201
202static void gethooktable (lua_State *L) {
203 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
204 lua_rawget(L, LUA_REGISTRYINDEX);
205 if (!lua_istable(L, -1)) {
206 lua_pop(L, 1);
207 lua_newtable(L);
208 lua_pushlightuserdata(L, (void *)&KEY_HOOK);
209 lua_pushvalue(L, -2);
210 lua_rawset(L, LUA_REGISTRYINDEX);
211 }
212}
213
214
177static int sethook (lua_State *L) { 215static int sethook (lua_State *L) {
178 if (lua_isnoneornil(L, 1)) { 216 int arg;
179 lua_settop(L, 1); 217 lua_State *L1 = getthread(L, &arg);
180 lua_sethook(L, NULL, 0, 0); /* turn off hooks */ 218 if (lua_isnoneornil(L, arg+1)) {
219 lua_settop(L, arg+1);
220 lua_sethook(L1, NULL, 0, 0); /* turn off hooks */
181 } 221 }
182 else { 222 else {
183 const char *smask = luaL_checkstring(L, 2); 223 const char *smask = luaL_checkstring(L, arg+2);
184 int count = luaL_optint(L, 3, 0); 224 int count = luaL_optint(L, arg+3, 0);
185 luaL_checktype(L, 1, LUA_TFUNCTION); 225 luaL_checktype(L, arg+1, LUA_TFUNCTION);
186 lua_sethook(L, hookf, makemask(smask, count), count); 226 lua_sethook(L1, hookf, makemask(smask, count), count);
187 } 227 }
188 lua_pushlightuserdata(L, (void *)&KEY_HOOK); 228 gethooktable(L1);
189 lua_pushvalue(L, 1); 229 lua_pushlightuserdata(L1, L1);
190 lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ 230 lua_pushvalue(L, arg+1);
231 lua_xmove(L, L1, 1);
232 lua_rawset(L1, -3); /* set new hook */
233 lua_pop(L1, 1); /* remove hook table */
191 return 0; 234 return 0;
192} 235}
193 236
194 237
195static int gethook (lua_State *L) { 238static int gethook (lua_State *L) {
239 int arg;
240 lua_State *L1 = getthread(L, &arg);
196 char buff[5]; 241 char buff[5];
197 int mask = lua_gethookmask(L); 242 int mask = lua_gethookmask(L1);
198 lua_Hook hook = lua_gethook(L); 243 lua_Hook hook = lua_gethook(L1);
199 if (hook != NULL && hook != hookf) /* external hook? */ 244 if (hook != NULL && hook != hookf) /* external hook? */
200 lua_pushliteral(L, "external hook"); 245 lua_pushliteral(L, "external hook");
201 else { 246 else {
202 lua_pushlightuserdata(L, (void *)&KEY_HOOK); 247 gethooktable(L1);
203 lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ 248 lua_pushlightuserdata(L1, L1);
249 lua_rawget(L1, -2); /* get hook */
250 lua_remove(L1, -2); /* remove hook table */
251 lua_xmove(L1, L, 1);
204 } 252 }
205 lua_pushstring(L, unmakemask(mask, buff)); 253 lua_pushstring(L, unmakemask(mask, buff));
206 lua_pushnumber(L, (lua_Number)lua_gethookcount(L)); 254 lua_pushnumber(L, (lua_Number)lua_gethookcount(L1));
207 return 3; 255 return 3;
208} 256}
209 257
@@ -227,27 +275,29 @@ static int debug (lua_State *L) {
227static int errorfb (lua_State *L) { 275static int errorfb (lua_State *L) {
228 int level = 1; /* skip level 0 (it's this function) */ 276 int level = 1; /* skip level 0 (it's this function) */
229 int firstpart = 1; /* still before eventual `...' */ 277 int firstpart = 1; /* still before eventual `...' */
278 int arg;
279 lua_State *L1 = getthread(L, &arg);
230 lua_Debug ar; 280 lua_Debug ar;
231 if (lua_gettop(L) == 0) 281 if (lua_gettop(L) == arg)
232 lua_pushliteral(L, ""); 282 lua_pushliteral(L, "");
233 else if (!lua_isstring(L, 1)) return 1; /* no string message */ 283 else if (!lua_isstring(L, arg+1)) return 1; /* no string message */
234 else lua_pushliteral(L, "\n"); 284 else lua_pushliteral(L, "\n");
235 lua_pushliteral(L, "stack traceback:"); 285 lua_pushliteral(L, "stack traceback:");
236 while (lua_getstack(L, level++, &ar)) { 286 while (lua_getstack(L1, level++, &ar)) {
237 if (level > LEVELS1 && firstpart) { 287 if (level > LEVELS1 && firstpart) {
238 /* no more than `LEVELS2' more levels? */ 288 /* no more than `LEVELS2' more levels? */
239 if (!lua_getstack(L, level+LEVELS2, &ar)) 289 if (!lua_getstack(L1, level+LEVELS2, &ar))
240 level--; /* keep going */ 290 level--; /* keep going */
241 else { 291 else {
242 lua_pushliteral(L, "\n\t..."); /* too many levels */ 292 lua_pushliteral(L, "\n\t..."); /* too many levels */
243 while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ 293 while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
244 level++; 294 level++;
245 } 295 }
246 firstpart = 0; 296 firstpart = 0;
247 continue; 297 continue;
248 } 298 }
249 lua_pushliteral(L, "\n\t"); 299 lua_pushliteral(L, "\n\t");
250 lua_getinfo(L, "Snl", &ar); 300 lua_getinfo(L1, "Snl", &ar);
251 lua_pushfstring(L, "%s:", ar.short_src); 301 lua_pushfstring(L, "%s:", ar.short_src);
252 if (ar.currentline > 0) 302 if (ar.currentline > 0)
253 lua_pushfstring(L, "%d:", ar.currentline); 303 lua_pushfstring(L, "%d:", ar.currentline);
@@ -268,9 +318,9 @@ static int errorfb (lua_State *L) {
268 ar.short_src, ar.linedefined); 318 ar.short_src, ar.linedefined);
269 } 319 }
270 } 320 }
271 lua_concat(L, lua_gettop(L)); 321 lua_concat(L, lua_gettop(L) - arg);
272 } 322 }
273 lua_concat(L, lua_gettop(L)); 323 lua_concat(L, lua_gettop(L) - arg);
274 return 1; 324 return 1;
275} 325}
276 326