beta-0.89.2
[luatex.git] / source / libs / luajit / LuaJIT-src / src / lj_debug.c
blob3226d03b9e187251d75ffd85de9d972c446a3135
1 /*
2 ** Debugging and introspection.
3 ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
4 */
6 #define lj_debug_c
7 #define LUA_CORE
9 #include "lj_obj.h"
10 #include "lj_err.h"
11 #include "lj_debug.h"
12 #include "lj_buf.h"
13 #include "lj_tab.h"
14 #include "lj_state.h"
15 #include "lj_frame.h"
16 #include "lj_bc.h"
17 #include "lj_strfmt.h"
18 #if LJ_HASJIT
19 #include "lj_jit.h"
20 #endif
22 /* -- Frames -------------------------------------------------------------- */
24 /* Get frame corresponding to a level. */
25 cTValue *lj_debug_frame(lua_State *L, int level, int *size)
27 cTValue *frame, *nextframe, *bot = tvref(L->stack)+LJ_FR2;
28 /* Traverse frames backwards. */
29 for (nextframe = frame = L->base-1; frame > bot; ) {
30 if (frame_gc(frame) == obj2gco(L))
31 level++; /* Skip dummy frames. See lj_err_optype_call(). */
32 if (level-- == 0) {
33 *size = (int)(nextframe - frame);
34 return frame; /* Level found. */
36 nextframe = frame;
37 if (frame_islua(frame)) {
38 frame = frame_prevl(frame);
39 } else {
40 if (frame_isvarg(frame))
41 level++; /* Skip vararg pseudo-frame. */
42 frame = frame_prevd(frame);
45 *size = level;
46 return NULL; /* Level not found. */
49 /* Invalid bytecode position. */
50 #define NO_BCPOS (~(BCPos)0)
52 /* Return bytecode position for function/frame or NO_BCPOS. */
53 static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
55 const BCIns *ins;
56 GCproto *pt;
57 BCPos pos;
58 lua_assert(fn->c.gct == ~LJ_TFUNC || fn->c.gct == ~LJ_TTHREAD);
59 if (!isluafunc(fn)) { /* Cannot derive a PC for non-Lua functions. */
60 return NO_BCPOS;
61 } else if (nextframe == NULL) { /* Lua function on top. */
62 void *cf = cframe_raw(L->cframe);
63 if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
64 return NO_BCPOS;
65 ins = cframe_pc(cf); /* Only happens during error/hook handling. */
66 } else {
67 if (frame_islua(nextframe)) {
68 ins = frame_pc(nextframe);
69 } else if (frame_iscont(nextframe)) {
70 ins = frame_contpc(nextframe);
71 } else {
72 /* Lua function below errfunc/gc/hook: find cframe to get the PC. */
73 void *cf = cframe_raw(L->cframe);
74 TValue *f = L->base-1;
75 for (;;) {
76 if (cf == NULL)
77 return NO_BCPOS;
78 while (cframe_nres(cf) < 0) {
79 if (f >= restorestack(L, -cframe_nres(cf)))
80 break;
81 cf = cframe_raw(cframe_prev(cf));
82 if (cf == NULL)
83 return NO_BCPOS;
85 if (f < nextframe)
86 break;
87 if (frame_islua(f)) {
88 f = frame_prevl(f);
89 } else {
90 if (frame_isc(f) || (frame_iscont(f) && frame_iscont_fficb(f)))
91 cf = cframe_raw(cframe_prev(cf));
92 f = frame_prevd(f);
95 ins = cframe_pc(cf);
98 pt = funcproto(fn);
99 pos = proto_bcpos(pt, ins) - 1;
100 #if LJ_HASJIT
101 if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
102 GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
103 lua_assert(bc_isret(bc_op(ins[-1])));
104 pos = proto_bcpos(pt, mref(T->startpc, const BCIns));
106 #endif
107 return pos;
110 /* -- Line numbers -------------------------------------------------------- */
112 /* Get line number for a bytecode position. */
113 BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc)
115 const void *lineinfo = proto_lineinfo(pt);
116 if (pc <= pt->sizebc && lineinfo) {
117 BCLine first = pt->firstline;
118 if (pc == pt->sizebc) return first + pt->numline;
119 if (pc-- == 0) return first;
120 if (pt->numline < 256)
121 return first + (BCLine)((const uint8_t *)lineinfo)[pc];
122 else if (pt->numline < 65536)
123 return first + (BCLine)((const uint16_t *)lineinfo)[pc];
124 else
125 return first + (BCLine)((const uint32_t *)lineinfo)[pc];
127 return 0;
130 /* Get line number for function/frame. */
131 static BCLine debug_frameline(lua_State *L, GCfunc *fn, cTValue *nextframe)
133 BCPos pc = debug_framepc(L, fn, nextframe);
134 if (pc != NO_BCPOS) {
135 GCproto *pt = funcproto(fn);
136 lua_assert(pc <= pt->sizebc);
137 return lj_debug_line(pt, pc);
139 return -1;
142 /* -- Variable names ------------------------------------------------------ */
144 /* Get name of a local variable from slot number and PC. */
145 static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
147 const char *p = (const char *)proto_varinfo(pt);
148 if (p) {
149 BCPos lastpc = 0;
150 for (;;) {
151 const char *name = p;
152 uint32_t vn = *(const uint8_t *)p;
153 BCPos startpc, endpc;
154 if (vn < VARNAME__MAX) {
155 if (vn == VARNAME_END) break; /* End of varinfo. */
156 } else {
157 do { p++; } while (*(const uint8_t *)p); /* Skip over variable name. */
159 p++;
160 lastpc = startpc = lastpc + lj_buf_ruleb128(&p);
161 if (startpc > pc) break;
162 endpc = startpc + lj_buf_ruleb128(&p);
163 if (pc < endpc && slot-- == 0) {
164 if (vn < VARNAME__MAX) {
165 #define VARNAMESTR(name, str) str "\0"
166 name = VARNAMEDEF(VARNAMESTR);
167 #undef VARNAMESTR
168 if (--vn) while (*name++ || --vn) ;
170 return name;
174 return NULL;
177 /* Get name of local variable from 1-based slot number and function/frame. */
178 static TValue *debug_localname(lua_State *L, const lua_Debug *ar,
179 const char **name, BCReg slot1)
181 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
182 uint32_t size = (uint32_t)ar->i_ci >> 16;
183 TValue *frame = tvref(L->stack) + offset;
184 TValue *nextframe = size ? frame + size : NULL;
185 GCfunc *fn = frame_func(frame);
186 BCPos pc = debug_framepc(L, fn, nextframe);
187 if (!nextframe) nextframe = L->top+LJ_FR2;
188 if ((int)slot1 < 0) { /* Negative slot number is for varargs. */
189 if (pc != NO_BCPOS) {
190 GCproto *pt = funcproto(fn);
191 if ((pt->flags & PROTO_VARARG)) {
192 slot1 = pt->numparams + (BCReg)(-(int)slot1);
193 if (frame_isvarg(frame)) { /* Vararg frame has been set up? (pc!=0) */
194 nextframe = frame;
195 frame = frame_prevd(frame);
197 if (frame + slot1+LJ_FR2 < nextframe) {
198 *name = "(*vararg)";
199 return frame+slot1;
203 return NULL;
205 if (pc != NO_BCPOS &&
206 (*name = debug_varname(funcproto(fn), pc, slot1-1)) != NULL)
208 else if (slot1 > 0 && frame + slot1+LJ_FR2 < nextframe)
209 *name = "(*temporary)";
210 return frame+slot1;
213 /* Get name of upvalue. */
214 const char *lj_debug_uvname(GCproto *pt, uint32_t idx)
216 const uint8_t *p = proto_uvinfo(pt);
217 lua_assert(idx < pt->sizeuv);
218 if (!p) return "";
219 if (idx) while (*p++ || --idx) ;
220 return (const char *)p;
223 /* Get name and value of upvalue. */
224 const char *lj_debug_uvnamev(cTValue *o, uint32_t idx, TValue **tvp)
226 if (tvisfunc(o)) {
227 GCfunc *fn = funcV(o);
228 if (isluafunc(fn)) {
229 GCproto *pt = funcproto(fn);
230 if (idx < pt->sizeuv) {
231 *tvp = uvval(&gcref(fn->l.uvptr[idx])->uv);
232 return lj_debug_uvname(pt, idx);
234 } else {
235 if (idx < fn->c.nupvalues) {
236 *tvp = &fn->c.upvalue[idx];
237 return "";
241 return NULL;
244 /* Deduce name of an object from slot number and PC. */
245 const char *lj_debug_slotname(GCproto *pt, const BCIns *ip, BCReg slot,
246 const char **name)
248 const char *lname;
249 restart:
250 lname = debug_varname(pt, proto_bcpos(pt, ip), slot);
251 if (lname != NULL) { *name = lname; return "local"; }
252 while (--ip > proto_bc(pt)) {
253 BCIns ins = *ip;
254 BCOp op = bc_op(ins);
255 BCReg ra = bc_a(ins);
256 if (bcmode_a(op) == BCMbase) {
257 if (slot >= ra && (op != BC_KNIL || slot <= bc_d(ins)))
258 return NULL;
259 } else if (bcmode_a(op) == BCMdst && ra == slot) {
260 switch (bc_op(ins)) {
261 case BC_MOV:
262 if (ra == slot) { slot = bc_d(ins); goto restart; }
263 break;
264 case BC_GGET:
265 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_d(ins))));
266 return "global";
267 case BC_TGETS:
268 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
269 if (ip > proto_bc(pt)) {
270 BCIns insp = ip[-1];
271 if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1+LJ_FR2 &&
272 bc_d(insp) == bc_b(ins))
273 return "method";
275 return "field";
276 case BC_UGET:
277 *name = lj_debug_uvname(pt, bc_d(ins));
278 return "upvalue";
279 default:
280 return NULL;
284 return NULL;
287 /* Deduce function name from caller of a frame. */
288 const char *lj_debug_funcname(lua_State *L, cTValue *frame, const char **name)
290 cTValue *pframe;
291 GCfunc *fn;
292 BCPos pc;
293 if (frame <= tvref(L->stack)+LJ_FR2)
294 return NULL;
295 if (frame_isvarg(frame))
296 frame = frame_prevd(frame);
297 pframe = frame_prev(frame);
298 fn = frame_func(pframe);
299 pc = debug_framepc(L, fn, frame);
300 if (pc != NO_BCPOS) {
301 GCproto *pt = funcproto(fn);
302 const BCIns *ip = &proto_bc(pt)[check_exp(pc < pt->sizebc, pc)];
303 MMS mm = bcmode_mm(bc_op(*ip));
304 if (mm == MM_call) {
305 BCReg slot = bc_a(*ip);
306 if (bc_op(*ip) == BC_ITERC) slot -= 3;
307 return lj_debug_slotname(pt, ip, slot, name);
308 } else if (mm != MM__MAX) {
309 *name = strdata(mmname_str(G(L), mm));
310 return "metamethod";
313 return NULL;
316 /* -- Source code locations ----------------------------------------------- */
318 /* Generate shortened source name. */
319 void lj_debug_shortname(char *out, GCstr *str, BCLine line)
321 const char *src = strdata(str);
322 if (*src == '=') {
323 strncpy(out, src+1, LUA_IDSIZE); /* Remove first char. */
324 out[LUA_IDSIZE-1] = '\0'; /* Ensures null termination. */
325 } else if (*src == '@') { /* Output "source", or "...source". */
326 size_t len = str->len-1;
327 src++; /* Skip the `@' */
328 if (len >= LUA_IDSIZE) {
329 src += len-(LUA_IDSIZE-4); /* Get last part of file name. */
330 *out++ = '.'; *out++ = '.'; *out++ = '.';
332 strcpy(out, src);
333 } else { /* Output [string "string"] or [builtin:name]. */
334 size_t len; /* Length, up to first control char. */
335 for (len = 0; len < LUA_IDSIZE-12; len++)
336 if (((const unsigned char *)src)[len] < ' ') break;
337 strcpy(out, line == ~(BCLine)0 ? "[builtin:" : "[string \""); out += 9;
338 if (src[len] != '\0') { /* Must truncate? */
339 if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
340 strncpy(out, src, len); out += len;
341 strcpy(out, "..."); out += 3;
342 } else {
343 strcpy(out, src); out += len;
345 strcpy(out, line == ~(BCLine)0 ? "]" : "\"]");
349 /* Add current location of a frame to error message. */
350 void lj_debug_addloc(lua_State *L, const char *msg,
351 cTValue *frame, cTValue *nextframe)
353 if (frame) {
354 GCfunc *fn = frame_func(frame);
355 if (isluafunc(fn)) {
356 BCLine line = debug_frameline(L, fn, nextframe);
357 if (line >= 0) {
358 GCproto *pt = funcproto(fn);
359 char buf[LUA_IDSIZE];
360 lj_debug_shortname(buf, proto_chunkname(pt), pt->firstline);
361 lj_strfmt_pushf(L, "%s:%d: %s", buf, line, msg);
362 return;
366 lj_strfmt_pushf(L, "%s", msg);
369 /* Push location string for a bytecode position to Lua stack. */
370 void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc)
372 GCstr *name = proto_chunkname(pt);
373 const char *s = strdata(name);
374 MSize i, len = name->len;
375 BCLine line = lj_debug_line(pt, pc);
376 if (pt->firstline == ~(BCLine)0) {
377 lj_strfmt_pushf(L, "builtin:%s", s);
378 } else if (*s == '@') {
379 s++; len--;
380 for (i = len; i > 0; i--)
381 if (s[i] == '/' || s[i] == '\\') {
382 s += i+1;
383 break;
385 lj_strfmt_pushf(L, "%s:%d", s, line);
386 } else if (len > 40) {
387 lj_strfmt_pushf(L, "%p:%d", pt, line);
388 } else if (*s == '=') {
389 lj_strfmt_pushf(L, "%s:%d", s+1, line);
390 } else {
391 lj_strfmt_pushf(L, "\"%s\":%d", s, line);
395 /* -- Public debug API ---------------------------------------------------- */
397 /* lua_getupvalue() and lua_setupvalue() are in lj_api.c. */
399 LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n)
401 const char *name = NULL;
402 if (ar) {
403 TValue *o = debug_localname(L, ar, &name, (BCReg)n);
404 if (name) {
405 copyTV(L, L->top, o);
406 incr_top(L);
408 } else if (tvisfunc(L->top-1) && isluafunc(funcV(L->top-1))) {
409 name = debug_varname(funcproto(funcV(L->top-1)), 0, (BCReg)n-1);
411 return name;
414 LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n)
416 const char *name = NULL;
417 TValue *o = debug_localname(L, ar, &name, (BCReg)n);
418 if (name)
419 copyTV(L, o, L->top-1);
420 L->top--;
421 return name;
424 int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar, int ext)
426 int opt_f = 0, opt_L = 0;
427 TValue *frame = NULL;
428 TValue *nextframe = NULL;
429 GCfunc *fn;
430 if (*what == '>') {
431 TValue *func = L->top - 1;
432 api_check(L, tvisfunc(func));
433 fn = funcV(func);
434 L->top--;
435 what++;
436 } else {
437 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
438 uint32_t size = (uint32_t)ar->i_ci >> 16;
439 lua_assert(offset != 0);
440 frame = tvref(L->stack) + offset;
441 if (size) nextframe = frame + size;
442 lua_assert(frame <= tvref(L->maxstack) &&
443 (!nextframe || nextframe <= tvref(L->maxstack)));
444 fn = frame_func(frame);
445 lua_assert(fn->c.gct == ~LJ_TFUNC);
447 for (; *what; what++) {
448 if (*what == 'S') {
449 if (isluafunc(fn)) {
450 GCproto *pt = funcproto(fn);
451 BCLine firstline = pt->firstline;
452 GCstr *name = proto_chunkname(pt);
453 ar->source = strdata(name);
454 lj_debug_shortname(ar->short_src, name, pt->firstline);
455 ar->linedefined = (int)firstline;
456 ar->lastlinedefined = (int)(firstline + pt->numline);
457 ar->what = (firstline || !pt->numline) ? "Lua" : "main";
458 } else {
459 ar->source = "=[C]";
460 ar->short_src[0] = '[';
461 ar->short_src[1] = 'C';
462 ar->short_src[2] = ']';
463 ar->short_src[3] = '\0';
464 ar->linedefined = -1;
465 ar->lastlinedefined = -1;
466 ar->what = "C";
468 } else if (*what == 'l') {
469 ar->currentline = frame ? debug_frameline(L, fn, nextframe) : -1;
470 } else if (*what == 'u') {
471 ar->nups = fn->c.nupvalues;
472 if (ext) {
473 if (isluafunc(fn)) {
474 GCproto *pt = funcproto(fn);
475 ar->nparams = pt->numparams;
476 ar->isvararg = !!(pt->flags & PROTO_VARARG);
477 } else {
478 ar->nparams = 0;
479 ar->isvararg = 1;
482 } else if (*what == 'n') {
483 ar->namewhat = frame ? lj_debug_funcname(L, frame, &ar->name) : NULL;
484 if (ar->namewhat == NULL) {
485 ar->namewhat = "";
486 ar->name = NULL;
488 } else if (*what == 'f') {
489 opt_f = 1;
490 } else if (*what == 'L') {
491 opt_L = 1;
492 } else {
493 return 0; /* Bad option. */
496 if (opt_f) {
497 setfuncV(L, L->top, fn);
498 incr_top(L);
500 if (opt_L) {
501 if (isluafunc(fn)) {
502 GCtab *t = lj_tab_new(L, 0, 0);
503 GCproto *pt = funcproto(fn);
504 const void *lineinfo = proto_lineinfo(pt);
505 if (lineinfo) {
506 BCLine first = pt->firstline;
507 int sz = pt->numline < 256 ? 1 : pt->numline < 65536 ? 2 : 4;
508 MSize i, szl = pt->sizebc-1;
509 for (i = 0; i < szl; i++) {
510 BCLine line = first +
511 (sz == 1 ? (BCLine)((const uint8_t *)lineinfo)[i] :
512 sz == 2 ? (BCLine)((const uint16_t *)lineinfo)[i] :
513 (BCLine)((const uint32_t *)lineinfo)[i]);
514 setboolV(lj_tab_setint(L, t, line), 1);
517 settabV(L, L->top, t);
518 } else {
519 setnilV(L->top);
521 incr_top(L);
523 return 1; /* Ok. */
526 LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
528 return lj_debug_getinfo(L, what, (lj_Debug *)ar, 0);
531 LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
533 int size;
534 cTValue *frame = lj_debug_frame(L, level, &size);
535 if (frame) {
536 ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack));
537 return 1;
538 } else {
539 ar->i_ci = level - size;
540 return 0;
544 #if LJ_HASPROFILE
545 /* Put the chunkname into a buffer. */
546 static int debug_putchunkname(SBuf *sb, GCproto *pt, int pathstrip)
548 GCstr *name = proto_chunkname(pt);
549 const char *p = strdata(name);
550 if (pt->firstline == ~(BCLine)0) {
551 lj_buf_putmem(sb, "[builtin:", 9);
552 lj_buf_putstr(sb, name);
553 lj_buf_putb(sb, ']');
554 return 0;
556 if (*p == '=' || *p == '@') {
557 MSize len = name->len-1;
558 p++;
559 if (pathstrip) {
560 int i;
561 for (i = len-1; i >= 0; i--)
562 if (p[i] == '/' || p[i] == '\\') {
563 len -= i+1;
564 p = p+i+1;
565 break;
568 lj_buf_putmem(sb, p, len);
569 } else {
570 lj_buf_putmem(sb, "[string]", 8);
572 return 1;
575 /* Put a compact stack dump into a buffer. */
576 void lj_debug_dumpstack(lua_State *L, SBuf *sb, const char *fmt, int depth)
578 int level = 0, dir = 1, pathstrip = 1;
579 MSize lastlen = 0;
580 if (depth < 0) { level = ~depth; depth = dir = -1; } /* Reverse frames. */
581 while (level != depth) { /* Loop through all frame. */
582 int size;
583 cTValue *frame = lj_debug_frame(L, level, &size);
584 if (frame) {
585 cTValue *nextframe = size ? frame+size : NULL;
586 GCfunc *fn = frame_func(frame);
587 const uint8_t *p = (const uint8_t *)fmt;
588 int c;
589 while ((c = *p++)) {
590 switch (c) {
591 case 'p': /* Preserve full path. */
592 pathstrip = 0;
593 break;
594 case 'F': case 'f': { /* Dump function name. */
595 const char *name;
596 const char *what = lj_debug_funcname(L, frame, &name);
597 if (what) {
598 if (c == 'F' && isluafunc(fn)) { /* Dump module:name for 'F'. */
599 GCproto *pt = funcproto(fn);
600 if (pt->firstline != ~(BCLine)0) { /* Not a bytecode builtin. */
601 debug_putchunkname(sb, pt, pathstrip);
602 lj_buf_putb(sb, ':');
605 lj_buf_putmem(sb, name, (MSize)strlen(name));
606 break;
607 } /* else: can't derive a name, dump module:line. */
609 /* fallthrough */
610 case 'l': /* Dump module:line. */
611 if (isluafunc(fn)) {
612 GCproto *pt = funcproto(fn);
613 if (debug_putchunkname(sb, pt, pathstrip)) {
614 /* Regular Lua function. */
615 BCLine line = c == 'l' ? debug_frameline(L, fn, nextframe) :
616 pt->firstline;
617 lj_buf_putb(sb, ':');
618 lj_strfmt_putint(sb, line >= 0 ? line : pt->firstline);
620 } else if (isffunc(fn)) { /* Dump numbered builtins. */
621 lj_buf_putmem(sb, "[builtin#", 9);
622 lj_strfmt_putint(sb, fn->c.ffid);
623 lj_buf_putb(sb, ']');
624 } else { /* Dump C function address. */
625 lj_buf_putb(sb, '@');
626 lj_strfmt_putptr(sb, fn->c.f);
628 break;
629 case 'Z': /* Zap trailing separator. */
630 lastlen = sbuflen(sb);
631 break;
632 default:
633 lj_buf_putb(sb, c);
634 break;
637 } else if (dir == 1) {
638 break;
639 } else {
640 level -= size; /* Reverse frame order: quickly skip missing level. */
642 level += dir;
644 if (lastlen)
645 setsbufP(sb, sbufB(sb) + lastlen); /* Zap trailing separator. */
647 #endif
649 /* Number of frames for the leading and trailing part of a traceback. */
650 #define TRACEBACK_LEVELS1 12
651 #define TRACEBACK_LEVELS2 10
653 LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
654 int level)
656 int top = (int)(L->top - L->base);
657 int lim = TRACEBACK_LEVELS1;
658 lua_Debug ar;
659 if (msg) lua_pushfstring(L, "%s\n", msg);
660 lua_pushliteral(L, "stack traceback:");
661 while (lua_getstack(L1, level++, &ar)) {
662 GCfunc *fn;
663 if (level > lim) {
664 if (!lua_getstack(L1, level + TRACEBACK_LEVELS2, &ar)) {
665 level--;
666 } else {
667 lua_pushliteral(L, "\n\t...");
668 lua_getstack(L1, -10, &ar);
669 level = ar.i_ci - TRACEBACK_LEVELS2;
671 lim = 2147483647;
672 continue;
674 lua_getinfo(L1, "Snlf", &ar);
675 fn = funcV(L1->top-1); L1->top--;
676 if (isffunc(fn) && !*ar.namewhat)
677 lua_pushfstring(L, "\n\t[builtin#%d]:", fn->c.ffid);
678 else
679 lua_pushfstring(L, "\n\t%s:", ar.short_src);
680 if (ar.currentline > 0)
681 lua_pushfstring(L, "%d:", ar.currentline);
682 if (*ar.namewhat) {
683 lua_pushfstring(L, " in function " LUA_QS, ar.name);
684 } else {
685 if (*ar.what == 'm') {
686 lua_pushliteral(L, " in main chunk");
687 } else if (*ar.what == 'C') {
688 lua_pushfstring(L, " at %p", fn->c.f);
689 } else {
690 lua_pushfstring(L, " in function <%s:%d>",
691 ar.short_src, ar.linedefined);
694 if ((int)(L->top - L->base) - top >= 15)
695 lua_concat(L, (int)(L->top - L->base) - top);
697 lua_concat(L, (int)(L->top - L->base) - top);