diff --git a/lib/dump.lua b/lib/dump.lua index be456aa0..c12b0ba8 100644 --- a/lib/dump.lua +++ b/lib/dump.lua @@ -227,6 +227,19 @@ local function ctlsub(c) end end +local function fmtfunc(func, pc) + local fi = funcinfo(func, pc) + if fi.loc then + return fi.loc + elseif fi.ffid then + return vmdef.ffnames[fi.ffid] + elseif fi.addr then + return format("C:%x", fi.addr) + else + return "(?)" + end +end + local function formatk(tr, idx) local k, t, slot = tracek(tr, idx) local tn = type(k) @@ -240,12 +253,7 @@ local function formatk(tr, idx) elseif tn == "string" then s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) elseif tn == "function" then - local fi = funcinfo(k) - if fi.ffid then - s = vmdef.ffnames[fi.ffid] - else - s = fi.loc - end + s = fmtfunc(k) elseif tn == "table" then s = format("{%p}", k) elseif tn == "userdata" then @@ -428,14 +436,7 @@ local recdepth = 0 -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then - if type(info) == "function" then - local fi = funcinfo(info) - if fi.ffid then - info = vmdef.ffnames[fi.ffid] - else - info = fi.loc - end - end + if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err @@ -452,16 +453,14 @@ local function dump_trace(what, tr, func, pc, otr, oex) if dumpmode.H then out:write('
\n') end out:write("---- TRACE ", tr, " ", what) if otr then out:write(" ", otr, "/", oex) end - local fi = funcinfo(func, pc) - out:write(" ", fi.loc, "\n") + out:write(" ", fmtfunc(func, pc), "\n") recprefix = "" reclevel = 0 elseif what == "stop" or what == "abort" then out:write("---- TRACE ", tr, " ", what) recprefix = nil if what == "abort" then - local fi = funcinfo(func, pc) - out:write(" ", fi.loc, " -- ", fmterr(otr, oex), "\n") + out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n") else local link = traceinfo(tr).link if link == tr then @@ -487,12 +486,7 @@ local function dump_record(tr, func, pc, depth, callee) local line = bcline(func, pc, recprefix) if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end if type(callee) == "function" then - local fi = funcinfo(callee) - if fi.ffid then - out:write(sub(line, 1, -2), " ; ", vmdef.ffnames[fi.ffid], "\n") - else - out:write(sub(line, 1, -2), " ; ", fi.loc, "\n") - end + out:write(sub(line, 1, -2), " ; ", fmtfunc(callee), "\n") else out:write(line) end diff --git a/lib/v.lua b/lib/v.lua index 93f1cbb2..649bbf8d 100644 --- a/lib/v.lua +++ b/lib/v.lua @@ -73,17 +73,23 @@ local active, out local startloc, startex +local function fmtfunc(func, pc) + local fi = funcinfo(func, pc) + if fi.loc then + return fi.loc + elseif fi.ffid then + return vmdef.ffnames[fi.ffid] + elseif fi.addr then + return format("C:%x", fi.addr) + else + return "(?)" + end +end + -- Format trace error message. local function fmterr(err, info) if type(err) == "number" then - if type(info) == "function" then - local fi = funcinfo(info) - if fi.ffid then - info = vmdef.ffnames[fi.ffid] - else - info = fi.loc - end - end + if type(info) == "function" then info = fmtfunc(info) end err = format(vmdef.traceerr[err], info) end return err @@ -92,11 +98,11 @@ end -- Dump trace states. local function dump_trace(what, tr, func, pc, otr, oex) if what == "start" then - startloc = funcinfo(func, pc).loc + startloc = fmtfunc(func, pc) startex = otr and "("..otr.."/"..oex..") " or "" else if what == "abort" then - local loc = funcinfo(func, pc).loc + local loc = fmtfunc(func, pc) if loc ~= startloc then out:write(format("[TRACE --- %s%s -- %s at %s]\n", startex, startloc, fmterr(otr, oex), loc)) diff --git a/src/lib_jit.c b/src/lib_jit.c index a5829dc3..0ee5ad0d 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -197,9 +197,12 @@ LJLIB_CF(jit_util_funcinfo) } else { GCfunc *fn = funcV(L->base); GCtab *t; - lua_createtable(L, 0, 2); /* Increment hash size if fields are added. */ + lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */ t = tabV(L->top-1); - setintfield(L, t, "ffid", fn->c.ffid); + if (!iscfunc(fn)) + setintfield(L, t, "ffid", fn->c.ffid); + setnumV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")), + cast_num((intptr_t)fn->c.f)); setintfield(L, t, "upvalues", fn->c.nupvalues); } return 1; diff --git a/src/lj_trace.c b/src/lj_trace.c index b5946346..7b366d54 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -475,17 +475,18 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) case LJ_TRACE_RECORD: setvmstate(J2G(J), RECORD); - lj_vmevent_send(L, RECORD, - setintV(L->top++, J->curtrace); - setfuncV(L, L->top++, J->fn); - setintV(L->top++, proto_bcpos(J->pt, J->pc)); - setintV(L->top++, J->framedepth); - if (bcmode_mm(bc_op(*J->pc)) == MM_call) { - cTValue *o = &L->base[bc_a(*J->pc)]; - if (bc_op(*J->pc) == BC_ITERC) o -= 3; - copyTV(L, L->top++, o); - } - ); + if (J->pt) + lj_vmevent_send(L, RECORD, + setintV(L->top++, J->curtrace); + setfuncV(L, L->top++, J->fn); + setintV(L->top++, proto_bcpos(J->pt, J->pc)); + setintV(L->top++, J->framedepth); + if (bcmode_mm(bc_op(*J->pc)) == MM_call) { + cTValue *o = &L->base[bc_a(*J->pc)]; + if (bc_op(*J->pc) == BC_ITERC) o -= 3; + copyTV(L, L->top++, o); + } + ); lj_record_ins(J); break; @@ -537,7 +538,7 @@ void lj_trace_ins(jit_State *J, const BCIns *pc) /* Note: J->L must already be set. pc is the true bytecode PC here. */ J->pc = pc; J->fn = curr_func(J->L); - J->pt = funcproto(J->fn); + J->pt = isluafunc(J->fn) ? funcproto(J->fn) : NULL; while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0) J->state = LJ_TRACE_ERR; }