27static const char *
const HOOKKEY =
"_HOOKKEY";
36 if (l_unlikely(L != L1 && !lua_checkstack(L1, n)))
37 luaL_error(L,
"stack overflow");
42 lua_pushvalue(L, LUA_REGISTRYINDEX);
47static int db_getmetatable (
lua_State *L) {
49 if (!lua_getmetatable(L, 1)) {
56static int db_setmetatable (
lua_State *L) {
57 int t = lua_type(L, 2);
58 luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table");
60 lua_setmetatable(L, 1);
65static int db_getuservalue (
lua_State *L) {
66 int n = (int)luaL_optinteger(L, 2, 1);
67 if (lua_type(L, 1) != LUA_TUSERDATA)
69 else if (lua_getiuservalue(L, 1, n) != LUA_TNONE) {
70 lua_pushboolean(L, 1);
77static int db_setuservalue (
lua_State *L) {
78 int n = (int)luaL_optinteger(L, 3, 1);
79 luaL_checktype(L, 1, LUA_TUSERDATA);
82 if (!lua_setiuservalue(L, 1, n))
95 if (lua_isthread(L, 1)) {
97 return lua_tothread(L, 1);
111static void settabss (
lua_State *L,
const char *k,
const char *v) {
112 lua_pushstring(L, v);
113 lua_setfield(L, -2, k);
116static void settabsi (
lua_State *L,
const char *k,
int v) {
117 lua_pushinteger(L, v);
118 lua_setfield(L, -2, k);
121static void settabsb (
lua_State *L,
const char *k,
int v) {
122 lua_pushboolean(L, v);
123 lua_setfield(L, -2, k);
136 lua_rotate(L, -2, 1);
139 lua_setfield(L, -2, fname);
153 const char *options = luaL_optstring(L, arg+2,
"flnSrtu");
154 checkstack(L, L1, 3);
155 luaL_argcheck(L, options[0] !=
'>', arg + 2,
"invalid option '>'");
156 if (lua_isfunction(L, arg + 1)) {
157 options = lua_pushfstring(L,
">%s", options);
158 lua_pushvalue(L, arg + 1);
162 if (!lua_getstack(L1, (
int)luaL_checkinteger(L, arg + 1), &ar)) {
167 if (!lua_getinfo(L1, options, &ar))
168 return luaL_argerror(L, arg+2,
"invalid option");
170 if (strchr(options,
'S')) {
171 lua_pushlstring(L, ar.source, ar.srclen);
172 lua_setfield(L, -2,
"source");
173 settabss(L,
"short_src", ar.short_src);
174 settabsi(L,
"linedefined", ar.linedefined);
175 settabsi(L,
"lastlinedefined", ar.lastlinedefined);
176 settabss(L,
"what", ar.what);
178 if (strchr(options,
'l'))
179 settabsi(L,
"currentline", ar.currentline);
180 if (strchr(options,
'u')) {
181 settabsi(L,
"nups", ar.nups);
182 settabsi(L,
"nparams", ar.nparams);
183 settabsb(L,
"isvararg", ar.isvararg);
185 if (strchr(options,
'n')) {
186 settabss(L,
"name", ar.name);
187 settabss(L,
"namewhat", ar.namewhat);
189 if (strchr(options,
'r')) {
190 settabsi(L,
"ftransfer", ar.ftransfer);
191 settabsi(L,
"ntransfer", ar.ntransfer);
193 if (strchr(options,
't'))
194 settabsb(L,
"istailcall", ar.istailcall);
195 if (strchr(options,
'L'))
196 treatstackoption(L, L1,
"activelines");
197 if (strchr(options,
'f'))
198 treatstackoption(L, L1,
"func");
206 int nvar = (int)luaL_checkinteger(L, arg + 2);
207 if (lua_isfunction(L, arg + 1)) {
208 lua_pushvalue(L, arg + 1);
209 lua_pushstring(L, lua_getlocal(L, NULL, nvar));
215 int level = (int)luaL_checkinteger(L, arg + 1);
216 if (l_unlikely(!lua_getstack(L1, level, &ar)))
217 return luaL_argerror(L, arg+1,
"level out of range");
218 checkstack(L, L1, 1);
219 name = lua_getlocal(L1, &ar, nvar);
222 lua_pushstring(L, name);
223 lua_rotate(L, -2, 1);
239 int level = (int)luaL_checkinteger(L, arg + 1);
240 int nvar = (int)luaL_checkinteger(L, arg + 2);
241 if (l_unlikely(!lua_getstack(L1, level, &ar)))
242 return luaL_argerror(L, arg+1,
"level out of range");
243 luaL_checkany(L, arg+3);
244 lua_settop(L, arg+3);
245 checkstack(L, L1, 1);
247 name = lua_setlocal(L1, &ar, nvar);
250 lua_pushstring(L, name);
258static int auxupvalue (
lua_State *L,
int get) {
260 int n = (int)luaL_checkinteger(L, 2);
261 luaL_checktype(L, 1, LUA_TFUNCTION);
262 name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
263 if (name == NULL)
return 0;
264 lua_pushstring(L, name);
265 lua_insert(L, -(get+1));
271 return auxupvalue(L, 1);
277 return auxupvalue(L, 0);
285static void *checkupval (
lua_State *L,
int argf,
int argnup,
int *pnup) {
287 int nup = (int)luaL_checkinteger(L, argnup);
288 luaL_checktype(L, argf, LUA_TFUNCTION);
289 id = lua_upvalueid(L, argf, nup);
291 luaL_argcheck(L,
id != NULL, argnup,
"invalid upvalue index");
299 void *
id = checkupval(L, 1, 2, NULL);
301 lua_pushlightuserdata(L,
id);
308static int db_upvaluejoin (
lua_State *L) {
310 checkupval(L, 1, 2, &n1);
311 checkupval(L, 3, 4, &n2);
312 luaL_argcheck(L, !lua_iscfunction(L, 1), 1,
"Lua function expected");
313 luaL_argcheck(L, !lua_iscfunction(L, 3), 3,
"Lua function expected");
314 lua_upvaluejoin(L, 1, n1, 3, n2);
324 static const char *
const hooknames[] =
325 {
"call",
"return",
"line",
"count",
"tail call"};
326 lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY);
328 if (lua_rawget(L, -2) == LUA_TFUNCTION) {
329 lua_pushstring(L, hooknames[(
int)ar->event]);
330 if (ar->currentline >= 0)
331 lua_pushinteger(L, ar->currentline);
333 lua_assert(lua_getinfo(L,
"lS", ar));
342static int makemask (
const char *smask,
int count) {
344 if (strchr(smask,
'c')) mask |= LUA_MASKCALL;
345 if (strchr(smask,
'r')) mask |= LUA_MASKRET;
346 if (strchr(smask,
'l')) mask |= LUA_MASKLINE;
347 if (count > 0) mask |= LUA_MASKCOUNT;
355static char *unmakemask (
int mask,
char *smask) {
357 if (mask & LUA_MASKCALL) smask[i++] =
'c';
358 if (mask & LUA_MASKRET) smask[i++] =
'r';
359 if (mask & LUA_MASKLINE) smask[i++] =
'l';
366 int arg, mask, count;
369 if (lua_isnoneornil(L, arg+1)) {
370 lua_settop(L, arg+1);
371 func = NULL; mask = 0; count = 0;
374 const char *smask = luaL_checkstring(L, arg+2);
375 luaL_checktype(L, arg+1, LUA_TFUNCTION);
376 count = (int)luaL_optinteger(L, arg + 3, 0);
377 func = hookf; mask = makemask(smask, count);
379 if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) {
381 lua_pushliteral(L,
"k");
382 lua_setfield(L, -2,
"__mode");
383 lua_pushvalue(L, -1);
384 lua_setmetatable(L, -2);
386 checkstack(L, L1, 1);
387 lua_pushthread(L1); lua_xmove(L1, L, 1);
388 lua_pushvalue(L, arg + 1);
390 lua_sethook(L1, func, mask, count);
399 int mask = lua_gethookmask(L1);
400 lua_Hook hook = lua_gethook(L1);
405 else if (hook != hookf)
406 lua_pushliteral(L,
"external hook");
408 lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY);
409 checkstack(L, L1, 1);
410 lua_pushthread(L1); lua_xmove(L1, L, 1);
414 lua_pushstring(L, unmakemask(mask, buff));
415 lua_pushinteger(L, lua_gethookcount(L1));
423 lua_writestringerror(
"%s",
"lua_debug> ");
424 if (fgets(buffer,
sizeof(buffer), stdin) == NULL ||
425 strcmp(buffer,
"cont\n") == 0)
427 if (luaL_loadbuffer(L, buffer, strlen(buffer),
"=(debug command)") ||
428 lua_pcall(L, 0, 0, 0))
429 lua_writestringerror(
"%s\n", luaL_tolstring(L, -1, NULL));
438 const char *msg = lua_tostring(L, arg + 1);
439 if (msg == NULL && !lua_isnoneornil(L, arg + 1))
440 lua_pushvalue(L, arg + 1);
442 int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
443 luaL_traceback(L, L1, msg, level);
449static int db_setcstacklimit (
lua_State *L) {
450 int limit = (int)luaL_checkinteger(L, 1);
451 int res = lua_setcstacklimit(L, limit);
452 lua_pushinteger(L, res);
459 {
"getuservalue", db_getuservalue},
460 {
"gethook", db_gethook},
461 {
"getinfo", db_getinfo},
462 {
"getlocal", db_getlocal},
463 {
"getregistry", db_getregistry},
464 {
"getmetatable", db_getmetatable},
465 {
"getupvalue", db_getupvalue},
466 {
"upvaluejoin", db_upvaluejoin},
467 {
"upvalueid", db_upvalueid},
468 {
"setuservalue", db_setuservalue},
469 {
"sethook", db_sethook},
470 {
"setlocal", db_setlocal},
471 {
"setmetatable", db_setmetatable},
472 {
"setupvalue", db_setupvalue},
473 {
"traceback", db_traceback},
474 {
"setcstacklimit", db_setcstacklimit},
479LUAMOD_API
int luaopen_debug (
lua_State *L) {
480 luaL_newlib(L, dblib);