mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Redesign of prototype generation, part 5: colocation of protoype arrays.
This commit is contained in:
parent
f275a9d7ef
commit
6194b1c896
@ -246,8 +246,8 @@ LJLIB_CF(jit_util_funcuvname)
|
|||||||
{
|
{
|
||||||
GCproto *pt = check_Lproto(L, 0);
|
GCproto *pt = check_Lproto(L, 0);
|
||||||
uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
|
uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
|
||||||
if (idx < pt->sizeuvname) {
|
if (idx < pt->sizeuv) {
|
||||||
setstrV(L, L->top-1, gco2str(proto_uvname(pt, idx)));
|
setstrV(L, L->top-1, proto_uvname(pt, idx));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -811,9 +811,9 @@ static const char *aux_upvalue(cTValue *f, uint32_t idx, TValue **val)
|
|||||||
fn = funcV(f);
|
fn = funcV(f);
|
||||||
if (isluafunc(fn)) {
|
if (isluafunc(fn)) {
|
||||||
GCproto *pt = funcproto(fn);
|
GCproto *pt = funcproto(fn);
|
||||||
if (idx < pt->sizeuvname) {
|
if (idx < pt->sizeuv) {
|
||||||
*val = uvval(&gcref(fn->l.uvptr[idx])->uv);
|
*val = uvval(&gcref(fn->l.uvptr[idx])->uv);
|
||||||
return strdata(gco2str(proto_uvname(pt, idx)));
|
return strdata(proto_uvname(pt, idx));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx < fn->c.nupvalues) {
|
if (idx < fn->c.nupvalues) {
|
||||||
|
@ -301,7 +301,7 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
|
|||||||
g->hookcount = g->hookcstart;
|
g->hookcount = g->hookcstart;
|
||||||
callhook(L, LUA_HOOKCOUNT, -1);
|
callhook(L, LUA_HOOKCOUNT, -1);
|
||||||
}
|
}
|
||||||
if ((g->hookmask & LUA_MASKLINE) && proto_lineinfo(pt)) {
|
if ((g->hookmask & LUA_MASKLINE)) {
|
||||||
BCPos npc = proto_bcpos(pt, pc) - 1;
|
BCPos npc = proto_bcpos(pt, pc) - 1;
|
||||||
BCPos opc = proto_bcpos(pt, oldpc) - 1;
|
BCPos opc = proto_bcpos(pt, oldpc) - 1;
|
||||||
BCLine line = proto_line(pt, npc);
|
BCLine line = proto_line(pt, npc);
|
||||||
|
21
src/lj_err.c
21
src/lj_err.c
@ -129,7 +129,7 @@ static BCLine currentline(lua_State *L, GCfunc *fn, cTValue *nextframe)
|
|||||||
if (pc != ~(BCPos)0) {
|
if (pc != ~(BCPos)0) {
|
||||||
GCproto *pt = funcproto(fn);
|
GCproto *pt = funcproto(fn);
|
||||||
lua_assert(pc < pt->sizebc);
|
lua_assert(pc < pt->sizebc);
|
||||||
return proto_lineinfo(pt) ? proto_line(pt, pc) : 0;
|
return proto_line(pt, pc);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -138,9 +138,10 @@ static BCLine currentline(lua_State *L, GCfunc *fn, cTValue *nextframe)
|
|||||||
static const char *getvarname(const GCproto *pt, BCPos pc, BCReg slot)
|
static const char *getvarname(const GCproto *pt, BCPos pc, BCReg slot)
|
||||||
{
|
{
|
||||||
MSize i;
|
MSize i;
|
||||||
for (i = 0; i < pt->sizevarinfo && proto_varinfo(pt)[i].startpc <= pc; i++)
|
VarInfo *vi = proto_varinfo(pt);
|
||||||
if (pc < proto_varinfo(pt)[i].endpc && slot-- == 0)
|
for (i = 0; i < pt->sizevarinfo && vi[i].startpc <= pc; i++)
|
||||||
return strdata(gco2str(gcref(proto_varinfo(pt)[i].name)));
|
if (pc < vi[i].endpc && slot-- == 0)
|
||||||
|
return strdata(gco2str(gcref(vi[i].name)));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,8 +177,7 @@ restart:
|
|||||||
}
|
}
|
||||||
return "field";
|
return "field";
|
||||||
case BC_UGET:
|
case BC_UGET:
|
||||||
*name = mref(pt->uvname, GCRef) ?
|
*name = strdata(proto_uvname(pt, bc_d(ins)));
|
||||||
strdata(gco2str(proto_uvname(pt,bc_d(ins)))) : "?";
|
|
||||||
return "upvalue";
|
return "upvalue";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -224,7 +224,7 @@ void lj_err_pushloc(lua_State *L, GCproto *pt, BCPos pc)
|
|||||||
MSize i, len = name->len;
|
MSize i, len = name->len;
|
||||||
BCLine line;
|
BCLine line;
|
||||||
if (pc)
|
if (pc)
|
||||||
line = proto_lineinfo(pt) ? proto_line(pt, pc-1) : 0;
|
line = proto_line(pt, pc-1);
|
||||||
else
|
else
|
||||||
line = pt->linedefined;
|
line = pt->linedefined;
|
||||||
if (*s == '@') {
|
if (*s == '@') {
|
||||||
@ -377,12 +377,11 @@ LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
|
|||||||
case 'L':
|
case 'L':
|
||||||
if (isluafunc(fn)) {
|
if (isluafunc(fn)) {
|
||||||
GCtab *t = lj_tab_new(L, 0, 0);
|
GCtab *t = lj_tab_new(L, 0, 0);
|
||||||
BCLine *lineinfo = proto_lineinfo(funcproto(fn));
|
GCproto *pt = funcproto(fn);
|
||||||
if (lineinfo) {
|
BCLine *lineinfo = proto_lineinfo(pt);
|
||||||
uint32_t i, szl = funcproto(fn)->sizelineinfo;
|
MSize i, szl = pt->sizebc;
|
||||||
for (i = 0; i < szl; i++)
|
for (i = 0; i < szl; i++)
|
||||||
setboolV(lj_tab_setint(L, t, lineinfo[i]), 1);
|
setboolV(lj_tab_setint(L, t, lineinfo[i]), 1);
|
||||||
}
|
|
||||||
settabV(L, L->top, t);
|
settabV(L, L->top, t);
|
||||||
} else {
|
} else {
|
||||||
setnilV(L->top);
|
setnilV(L->top);
|
||||||
|
@ -17,46 +17,10 @@
|
|||||||
|
|
||||||
/* -- Prototypes ---------------------------------------------------------- */
|
/* -- Prototypes ---------------------------------------------------------- */
|
||||||
|
|
||||||
GCproto *lj_func_newproto(lua_State *L)
|
|
||||||
{
|
|
||||||
GCproto *pt = lj_mem_newobj(L, GCproto);
|
|
||||||
pt->gct = ~LJ_TPROTO;
|
|
||||||
pt->numparams = 0;
|
|
||||||
pt->framesize = 0;
|
|
||||||
pt->sizeuv = 0;
|
|
||||||
pt->flags = 0;
|
|
||||||
pt->trace = 0;
|
|
||||||
setmref(pt->k, NULL);
|
|
||||||
setmref(pt->bc, NULL);
|
|
||||||
setmref(pt->uv, NULL);
|
|
||||||
pt->sizebc = 0;
|
|
||||||
pt->sizekgc = 0;
|
|
||||||
pt->sizekn = 0;
|
|
||||||
pt->sizelineinfo = 0;
|
|
||||||
pt->sizevarinfo = 0;
|
|
||||||
pt->sizeuvname = 0;
|
|
||||||
pt->linedefined = 0;
|
|
||||||
pt->lastlinedefined = 0;
|
|
||||||
setmref(pt->lineinfo, NULL);
|
|
||||||
setmref(pt->varinfo, NULL);
|
|
||||||
setmref(pt->uvname, NULL);
|
|
||||||
setgcrefnull(pt->chunkname);
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt)
|
void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt)
|
||||||
{
|
{
|
||||||
MSize nkgc = round_nkgc(pt->sizekgc);
|
|
||||||
MSize sizek = nkgc*(MSize)sizeof(GCRef) +
|
|
||||||
pt->sizekn*(MSize)sizeof(lua_Number);
|
|
||||||
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, proto_lineinfo(pt), pt->sizelineinfo, BCLine);
|
|
||||||
lj_mem_freevec(g, proto_varinfo(pt), pt->sizevarinfo, VarInfo);
|
|
||||||
lj_mem_freevec(g, mref(pt->uvname, GCRef), pt->sizeuvname, GCRef);
|
|
||||||
lj_trace_freeproto(g, pt);
|
lj_trace_freeproto(g, pt);
|
||||||
lj_mem_freet(g, pt);
|
lj_mem_free(g, pt, pt->sizept);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Upvalues ------------------------------------------------------------ */
|
/* -- Upvalues ------------------------------------------------------------ */
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
LJ_FUNC GCproto *lj_func_newproto(lua_State *L);
|
|
||||||
LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt);
|
LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt);
|
||||||
|
|
||||||
/* Upvalues. */
|
/* Upvalues. */
|
||||||
|
12
src/lj_gc.c
12
src/lj_gc.c
@ -254,8 +254,8 @@ static void gc_traverse_proto(global_State *g, GCproto *pt)
|
|||||||
gc_mark_str(proto_chunkname(pt));
|
gc_mark_str(proto_chunkname(pt));
|
||||||
for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */
|
for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */
|
||||||
gc_markobj(g, proto_kgc(pt, i));
|
gc_markobj(g, proto_kgc(pt, i));
|
||||||
for (i = 0; i < (ptrdiff_t)pt->sizeuvname; i++) /* Mark upvalue names. */
|
for (i = 0; i < (ptrdiff_t)pt->sizeuv; i++) /* Mark upvalue names. */
|
||||||
gc_mark_str(gco2str(proto_uvname(pt, i)));
|
gc_mark_str(proto_uvname(pt, i));
|
||||||
for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */
|
for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */
|
||||||
gc_mark_str(gco2str(gcref(proto_varinfo(pt)[i].name)));
|
gc_mark_str(gco2str(gcref(proto_varinfo(pt)[i].name)));
|
||||||
}
|
}
|
||||||
@ -323,13 +323,7 @@ static size_t propagatemark(global_State *g)
|
|||||||
} else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) {
|
} else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) {
|
||||||
GCproto *pt = gco2pt(o);
|
GCproto *pt = gco2pt(o);
|
||||||
gc_traverse_proto(g, pt);
|
gc_traverse_proto(g, pt);
|
||||||
return sizeof(GCproto) + sizeof(BCIns) * pt->sizebc +
|
return pt->sizept;
|
||||||
sizeof(GCRef) * pt->sizekgc +
|
|
||||||
sizeof(lua_Number) * pt->sizekn +
|
|
||||||
sizeof(uint16_t) * pt->sizeuv +
|
|
||||||
sizeof(BCLine) * pt->sizelineinfo +
|
|
||||||
sizeof(VarInfo) * pt->sizevarinfo +
|
|
||||||
sizeof(GCRef) * pt->sizeuvname;
|
|
||||||
} else {
|
} else {
|
||||||
lua_State *th = gco2th(o);
|
lua_State *th = gco2th(o);
|
||||||
setgcrefr(th->gclist, g->gc.grayagain);
|
setgcrefr(th->gclist, g->gc.grayagain);
|
||||||
|
@ -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.spadjp = CFRAME_SIZE + (MSize)(parent ? J->trace[parent]->spadjust : 0);
|
||||||
ctx.spadj = CFRAME_SIZE + T->spadjust;
|
ctx.spadj = CFRAME_SIZE + T->spadjust;
|
||||||
if (startpc >= proto_bc(pt))
|
if (startpc >= proto_bc(pt))
|
||||||
ctx.lineno = proto_lineinfo(pt) ? proto_line(pt,proto_bcpos(pt,startpc)): 0;
|
ctx.lineno = proto_line(pt,proto_bcpos(pt,startpc));
|
||||||
else
|
else
|
||||||
ctx.lineno = pt->linedefined;
|
ctx.lineno = pt->linedefined;
|
||||||
ctx.filename = strdata(proto_chunkname(pt));
|
ctx.filename = strdata(proto_chunkname(pt));
|
||||||
|
14
src/lj_obj.h
14
src/lj_obj.h
@ -355,19 +355,18 @@ typedef struct GCproto {
|
|||||||
MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */
|
MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */
|
||||||
MSize sizekgc; /* Number of collectable constants. */
|
MSize sizekgc; /* Number of collectable constants. */
|
||||||
MSize sizekn; /* Number of lua_Number constants. */
|
MSize sizekn; /* Number of lua_Number constants. */
|
||||||
|
MSize sizept; /* Total size including colocated arrays. */
|
||||||
uint8_t sizeuv; /* Number of upvalues. */
|
uint8_t sizeuv; /* Number of upvalues. */
|
||||||
uint8_t flags; /* Miscellaneous flags (see below). */
|
uint8_t flags; /* Miscellaneous flags (see below). */
|
||||||
uint16_t trace; /* Anchor for chain of root traces. */
|
uint16_t trace; /* Anchor for chain of root traces. */
|
||||||
/* ------ The following fields are for debugging/tracebacks only ------ */
|
/* ------ The following fields are for debugging/tracebacks only ------ */
|
||||||
MSize sizelineinfo; /* Size of lineinfo array (may be 0). */
|
GCRef chunkname; /* Name of the chunk this function was defined in. */
|
||||||
MSize sizevarinfo; /* Size of local var info array (may be 0). */
|
|
||||||
MSize sizeuvname; /* Size of upvalue names array (may be 0). */
|
|
||||||
BCLine linedefined; /* First line of the function definition. */
|
BCLine linedefined; /* First line of the function definition. */
|
||||||
BCLine lastlinedefined; /* Last line of the function definition. */
|
BCLine lastlinedefined; /* Last line of the function definition. */
|
||||||
MRef lineinfo; /* Map from bytecode instructions to source lines. */
|
MSize sizevarinfo; /* Size of local var info array. */
|
||||||
MRef varinfo; /* Names and extents of local variables. */
|
MRef varinfo; /* Names and extents of local variables. */
|
||||||
MRef uvname; /* Array of upvalue names (GCRef of GCstr). */
|
MRef uvname; /* Array of upvalue names (GCRef of GCstr). */
|
||||||
GCRef chunkname; /* Name of the chunk this function was defined in. */
|
MRef lineinfo; /* Map from bytecode instructions to source lines. */
|
||||||
} GCproto;
|
} GCproto;
|
||||||
|
|
||||||
#define PROTO_IS_VARARG 0x01
|
#define PROTO_IS_VARARG 0x01
|
||||||
@ -389,9 +388,10 @@ typedef struct GCproto {
|
|||||||
check_exp((uintptr_t)(pos) < (pt)->sizebc, &proto_bc(pt)[(pos)])
|
check_exp((uintptr_t)(pos) < (pt)->sizebc, &proto_bc(pt)[(pos)])
|
||||||
#define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt)))
|
#define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt)))
|
||||||
#define proto_uv(pt) (mref((pt)->uv, uint16_t))
|
#define proto_uv(pt) (mref((pt)->uv, uint16_t))
|
||||||
|
|
||||||
#define proto_uvname(pt, idx) \
|
#define proto_uvname(pt, idx) \
|
||||||
check_exp((uintptr_t)(idx) < (pt)->sizeuvname, \
|
check_exp((uintptr_t)(idx) < (pt)->sizeuv, \
|
||||||
gcref(mref((pt)->uvname, GCRef)[(idx)]))
|
gco2str(gcref(mref((pt)->uvname, GCRef)[(idx)])))
|
||||||
#define proto_chunkname(pt) (gco2str(gcref((pt)->chunkname)))
|
#define proto_chunkname(pt) (gco2str(gcref((pt)->chunkname)))
|
||||||
#define proto_lineinfo(pt) (mref((pt)->lineinfo, BCLine))
|
#define proto_lineinfo(pt) (mref((pt)->lineinfo, BCLine))
|
||||||
#define proto_line(pt, pos) \
|
#define proto_line(pt, pos) \
|
||||||
|
115
src/lj_parse.c
115
src/lj_parse.c
@ -1026,22 +1026,32 @@ static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first)
|
|||||||
|
|
||||||
/* -- Function state management ------------------------------------------- */
|
/* -- Function state management ------------------------------------------- */
|
||||||
|
|
||||||
|
/* NYI: compress debug info. */
|
||||||
|
|
||||||
|
/* Fixup bytecode and lineinfo for prototype. */
|
||||||
|
static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, BCLine *lineinfo)
|
||||||
|
{
|
||||||
|
MSize i, n = fs->pc;
|
||||||
|
BCInsLine *base = fs->bcbase;
|
||||||
|
setmref(pt->bc, bc);
|
||||||
|
setmref(pt->lineinfo, lineinfo);
|
||||||
|
pt->sizebc = n;
|
||||||
|
bc[n] = ~0u; /* Close potentially uninitialized gap between bc and kgc. */
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
bc[i] = base[i].ins;
|
||||||
|
lineinfo[i] = base[i].line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Fixup constants for prototype. */
|
/* Fixup constants for prototype. */
|
||||||
static void fs_fixup_k(FuncState *fs, GCproto *pt)
|
static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr)
|
||||||
{
|
{
|
||||||
GCtab *kt;
|
GCtab *kt;
|
||||||
TValue *array;
|
TValue *array;
|
||||||
Node *node;
|
Node *node;
|
||||||
BCReg nkgc;
|
MSize i, hmask;
|
||||||
MSize i, hmask, sizek;
|
|
||||||
GCRef *kptr;
|
|
||||||
checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
|
checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
|
||||||
checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
|
checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
|
||||||
nkgc = round_nkgc(fs->nkgc);
|
|
||||||
sizek = (MSize)(nkgc*sizeof(GCRef) + fs->nkn*sizeof(lua_Number));
|
|
||||||
kptr = lj_mem_newt(fs->L, sizek, GCRef);
|
|
||||||
if (nkgc) setgcrefnull(kptr[0]); /* May be uninitialized otherwise. */
|
|
||||||
kptr += nkgc;
|
|
||||||
setmref(pt->k, kptr);
|
setmref(pt->k, kptr);
|
||||||
pt->sizekn = fs->nkn;
|
pt->sizekn = fs->nkn;
|
||||||
pt->sizekgc = fs->nkgc;
|
pt->sizekgc = fs->nkgc;
|
||||||
@ -1060,7 +1070,7 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt)
|
|||||||
((lua_Number *)kptr)[kidx] = numV(&n->key);
|
((lua_Number *)kptr)[kidx] = numV(&n->key);
|
||||||
} else {
|
} else {
|
||||||
GCobj *o = gcV(&n->key);
|
GCobj *o = gcV(&n->key);
|
||||||
setgcref(kptr[~kidx], o);
|
setgcref(((GCRef *)kptr)[~kidx], o);
|
||||||
lj_gc_objbarrier(fs->L, pt, o);
|
lj_gc_objbarrier(fs->L, pt, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1068,16 +1078,29 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fixup upvalues for prototype. */
|
/* Fixup upvalues for prototype. */
|
||||||
static void fs_fixup_uv(FuncState *fs, GCproto *pt)
|
static void fs_fixup_uv(FuncState *fs, GCproto *pt, uint16_t *uv)
|
||||||
{
|
{
|
||||||
MSize i, n = fs->nuv;
|
MSize i, n = fs->nuv;
|
||||||
uint16_t *uv = lj_mem_newvec(fs->L, n, uint16_t);
|
|
||||||
setmref(pt->uv, uv);
|
setmref(pt->uv, uv);
|
||||||
pt->sizeuv = n;
|
pt->sizeuv = n;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
uv[i] = fs->uvloc[i].slot;
|
uv[i] = fs->uvloc[i].slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fixup debug info for prototype. */
|
||||||
|
static void fs_fixup_dbg(FuncState *fs, GCproto *pt, VarInfo *vi, MSize sizevi)
|
||||||
|
{
|
||||||
|
MSize i, n = fs->nuv;
|
||||||
|
GCRef *uvname = (GCRef *)((char *)vi + sizevi*sizeof(VarInfo));
|
||||||
|
VarInfo *vstack = fs->ls->vstack;
|
||||||
|
setmref(pt->varinfo, vi);
|
||||||
|
setmref(pt->uvname, uvname);
|
||||||
|
pt->sizevarinfo = sizevi;
|
||||||
|
memcpy(vi, &vstack[fs->vbase], sizevi*sizeof(VarInfo));
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
setgcref(uvname[i], gcref(vstack[fs->uvloc[i].vidx].name));
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if bytecode op returns. */
|
/* Check if bytecode op returns. */
|
||||||
static int bcopisret(BCOp op)
|
static int bcopisret(BCOp op)
|
||||||
{
|
{
|
||||||
@ -1128,6 +1151,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
|
|||||||
{
|
{
|
||||||
lua_State *L = ls->L;
|
lua_State *L = ls->L;
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
|
MSize sizevi;
|
||||||
|
size_t sizept, ofsk, ofsuv, ofsdbg, ofsli;
|
||||||
GCproto *pt;
|
GCproto *pt;
|
||||||
|
|
||||||
/* Apply final fixups. */
|
/* Apply final fixups. */
|
||||||
@ -1135,61 +1160,41 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
|
|||||||
lua_assert(fs->bl == NULL);
|
lua_assert(fs->bl == NULL);
|
||||||
fs_fixup_ret(fs);
|
fs_fixup_ret(fs);
|
||||||
|
|
||||||
|
/* Calculate total size of prototype including all colocated arrays. */
|
||||||
|
sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef);
|
||||||
|
sizept = (sizept + sizeof(lua_Number)-1) & ~(sizeof(lua_Number)-1);
|
||||||
|
ofsk = sizept;
|
||||||
|
sizept += fs->nkn*sizeof(lua_Number);
|
||||||
|
ofsuv = sizept;
|
||||||
|
sizept += ((fs->nuv+1)&~1)*2;
|
||||||
|
ofsdbg = sizept;
|
||||||
|
sizevi = ls->vtop - fs->vbase;
|
||||||
|
sizept += sizevi*sizeof(VarInfo) + fs->nuv*sizeof(GCRef);
|
||||||
|
ofsli = sizept;
|
||||||
|
sizept += fs->pc*sizeof(BCLine);
|
||||||
|
|
||||||
/* Allocate prototype and initialize its fields. */
|
/* Allocate prototype and initialize its fields. */
|
||||||
pt = lj_func_newproto(L);
|
pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept);
|
||||||
|
pt->gct = ~LJ_TPROTO;
|
||||||
|
pt->sizept = (MSize)sizept;
|
||||||
setgcref(pt->chunkname, obj2gco(ls->chunkname));
|
setgcref(pt->chunkname, obj2gco(ls->chunkname));
|
||||||
|
pt->trace = 0;
|
||||||
pt->flags = fs->flags;
|
pt->flags = fs->flags;
|
||||||
pt->numparams = fs->numparams;
|
pt->numparams = fs->numparams;
|
||||||
pt->framesize = fs->framesize;
|
pt->framesize = fs->framesize;
|
||||||
pt->linedefined = fs->linedefined;
|
pt->linedefined = fs->linedefined;
|
||||||
pt->lastlinedefined = line;
|
pt->lastlinedefined = line;
|
||||||
|
|
||||||
/* Anchor prototype since allocation of the arrays may fail. */
|
fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)),
|
||||||
setprotoV(L, L->top, pt);
|
(BCLine *)((char *)pt + ofsli));
|
||||||
incr_top(L);
|
fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk));
|
||||||
|
fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv));
|
||||||
fs_fixup_k(fs, pt);
|
fs_fixup_dbg(fs, pt, (VarInfo *)((char *)pt + ofsdbg), sizevi);
|
||||||
fs_fixup_uv(fs, pt);
|
|
||||||
|
|
||||||
{
|
|
||||||
MSize i, n = fs->pc;
|
|
||||||
BCInsLine *base = fs->bcbase;
|
|
||||||
BCLine *lineinfo;
|
|
||||||
BCIns *bc = lj_mem_newvec(L, n, BCIns);
|
|
||||||
setmref(pt->bc, bc);
|
|
||||||
pt->sizebc = fs->pc;
|
|
||||||
lineinfo = lj_mem_newvec(L, n, BCLine);
|
|
||||||
setmref(pt->lineinfo, lineinfo);
|
|
||||||
pt->sizelineinfo = n;
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
bc[i] = base[i].ins;
|
|
||||||
lineinfo[i] = base[i].line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
MSize n = ls->vtop - fs->vbase;
|
|
||||||
VarInfo *vi = lj_mem_newvec(L, n, VarInfo);
|
|
||||||
memcpy(vi, &ls->vstack[fs->vbase], n*sizeof(VarInfo));
|
|
||||||
setmref(pt->varinfo, vi);
|
|
||||||
pt->sizevarinfo = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
MSize i, n = fs->nuv;
|
|
||||||
GCRef *uvname = lj_mem_newvec(L, n, GCRef);
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
setgcref(uvname[i], gcref(ls->vstack[fs->uvloc[i].vidx].name));
|
|
||||||
setmref(pt->uvname, uvname);
|
|
||||||
pt->sizeuvname = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
lj_vmevent_send(L, BC,
|
lj_vmevent_send(L, BC,
|
||||||
setprotoV(L, L->top++, pt);
|
setprotoV(L, L->top++, pt);
|
||||||
);
|
);
|
||||||
|
|
||||||
L->top--; /* Pop prototype. */
|
|
||||||
|
|
||||||
L->top--; /* Pop table of constants. */
|
L->top--; /* Pop table of constants. */
|
||||||
ls->vtop = fs->vbase; /* Reset variable stack. */
|
ls->vtop = fs->vbase; /* Reset variable stack. */
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
@ -1427,7 +1432,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
|
|||||||
lex_match(ls, TK_end, TK_function, line);
|
lex_match(ls, TK_end, TK_function, line);
|
||||||
pt = fs_finish(ls, lastline);
|
pt = fs_finish(ls, lastline);
|
||||||
fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
|
fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
|
||||||
fs->bclim = ls->sizebcstack - oldbase;
|
fs->bclim = (BCPos)(ls->sizebcstack - oldbase);
|
||||||
/* Store new prototype in the constant array of the parent. */
|
/* Store new prototype in the constant array of the parent. */
|
||||||
kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO);
|
kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO);
|
||||||
expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx));
|
expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx));
|
||||||
|
Loading…
Reference in New Issue
Block a user