diff --git a/src/lib_jit.c b/src/lib_jit.c index 52368a8b..d0b9e833 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -184,8 +184,9 @@ LJLIB_CF(jit_util_funcinfo) setintfield(L, t, "gcconsts", (int32_t)pt->sizekgc); setintfield(L, t, "nconsts", (int32_t)pt->sizekn); setintfield(L, t, "upvalues", (int32_t)pt->sizeuv); - if (pc > 0) - setintfield(L, t, "currentline", pt->lineinfo ? pt->lineinfo[pc-1] : 0); + if (pc-1 < pt->sizebc) + setintfield(L, t, "currentline", + proto_lineinfo(pt) ? proto_line(pt, pc-1) : 0); lua_pushboolean(L, (pt->flags & PROTO_IS_VARARG)); lua_setfield(L, -2, "isvararg"); setstrV(L, L->top++, proto_chunkname(pt)); diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index 09cb2f5d..5378531d 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c @@ -301,12 +301,12 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc) g->hookcount = g->hookcstart; callhook(L, LUA_HOOKCOUNT, -1); } - if ((g->hookmask & LUA_MASKLINE) && pt->lineinfo) { + if ((g->hookmask & LUA_MASKLINE) && proto_lineinfo(pt)) { BCPos npc = proto_bcpos(pt, pc) - 1; BCPos opc = proto_bcpos(pt, oldpc) - 1; - BCLine line = pt->lineinfo[npc]; + BCLine line = proto_line(pt, npc); if (npc == 0 || pc <= oldpc || - opc >= pt->sizebc || line != pt->lineinfo[opc]) { + opc >= pt->sizebc || line != proto_line(pt, opc)) { L->top = L->base + slots; /* Fix top again after instruction hook. */ callhook(L, LUA_HOOKLINE, line); } diff --git a/src/lj_err.c b/src/lj_err.c index 0c54cf62..cf7f9ae4 100644 --- a/src/lj_err.c +++ b/src/lj_err.c @@ -129,7 +129,7 @@ static BCLine currentline(lua_State *L, GCfunc *fn, cTValue *nextframe) if (pc != ~(BCPos)0) { GCproto *pt = funcproto(fn); lua_assert(pc < pt->sizebc); - return pt->lineinfo ? pt->lineinfo[pc] : 0; + return proto_lineinfo(pt) ? proto_line(pt, pc) : 0; } else { return -1; } @@ -224,7 +224,7 @@ void lj_err_pushloc(lua_State *L, GCproto *pt, BCPos pc) MSize i, len = name->len; BCLine line; if (pc) - line = pt->lineinfo ? pt->lineinfo[pc-1] : 0; + line = proto_lineinfo(pt) ? proto_line(pt, pc-1) : 0; else line = pt->linedefined; if (*s == '@') { @@ -377,10 +377,12 @@ LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar) case 'L': if (isluafunc(fn)) { GCtab *t = lj_tab_new(L, 0, 0); - BCLine *lineinfo = funcproto(fn)->lineinfo; - uint32_t i, szl = funcproto(fn)->sizelineinfo; - for (i = 0; i < szl; i++) - setboolV(lj_tab_setint(L, t, lineinfo[i]), 1); + BCLine *lineinfo = proto_lineinfo(funcproto(fn)); + if (lineinfo) { + uint32_t i, szl = funcproto(fn)->sizelineinfo; + for (i = 0; i < szl; i++) + setboolV(lj_tab_setint(L, t, lineinfo[i]), 1); + } settabV(L, L->top, t); } else { setnilV(L->top); diff --git a/src/lj_func.c b/src/lj_func.c index 284bd3b3..4354aa21 100644 --- a/src/lj_func.c +++ b/src/lj_func.c @@ -37,7 +37,7 @@ GCproto *lj_func_newproto(lua_State *L) pt->sizeuvname = 0; pt->linedefined = 0; pt->lastlinedefined = 0; - pt->lineinfo = NULL; + setmref(pt->lineinfo, NULL); pt->varinfo = NULL; setmref(pt->uvname, NULL); setgcrefnull(pt->chunkname); @@ -52,7 +52,7 @@ void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) lj_mem_free(g, mref(pt->k, GCRef) - nkgc, sizek); lj_mem_freevec(g, proto_bc(pt), pt->sizebc, BCIns); lj_mem_freevec(g, proto_uv(pt), pt->sizeuv, uint16_t); - lj_mem_freevec(g, pt->lineinfo, pt->sizelineinfo, int32_t); + lj_mem_freevec(g, proto_lineinfo(pt), pt->sizelineinfo, BCLine); lj_mem_freevec(g, pt->varinfo, pt->sizevarinfo, struct VarInfo); lj_mem_freevec(g, mref(pt->uvname, GCRef), pt->sizeuvname, GCRef); lj_trace_freeproto(g, pt); diff --git a/src/lj_gc.c b/src/lj_gc.c index 3c1b847a..04aa7161 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -330,7 +330,7 @@ static size_t propagatemark(global_State *g) sizeof(GCRef) * pt->sizekgc + sizeof(lua_Number) * pt->sizekn + sizeof(uint16_t) * pt->sizeuv + - sizeof(int32_t) * pt->sizelineinfo + + sizeof(BCLine) * pt->sizelineinfo + sizeof(VarInfo) * pt->sizevarinfo + sizeof(GCRef) * pt->sizeuvname; } else { diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index af31b277..e60a451b 100644 --- a/src/lj_gdbjit.c +++ b/src/lj_gdbjit.c @@ -706,7 +706,7 @@ void lj_gdbjit_addtrace(jit_State *J, Trace *T, TraceNo traceno) ctx.spadjp = CFRAME_SIZE + (MSize)(parent ? J->trace[parent]->spadjust : 0); ctx.spadj = CFRAME_SIZE + T->spadjust; if (startpc >= proto_bc(pt)) - ctx.lineno = pt->lineinfo ? pt->lineinfo[proto_bcpos(pt, startpc)] : 0; + ctx.lineno = proto_lineinfo(pt) ? proto_line(pt,proto_bcpos(pt,startpc)): 0; else ctx.lineno = pt->linedefined; ctx.filename = strdata(proto_chunkname(pt)); diff --git a/src/lj_obj.h b/src/lj_obj.h index 164ec853..cdb90dff 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -364,7 +364,7 @@ typedef struct GCproto { MSize sizeuvname; /* Size of upvalue names array (may be 0). */ BCLine linedefined; /* First line of the function definition. */ BCLine lastlinedefined; /* Last line of the function definition. */ - BCLine *lineinfo; /* Map from bytecode instructions to source lines. */ + MRef lineinfo; /* Map from bytecode instructions to source lines. */ struct VarInfo *varinfo; /* Names and extents of local variables. */ MRef uvname; /* Array of upvalue names (GCRef of GCstr). */ GCRef chunkname; /* Name of the chunk this function was defined in. */ @@ -393,6 +393,9 @@ typedef struct GCproto { check_exp((uintptr_t)(idx) < (pt)->sizeuvname, \ gcref(mref((pt)->uvname, GCRef)[(idx)])) #define proto_chunkname(pt) (gco2str(gcref((pt)->chunkname))) +#define proto_lineinfo(pt) (mref((pt)->lineinfo, BCLine)) +#define proto_line(pt, pos) \ + check_exp((uintptr_t)(pos) < (pt)->sizebc, proto_lineinfo(pt)[(pos)]) /* -- Upvalue object ------------------------------------------------------ */ diff --git a/src/lj_parse.c b/src/lj_parse.c index 864f9e20..a3291553 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -247,19 +247,22 @@ static void patchlist(FuncState *fs, BCPos list, BCPos target) static BCPos emitINS(FuncState *fs, BCIns i) { GCproto *pt; + BCIns *bc; + BCLine *lineinfo; patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); fs->jpc = NO_JMP; pt = fs->pt; + bc = proto_bc(pt); + lineinfo = proto_lineinfo(pt); if (LJ_UNLIKELY(fs->pc >= pt->sizebc)) { - BCIns *bc; checklimit(fs, fs->pc, LJ_MAX_BCINS, "bytecode instructions"); - bc = proto_bc(pt); lj_mem_growvec(fs->L, bc, pt->sizebc, LJ_MAX_BCINS, BCIns); setmref(pt->bc, bc); - lj_mem_growvec(fs->L, pt->lineinfo, pt->sizelineinfo, LJ_MAX_BCINS, BCLine); + lj_mem_growvec(fs->L, lineinfo, pt->sizelineinfo, LJ_MAX_BCINS, BCLine); + setmref(pt->lineinfo, lineinfo); } - *proto_insptr(pt, fs->pc) = i; - pt->lineinfo[fs->pc] = fs->ls->lastline; + bc[fs->pc] = i; + lineinfo[fs->pc] = fs->ls->lastline; return fs->pc++; } @@ -1233,6 +1236,7 @@ static void close_func(LexState *ls) GCproto *pt = fs->pt; BCIns *bc; GCRef *uvname; + BCLine *lineinfo; removevars(ls, 0); finalret(fs, pt); bc = proto_bc(pt); @@ -1241,7 +1245,9 @@ static void close_func(LexState *ls) pt->sizebc = fs->pc; collectk(fs, pt); collectuv(fs, pt); - lj_mem_reallocvec(L, pt->lineinfo, pt->sizelineinfo, fs->pc, BCLine); + lineinfo = proto_lineinfo(pt); + lj_mem_reallocvec(L, lineinfo, pt->sizelineinfo, fs->pc, BCLine); + setmref(pt->lineinfo, lineinfo); pt->sizelineinfo = fs->pc; lj_mem_reallocvec(L, pt->varinfo, pt->sizevarinfo, fs->nlocvars, VarInfo); pt->sizevarinfo = fs->nlocvars; @@ -1509,7 +1515,7 @@ static void funcargs(LexState *ls, ExpDesc *e) } init_exp(e, VCALL, emitINS(fs, ins)); e->u.s.aux = base; - fs->pt->lineinfo[fs->pc - 1] = line; + proto_lineinfo(fs->pt)[fs->pc - 1] = line; fs->freereg = base+1; /* call removes function and arguments and leaves (unless changed) one result */ } @@ -1929,9 +1935,9 @@ static void forbody(LexState *ls, BCReg base, BCLine line, BCReg nvars, fixjump(fs, loop, fs->pc); emitABC(fs, BC_ITERC, base+3, nvars+1, 2+1); loopend = emitAJ(fs, BC_ITERL, base+3, NO_JMP); - fs->pt->lineinfo[loopend-1] = line; + proto_lineinfo(fs->pt)[loopend-1] = line; } - fs->pt->lineinfo[loopend] = line; /* pretend last op starts the loop */ + proto_lineinfo(fs->pt)[loopend] = line; /* pretend last op starts the loop */ fixjump(fs, loopend, loop+1); } @@ -2091,7 +2097,7 @@ static void funcstat(LexState *ls, BCLine line) body(ls, &b, needself, line); fs = ls->fs; storevar(fs, &v, &b); - fs->pt->lineinfo[fs->pc - 1] = line; + proto_lineinfo(fs->pt)[fs->pc - 1] = line; } static void exprstat(LexState *ls)