3 ** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
5 ** Major portions taken verbatim or adapted from the Lua interpreter.
6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
20 /* ------------------------------------------------------------------------ */
22 #define LJLIB_MODULE_debug
24 LJLIB_CF(debug_getregistry
)
26 copyTV(L
, L
->top
++, registry(L
));
30 LJLIB_CF(debug_getmetatable
)
32 lj_lib_checkany(L
, 1);
33 if (!lua_getmetatable(L
, 1)) {
39 LJLIB_CF(debug_setmetatable
)
41 lj_lib_checktabornil(L
, 2);
43 lua_setmetatable(L
, 1);
45 setboolV(L
->top
-1, 1);
50 LJLIB_CF(debug_getfenv
)
52 lj_lib_checkany(L
, 1);
57 LJLIB_CF(debug_setfenv
)
59 lj_lib_checktab(L
, 2);
61 if (!lua_setfenv(L
, 1))
62 lj_err_caller(L
, LJ_ERR_SETFENV
);
66 /* ------------------------------------------------------------------------ */
68 static void settabss(lua_State
*L
, const char *i
, const char *v
)
71 lua_setfield(L
, -2, i
);
74 static void settabsi(lua_State
*L
, const char *i
, int v
)
76 lua_pushinteger(L
, v
);
77 lua_setfield(L
, -2, i
);
80 static lua_State
*getthread(lua_State
*L
, int *arg
)
82 if (L
->base
< L
->top
&& tvisthread(L
->base
)) {
84 return threadV(L
->base
);
91 static void treatstackoption(lua_State
*L
, lua_State
*L1
, const char *fname
)
99 lua_setfield(L
, -2, fname
);
102 LJLIB_CF(debug_getinfo
)
105 int arg
, opt_f
= 0, opt_L
= 0;
106 lua_State
*L1
= getthread(L
, &arg
);
107 const char *options
= luaL_optstring(L
, arg
+2, "flnSu");
108 if (lua_isnumber(L
, arg
+1)) {
109 if (!lua_getstack(L1
, (int)lua_tointeger(L
, arg
+1), &ar
)) {
113 } else if (L
->base
+arg
< L
->top
&& tvisfunc(L
->base
+arg
)) {
114 options
= lua_pushfstring(L
, ">%s", options
);
115 setfuncV(L1
, L1
->top
++, funcV(L
->base
+arg
));
117 lj_err_arg(L
, arg
+1, LJ_ERR_NOFUNCL
);
119 if (!lua_getinfo(L1
, options
, &ar
))
120 lj_err_arg(L
, arg
+2, LJ_ERR_INVOPT
);
121 lua_createtable(L
, 0, 16); /* Create result table. */
122 for (; *options
; options
++) {
125 settabss(L
, "source", ar
.source
);
126 settabss(L
, "short_src", ar
.short_src
);
127 settabsi(L
, "linedefined", ar
.linedefined
);
128 settabsi(L
, "lastlinedefined", ar
.lastlinedefined
);
129 settabss(L
, "what", ar
.what
);
132 settabsi(L
, "currentline", ar
.currentline
);
135 settabsi(L
, "nups", ar
.nups
);
138 settabss(L
, "name", ar
.name
);
139 settabss(L
, "namewhat", ar
.namewhat
);
141 case 'f': opt_f
= 1; break;
142 case 'L': opt_L
= 1; break;
146 if (opt_L
) treatstackoption(L
, L1
, "activelines");
147 if (opt_f
) treatstackoption(L
, L1
, "func");
148 return 1; /* Return result table. */
151 LJLIB_CF(debug_getlocal
)
154 lua_State
*L1
= getthread(L
, &arg
);
157 int slot
= lj_lib_checkint(L
, arg
+2);
158 if (tvisfunc(L
->base
+arg
)) {
159 L
->top
= L
->base
+arg
+1;
160 lua_pushstring(L
, lua_getlocal(L
, NULL
, slot
));
163 if (!lua_getstack(L1
, lj_lib_checkint(L
, arg
+1), &ar
))
164 lj_err_arg(L
, arg
+1, LJ_ERR_LVLRNG
);
165 name
= lua_getlocal(L1
, &ar
, slot
);
168 lua_pushstring(L
, name
);
169 lua_pushvalue(L
, -2);
177 LJLIB_CF(debug_setlocal
)
180 lua_State
*L1
= getthread(L
, &arg
);
183 if (!lua_getstack(L1
, lj_lib_checkint(L
, arg
+1), &ar
))
184 lj_err_arg(L
, arg
+1, LJ_ERR_LVLRNG
);
185 tv
= lj_lib_checkany(L
, arg
+3);
186 copyTV(L1
, L1
->top
++, tv
);
187 lua_pushstring(L
, lua_setlocal(L1
, &ar
, lj_lib_checkint(L
, arg
+2)));
191 static int debug_getupvalue(lua_State
*L
, int get
)
193 int32_t n
= lj_lib_checkint(L
, 2);
195 lj_lib_checkfunc(L
, 1);
196 name
= get
? lua_getupvalue(L
, 1, n
) : lua_setupvalue(L
, 1, n
);
198 lua_pushstring(L
, name
);
200 copyTV(L
, L
->top
, L
->top
-2);
207 LJLIB_CF(debug_getupvalue
)
209 return debug_getupvalue(L
, 1);
212 LJLIB_CF(debug_setupvalue
)
214 lj_lib_checkany(L
, 3);
215 return debug_getupvalue(L
, 0);
218 /* ------------------------------------------------------------------------ */
220 static const char KEY_HOOK
= 'h';
222 static void hookf(lua_State
*L
, lua_Debug
*ar
)
224 static const char *const hooknames
[] =
225 {"call", "return", "line", "count", "tail return"};
226 lua_pushlightuserdata(L
, (void *)&KEY_HOOK
);
227 lua_rawget(L
, LUA_REGISTRYINDEX
);
228 if (lua_isfunction(L
, -1)) {
229 lua_pushstring(L
, hooknames
[(int)ar
->event
]);
230 if (ar
->currentline
>= 0)
231 lua_pushinteger(L
, ar
->currentline
);
237 static int makemask(const char *smask
, int count
)
240 if (strchr(smask
, 'c')) mask
|= LUA_MASKCALL
;
241 if (strchr(smask
, 'r')) mask
|= LUA_MASKRET
;
242 if (strchr(smask
, 'l')) mask
|= LUA_MASKLINE
;
243 if (count
> 0) mask
|= LUA_MASKCOUNT
;
247 static char *unmakemask(int mask
, char *smask
)
250 if (mask
& LUA_MASKCALL
) smask
[i
++] = 'c';
251 if (mask
& LUA_MASKRET
) smask
[i
++] = 'r';
252 if (mask
& LUA_MASKLINE
) smask
[i
++] = 'l';
257 LJLIB_CF(debug_sethook
)
259 int arg
, mask
, count
;
261 (void)getthread(L
, &arg
);
262 if (lua_isnoneornil(L
, arg
+1)) {
263 lua_settop(L
, arg
+1);
264 func
= NULL
; mask
= 0; count
= 0; /* turn off hooks */
266 const char *smask
= luaL_checkstring(L
, arg
+2);
267 luaL_checktype(L
, arg
+1, LUA_TFUNCTION
);
268 count
= luaL_optint(L
, arg
+3, 0);
269 func
= hookf
; mask
= makemask(smask
, count
);
271 lua_pushlightuserdata(L
, (void *)&KEY_HOOK
);
272 lua_pushvalue(L
, arg
+1);
273 lua_rawset(L
, LUA_REGISTRYINDEX
);
274 lua_sethook(L
, func
, mask
, count
);
278 LJLIB_CF(debug_gethook
)
281 int mask
= lua_gethookmask(L
);
282 lua_Hook hook
= lua_gethook(L
);
283 if (hook
!= NULL
&& hook
!= hookf
) { /* external hook? */
284 lua_pushliteral(L
, "external hook");
286 lua_pushlightuserdata(L
, (void *)&KEY_HOOK
);
287 lua_rawget(L
, LUA_REGISTRYINDEX
); /* get hook */
289 lua_pushstring(L
, unmakemask(mask
, buff
));
290 lua_pushinteger(L
, lua_gethookcount(L
));
294 /* ------------------------------------------------------------------------ */
296 LJLIB_CF(debug_debug
)
300 fputs("lua_debug> ", stderr
);
301 if (fgets(buffer
, sizeof(buffer
), stdin
) == 0 ||
302 strcmp(buffer
, "cont\n") == 0)
304 if (luaL_loadbuffer(L
, buffer
, strlen(buffer
), "=(debug command)") ||
305 lua_pcall(L
, 0, 0, 0)) {
306 fputs(lua_tostring(L
, -1), stderr
);
309 lua_settop(L
, 0); /* remove eventual returns */
313 /* ------------------------------------------------------------------------ */
315 #define LEVELS1 12 /* size of the first part of the stack */
316 #define LEVELS2 10 /* size of the second part of the stack */
318 LJLIB_CF(debug_traceback
)
321 int firstpart
= 1; /* still before eventual `...' */
323 lua_State
*L1
= getthread(L
, &arg
);
325 if (lua_isnumber(L
, arg
+2)) {
326 level
= (int)lua_tointeger(L
, arg
+2);
330 level
= (L
== L1
) ? 1 : 0; /* level 0 may be this own function */
331 if (lua_gettop(L
) == arg
)
332 lua_pushliteral(L
, "");
333 else if (!lua_isstring(L
, arg
+1)) return 1; /* message is not a string */
334 else lua_pushliteral(L
, "\n");
335 lua_pushliteral(L
, "stack traceback:");
336 while (lua_getstack(L1
, level
++, &ar
)) {
337 if (level
> LEVELS1
&& firstpart
) {
338 /* no more than `LEVELS2' more levels? */
339 if (!lua_getstack(L1
, level
+LEVELS2
, &ar
)) {
340 level
--; /* keep going */
342 lua_pushliteral(L
, "\n\t..."); /* too many levels */
343 /* This only works with LuaJIT 2.x. Avoids O(n^2) behaviour. */
344 lua_getstack(L1
, -10, &ar
);
345 level
= ar
.i_ci
- LEVELS2
;
350 lua_pushliteral(L
, "\n\t");
351 lua_getinfo(L1
, "Snl", &ar
);
352 lua_pushfstring(L
, "%s:", ar
.short_src
);
353 if (ar
.currentline
> 0)
354 lua_pushfstring(L
, "%d:", ar
.currentline
);
355 if (*ar
.namewhat
!= '\0') { /* is there a name? */
356 lua_pushfstring(L
, " in function " LUA_QS
, ar
.name
);
358 if (*ar
.what
== 'm') /* main? */
359 lua_pushfstring(L
, " in main chunk");
360 else if (*ar
.what
== 'C' || *ar
.what
== 't')
361 lua_pushliteral(L
, " ?"); /* C function or tail call */
363 lua_pushfstring(L
, " in function <%s:%d>",
364 ar
.short_src
, ar
.linedefined
);
366 lua_concat(L
, lua_gettop(L
) - arg
);
368 lua_concat(L
, lua_gettop(L
) - arg
);
372 /* ------------------------------------------------------------------------ */
374 #include "lj_libdef.h"
376 LUALIB_API
int luaopen_debug(lua_State
*L
)
378 LJ_LIB_REG(L
, LUA_DBLIBNAME
, debug
);