3 ** Copyright (C) 2005-2023 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
22 /* ------------------------------------------------------------------------ */
24 #define LJLIB_MODULE_debug
26 LJLIB_CF(debug_getregistry
)
28 copyTV(L
, L
->top
++, registry(L
));
32 LJLIB_CF(debug_getmetatable
)
34 lj_lib_checkany(L
, 1);
35 if (!lua_getmetatable(L
, 1)) {
41 LJLIB_CF(debug_setmetatable
)
43 lj_lib_checktabornil(L
, 2);
45 lua_setmetatable(L
, 1);
47 setboolV(L
->top
-1, 1);
52 LJLIB_CF(debug_getfenv
)
54 lj_lib_checkany(L
, 1);
59 LJLIB_CF(debug_setfenv
)
61 lj_lib_checktab(L
, 2);
63 if (!lua_setfenv(L
, 1))
64 lj_err_caller(L
, LJ_ERR_SETFENV
);
68 /* ------------------------------------------------------------------------ */
70 static void settabss(lua_State
*L
, const char *i
, const char *v
)
73 lua_setfield(L
, -2, i
);
76 static void settabsi(lua_State
*L
, const char *i
, int v
)
78 lua_pushinteger(L
, v
);
79 lua_setfield(L
, -2, i
);
82 static void settabsb(lua_State
*L
, const char *i
, int v
)
84 lua_pushboolean(L
, v
);
85 lua_setfield(L
, -2, i
);
88 static lua_State
*getthread(lua_State
*L
, int *arg
)
90 if (L
->base
< L
->top
&& tvisthread(L
->base
)) {
92 return threadV(L
->base
);
99 static void treatstackoption(lua_State
*L
, lua_State
*L1
, const char *fname
)
102 lua_pushvalue(L
, -2);
107 lua_setfield(L
, -2, fname
);
110 LJLIB_CF(debug_getinfo
)
113 int arg
, opt_f
= 0, opt_L
= 0;
114 lua_State
*L1
= getthread(L
, &arg
);
115 const char *options
= luaL_optstring(L
, arg
+2, "flnSu");
116 if (lua_isnumber(L
, arg
+1)) {
117 if (!lua_getstack(L1
, (int)lua_tointeger(L
, arg
+1), (lua_Debug
*)&ar
)) {
121 } else if (L
->base
+arg
< L
->top
&& tvisfunc(L
->base
+arg
)) {
122 options
= lua_pushfstring(L
, ">%s", options
);
123 setfuncV(L1
, L1
->top
++, funcV(L
->base
+arg
));
125 lj_err_arg(L
, arg
+1, LJ_ERR_NOFUNCL
);
127 if (!lj_debug_getinfo(L1
, options
, &ar
, 1))
128 lj_err_arg(L
, arg
+2, LJ_ERR_INVOPT
);
129 lua_createtable(L
, 0, 16); /* Create result table. */
130 for (; *options
; options
++) {
133 settabss(L
, "source", ar
.source
);
134 settabss(L
, "short_src", ar
.short_src
);
135 settabsi(L
, "linedefined", ar
.linedefined
);
136 settabsi(L
, "lastlinedefined", ar
.lastlinedefined
);
137 settabss(L
, "what", ar
.what
);
140 settabsi(L
, "currentline", ar
.currentline
);
143 settabsi(L
, "nups", ar
.nups
);
144 settabsi(L
, "nparams", ar
.nparams
);
145 settabsb(L
, "isvararg", ar
.isvararg
);
148 settabss(L
, "name", ar
.name
);
149 settabss(L
, "namewhat", ar
.namewhat
);
151 case 'f': opt_f
= 1; break;
152 case 'L': opt_L
= 1; break;
156 if (opt_L
) treatstackoption(L
, L1
, "activelines");
157 if (opt_f
) treatstackoption(L
, L1
, "func");
158 return 1; /* Return result table. */
161 LJLIB_CF(debug_getlocal
)
164 lua_State
*L1
= getthread(L
, &arg
);
167 int slot
= lj_lib_checkint(L
, arg
+2);
168 if (tvisfunc(L
->base
+arg
)) {
169 L
->top
= L
->base
+arg
+1;
170 lua_pushstring(L
, lua_getlocal(L
, NULL
, slot
));
173 if (!lua_getstack(L1
, lj_lib_checkint(L
, arg
+1), &ar
))
174 lj_err_arg(L
, arg
+1, LJ_ERR_LVLRNG
);
175 name
= lua_getlocal(L1
, &ar
, slot
);
178 lua_pushstring(L
, name
);
179 lua_pushvalue(L
, -2);
187 LJLIB_CF(debug_setlocal
)
190 lua_State
*L1
= getthread(L
, &arg
);
193 if (!lua_getstack(L1
, lj_lib_checkint(L
, arg
+1), &ar
))
194 lj_err_arg(L
, arg
+1, LJ_ERR_LVLRNG
);
195 tv
= lj_lib_checkany(L
, arg
+3);
196 copyTV(L1
, L1
->top
++, tv
);
197 lua_pushstring(L
, lua_setlocal(L1
, &ar
, lj_lib_checkint(L
, arg
+2)));
201 static int debug_getupvalue(lua_State
*L
, int get
)
203 int32_t n
= lj_lib_checkint(L
, 2);
205 lj_lib_checkfunc(L
, 1);
206 name
= get
? lua_getupvalue(L
, 1, n
) : lua_setupvalue(L
, 1, n
);
208 lua_pushstring(L
, name
);
210 copyTV(L
, L
->top
, L
->top
-2);
217 LJLIB_CF(debug_getupvalue
)
219 return debug_getupvalue(L
, 1);
222 LJLIB_CF(debug_setupvalue
)
224 lj_lib_checkany(L
, 3);
225 return debug_getupvalue(L
, 0);
228 LJLIB_CF(debug_upvalueid
)
230 GCfunc
*fn
= lj_lib_checkfunc(L
, 1);
231 int32_t n
= lj_lib_checkint(L
, 2) - 1;
232 if ((uint32_t)n
>= fn
->l
.nupvalues
)
233 lj_err_arg(L
, 2, LJ_ERR_IDXRNG
);
234 setlightudV(L
->top
-1, isluafunc(fn
) ? (void *)gcref(fn
->l
.uvptr
[n
]) :
235 (void *)&fn
->c
.upvalue
[n
]);
239 LJLIB_CF(debug_upvaluejoin
)
244 for (i
= 0; i
< 2; i
++) {
246 fn
[i
] = lj_lib_checkfunc(L
, 2*i
+1);
247 if (!isluafunc(fn
[i
]))
248 lj_err_arg(L
, 2*i
+1, LJ_ERR_NOLFUNC
);
249 n
= lj_lib_checkint(L
, 2*i
+2) - 1;
250 if ((uint32_t)n
>= fn
[i
]->l
.nupvalues
)
251 lj_err_arg(L
, 2*i
+2, LJ_ERR_IDXRNG
);
252 p
[i
] = &fn
[i
]->l
.uvptr
[n
];
254 setgcrefr(*p
[0], *p
[1]);
255 lj_gc_objbarrier(L
, fn
[0], gcref(*p
[1]));
260 LJLIB_CF(debug_getuservalue
)
263 if (o
< L
->top
&& tvisudata(o
))
264 settabV(L
, o
, tabref(udataV(o
)->env
));
271 LJLIB_CF(debug_setuservalue
)
274 if (!(o
< L
->top
&& tvisudata(o
)))
275 lj_err_argt(L
, 1, LUA_TUSERDATA
);
276 if (!(o
+1 < L
->top
&& tvistab(o
+1)))
277 lj_err_argt(L
, 2, LUA_TTABLE
);
284 /* ------------------------------------------------------------------------ */
286 static const char KEY_HOOK
= 'h';
288 static void hookf(lua_State
*L
, lua_Debug
*ar
)
290 static const char *const hooknames
[] =
291 {"call", "return", "line", "count", "tail return"};
292 lua_pushlightuserdata(L
, (void *)&KEY_HOOK
);
293 lua_rawget(L
, LUA_REGISTRYINDEX
);
294 if (lua_isfunction(L
, -1)) {
295 lua_pushstring(L
, hooknames
[(int)ar
->event
]);
296 if (ar
->currentline
>= 0)
297 lua_pushinteger(L
, ar
->currentline
);
303 static int makemask(const char *smask
, int count
)
306 if (strchr(smask
, 'c')) mask
|= LUA_MASKCALL
;
307 if (strchr(smask
, 'r')) mask
|= LUA_MASKRET
;
308 if (strchr(smask
, 'l')) mask
|= LUA_MASKLINE
;
309 if (count
> 0) mask
|= LUA_MASKCOUNT
;
313 static char *unmakemask(int mask
, char *smask
)
316 if (mask
& LUA_MASKCALL
) smask
[i
++] = 'c';
317 if (mask
& LUA_MASKRET
) smask
[i
++] = 'r';
318 if (mask
& LUA_MASKLINE
) smask
[i
++] = 'l';
323 LJLIB_CF(debug_sethook
)
325 int arg
, mask
, count
;
327 (void)getthread(L
, &arg
);
328 if (lua_isnoneornil(L
, arg
+1)) {
329 lua_settop(L
, arg
+1);
330 func
= NULL
; mask
= 0; count
= 0; /* turn off hooks */
332 const char *smask
= luaL_checkstring(L
, arg
+2);
333 luaL_checktype(L
, arg
+1, LUA_TFUNCTION
);
334 count
= luaL_optint(L
, arg
+3, 0);
335 func
= hookf
; mask
= makemask(smask
, count
);
337 lua_pushlightuserdata(L
, (void *)&KEY_HOOK
);
338 lua_pushvalue(L
, arg
+1);
339 lua_rawset(L
, LUA_REGISTRYINDEX
);
340 lua_sethook(L
, func
, mask
, count
);
344 LJLIB_CF(debug_gethook
)
347 int mask
= lua_gethookmask(L
);
348 lua_Hook hook
= lua_gethook(L
);
349 if (hook
!= NULL
&& hook
!= hookf
) { /* external hook? */
350 lua_pushliteral(L
, "external hook");
352 lua_pushlightuserdata(L
, (void *)&KEY_HOOK
);
353 lua_rawget(L
, LUA_REGISTRYINDEX
); /* get hook */
355 lua_pushstring(L
, unmakemask(mask
, buff
));
356 lua_pushinteger(L
, lua_gethookcount(L
));
360 /* ------------------------------------------------------------------------ */
362 LJLIB_CF(debug_debug
)
366 fputs("lua_debug> ", stderr
);
367 if (fgets(buffer
, sizeof(buffer
), stdin
) == 0 ||
368 strcmp(buffer
, "cont\n") == 0)
370 if (luaL_loadbuffer(L
, buffer
, strlen(buffer
), "=(debug command)") ||
371 lua_pcall(L
, 0, 0, 0)) {
372 const char *s
= lua_tostring(L
, -1);
373 fputs(s
? s
: "(error object is not a string)", stderr
);
376 lua_settop(L
, 0); /* remove eventual returns */
380 /* ------------------------------------------------------------------------ */
382 #define LEVELS1 12 /* size of the first part of the stack */
383 #define LEVELS2 10 /* size of the second part of the stack */
385 LJLIB_CF(debug_traceback
)
388 lua_State
*L1
= getthread(L
, &arg
);
389 const char *msg
= lua_tostring(L
, arg
+1);
390 if (msg
== NULL
&& L
->top
> L
->base
+arg
)
391 L
->top
= L
->base
+arg
+1;
393 luaL_traceback(L
, L1
, msg
, lj_lib_optint(L
, arg
+2, (L
== L1
)));
397 /* ------------------------------------------------------------------------ */
399 #include "lj_libdef.h"
401 LUALIB_API
int luaopen_debug(lua_State
*L
)
403 LJ_LIB_REG(L
, LUA_DBLIBNAME
, debug
);