Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Commit fcddd5a

Browse files
author
Mike Pall
committed
From Lua 5.2: Add luaL_traceback().
1 parent 3ad6168 commit fcddd5a

File tree

5 files changed

+59
-60
lines changed

5 files changed

+59
-60
lines changed

src/lauxlib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
8282
const char *mode);
8383
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
8484
const char *name, const char *mode);
85+
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
86+
int level);
8587

8688

8789
/*

src/lib_base.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ LJLIB_ASM(tostring) LJLIB_REC(.)
320320
s = strV(lj_lib_upvalue(L, -(int32_t)itype(o)));
321321
} else {
322322
if (tvisfunc(o) && isffunc(funcV(o)))
323-
lua_pushfstring(L, "function: fast#%d", funcV(o)->c.ffid);
323+
lua_pushfstring(L, "function: builtin#%d", funcV(o)->c.ffid);
324324
else
325325
lua_pushfstring(L, "%s: %p", lj_typename(o), lua_topointer(L, 1));
326326
/* Note: lua_pushfstring calls the GC which may invalidate o. */

src/lib_debug.c

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -383,55 +383,13 @@ LJLIB_CF(debug_debug)
383383

384384
LJLIB_CF(debug_traceback)
385385
{
386-
int level;
387-
int firstpart = 1; /* still before eventual `...' */
388386
int arg;
389387
lua_State *L1 = getthread(L, &arg);
390-
lua_Debug ar;
391-
if (lua_isnumber(L, arg+2)) {
392-
level = (int)lua_tointeger(L, arg+2);
393-
lua_pop(L, 1);
394-
}
388+
const char *msg = lua_tostring(L, arg+1);
389+
if (msg == NULL && L->top > L->base+arg)
390+
L->top = L->base+arg+1;
395391
else
396-
level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
397-
if (lua_gettop(L) == arg)
398-
lua_pushliteral(L, "");
399-
else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
400-
else lua_pushliteral(L, "\n");
401-
lua_pushliteral(L, "stack traceback:");
402-
while (lua_getstack(L1, level++, &ar)) {
403-
if (level > LEVELS1 && firstpart) {
404-
/* no more than `LEVELS2' more levels? */
405-
if (!lua_getstack(L1, level+LEVELS2, &ar)) {
406-
level--; /* keep going */
407-
} else {
408-
lua_pushliteral(L, "\n\t..."); /* too many levels */
409-
/* This only works with LuaJIT 2.x. Avoids O(n^2) behaviour. */
410-
lua_getstack(L1, -10, &ar);
411-
level = ar.i_ci - LEVELS2;
412-
}
413-
firstpart = 0;
414-
continue;
415-
}
416-
lua_pushliteral(L, "\n\t");
417-
lua_getinfo(L1, "Snl", &ar);
418-
lua_pushfstring(L, "%s:", ar.short_src);
419-
if (ar.currentline > 0)
420-
lua_pushfstring(L, "%d:", ar.currentline);
421-
if (*ar.namewhat != '\0') { /* is there a name? */
422-
lua_pushfstring(L, " in function " LUA_QS, ar.name);
423-
} else {
424-
if (*ar.what == 'm') /* main? */
425-
lua_pushfstring(L, " in main chunk");
426-
else if (*ar.what == 'C' || *ar.what == 't')
427-
lua_pushliteral(L, " ?"); /* C function or tail call */
428-
else
429-
lua_pushfstring(L, " in function <%s:%d>",
430-
ar.short_src, ar.linedefined);
431-
}
432-
lua_concat(L, lua_gettop(L) - arg);
433-
}
434-
lua_concat(L, lua_gettop(L) - arg);
392+
luaL_traceback(L, L1, msg, lj_lib_optint(L, arg+2, (L == L1)));
435393
return 1;
436394
}
437395

src/lj_debug.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,3 +543,54 @@ LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
543543
}
544544
}
545545

546+
/* Number of frames for the leading and trailing part of a traceback. */
547+
#define TRACEBACK_LEVELS1 12
548+
#define TRACEBACK_LEVELS2 10
549+
550+
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
551+
int level)
552+
{
553+
int top = (int)(L->top - L->base);
554+
int lim = TRACEBACK_LEVELS1;
555+
lua_Debug ar;
556+
if (msg) lua_pushfstring(L, "%s\n", msg);
557+
lua_pushliteral(L, "stack traceback:");
558+
while (lua_getstack(L1, level++, &ar)) {
559+
GCfunc *fn;
560+
if (level > lim) {
561+
if (!lua_getstack(L1, level + TRACEBACK_LEVELS2, &ar)) {
562+
level--;
563+
} else {
564+
lua_pushliteral(L, "\n\t...");
565+
lua_getstack(L1, -10, &ar);
566+
level = ar.i_ci - TRACEBACK_LEVELS2;
567+
}
568+
lim = 2147483647;
569+
continue;
570+
}
571+
lua_getinfo(L1, "Snlf", &ar);
572+
fn = funcV(L1->top-1); L1->top--;
573+
if (isffunc(fn) && !*ar.namewhat)
574+
lua_pushfstring(L, "\n\t[builtin#%d]:", fn->c.ffid);
575+
else
576+
lua_pushfstring(L, "\n\t%s:", ar.short_src);
577+
if (ar.currentline > 0)
578+
lua_pushfstring(L, "%d:", ar.currentline);
579+
if (*ar.namewhat) {
580+
lua_pushfstring(L, " in function " LUA_QS, ar.name);
581+
} else {
582+
if (*ar.what == 'm') {
583+
lua_pushliteral(L, " in main chunk");
584+
} else if (*ar.what == 'C') {
585+
lua_pushfstring(L, " at %p", fn->c.f);
586+
} else {
587+
lua_pushfstring(L, " in function <%s:%d>",
588+
ar.short_src, ar.linedefined);
589+
}
590+
}
591+
if ((int)(L->top - L->base) - top >= 15)
592+
lua_concat(L, (int)(L->top - L->base) - top);
593+
}
594+
lua_concat(L, (int)(L->top - L->base) - top);
595+
}
596+

src/luajit.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,7 @@ static int traceback(lua_State *L)
106106
return 1; /* Return non-string error object. */
107107
lua_remove(L, 1); /* Replace object by result of __tostring metamethod. */
108108
}
109-
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
110-
if (!lua_istable(L, -1)) {
111-
lua_pop(L, 1);
112-
return 1;
113-
}
114-
lua_getfield(L, -1, "traceback");
115-
if (!lua_isfunction(L, -1)) {
116-
lua_pop(L, 2);
117-
return 1;
118-
}
119-
lua_pushvalue(L, 1); /* Push error message. */
120-
lua_pushinteger(L, 2); /* Skip this function and debug.traceback(). */
121-
lua_call(L, 2, 1); /* Call debug.traceback(). */
109+
luaL_traceback(L, L, lua_tostring(L, 1), 1);
122110
return 1;
123111
}
124112

0 commit comments

Comments
 (0)