diff options
| author | Mike Pall <mike> | 2010-02-08 05:30:57 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-02-08 05:30:57 +0100 |
| commit | 6194b1c896c78c2ba0436053dcae596725317e9c (patch) | |
| tree | c3fc29eddcb51e3717fce1d00eff29f9a211f300 | |
| parent | f275a9d7ef1a47c30cbb9c70897914d633dff14c (diff) | |
| download | luajit-6194b1c896c78c2ba0436053dcae596725317e9c.tar.gz luajit-6194b1c896c78c2ba0436053dcae596725317e9c.tar.bz2 luajit-6194b1c896c78c2ba0436053dcae596725317e9c.zip | |
Redesign of prototype generation, part 5: colocation of protoype arrays.
| -rw-r--r-- | src/lib_jit.c | 4 | ||||
| -rw-r--r-- | src/lj_api.c | 4 | ||||
| -rw-r--r-- | src/lj_dispatch.c | 2 | ||||
| -rw-r--r-- | src/lj_err.c | 25 | ||||
| -rw-r--r-- | src/lj_func.c | 38 | ||||
| -rw-r--r-- | src/lj_func.h | 1 | ||||
| -rw-r--r-- | src/lj_gc.c | 12 | ||||
| -rw-r--r-- | src/lj_gdbjit.c | 2 | ||||
| -rw-r--r-- | src/lj_obj.h | 14 | ||||
| -rw-r--r-- | src/lj_parse.c | 117 |
10 files changed, 90 insertions, 129 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c index d0b9e833..33571b17 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c | |||
| @@ -246,8 +246,8 @@ LJLIB_CF(jit_util_funcuvname) | |||
| 246 | { | 246 | { |
| 247 | GCproto *pt = check_Lproto(L, 0); | 247 | GCproto *pt = check_Lproto(L, 0); |
| 248 | uint32_t idx = (uint32_t)lj_lib_checkint(L, 2); | 248 | uint32_t idx = (uint32_t)lj_lib_checkint(L, 2); |
| 249 | if (idx < pt->sizeuvname) { | 249 | if (idx < pt->sizeuv) { |
| 250 | setstrV(L, L->top-1, gco2str(proto_uvname(pt, idx))); | 250 | setstrV(L, L->top-1, proto_uvname(pt, idx)); |
| 251 | return 1; | 251 | return 1; |
| 252 | } | 252 | } |
| 253 | return 0; | 253 | return 0; |
diff --git a/src/lj_api.c b/src/lj_api.c index 48bd605d..ad28bbf2 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
| @@ -811,9 +811,9 @@ static const char *aux_upvalue(cTValue *f, uint32_t idx, TValue **val) | |||
| 811 | fn = funcV(f); | 811 | fn = funcV(f); |
| 812 | if (isluafunc(fn)) { | 812 | if (isluafunc(fn)) { |
| 813 | GCproto *pt = funcproto(fn); | 813 | GCproto *pt = funcproto(fn); |
| 814 | if (idx < pt->sizeuvname) { | 814 | if (idx < pt->sizeuv) { |
| 815 | *val = uvval(&gcref(fn->l.uvptr[idx])->uv); | 815 | *val = uvval(&gcref(fn->l.uvptr[idx])->uv); |
| 816 | return strdata(gco2str(proto_uvname(pt, idx))); | 816 | return strdata(proto_uvname(pt, idx)); |
| 817 | } | 817 | } |
| 818 | } else { | 818 | } else { |
| 819 | if (idx < fn->c.nupvalues) { | 819 | if (idx < fn->c.nupvalues) { |
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index 02fcf6ef..e2605e96 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c | |||
| @@ -301,7 +301,7 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc) | |||
| 301 | g->hookcount = g->hookcstart; | 301 | g->hookcount = g->hookcstart; |
| 302 | callhook(L, LUA_HOOKCOUNT, -1); | 302 | callhook(L, LUA_HOOKCOUNT, -1); |
| 303 | } | 303 | } |
| 304 | if ((g->hookmask & LUA_MASKLINE) && proto_lineinfo(pt)) { | 304 | if ((g->hookmask & LUA_MASKLINE)) { |
| 305 | BCPos npc = proto_bcpos(pt, pc) - 1; | 305 | BCPos npc = proto_bcpos(pt, pc) - 1; |
| 306 | BCPos opc = proto_bcpos(pt, oldpc) - 1; | 306 | BCPos opc = proto_bcpos(pt, oldpc) - 1; |
| 307 | BCLine line = proto_line(pt, npc); | 307 | BCLine line = proto_line(pt, npc); |
diff --git a/src/lj_err.c b/src/lj_err.c index b0143c5a..2b021d28 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) | |||
| 129 | if (pc != ~(BCPos)0) { | 129 | if (pc != ~(BCPos)0) { |
| 130 | GCproto *pt = funcproto(fn); | 130 | GCproto *pt = funcproto(fn); |
| 131 | lua_assert(pc < pt->sizebc); | 131 | lua_assert(pc < pt->sizebc); |
| 132 | return proto_lineinfo(pt) ? proto_line(pt, pc) : 0; | 132 | return proto_line(pt, pc); |
| 133 | } else { | 133 | } else { |
| 134 | return -1; | 134 | return -1; |
| 135 | } | 135 | } |
| @@ -138,9 +138,10 @@ static BCLine currentline(lua_State *L, GCfunc *fn, cTValue *nextframe) | |||
| 138 | static const char *getvarname(const GCproto *pt, BCPos pc, BCReg slot) | 138 | static const char *getvarname(const GCproto *pt, BCPos pc, BCReg slot) |
| 139 | { | 139 | { |
| 140 | MSize i; | 140 | MSize i; |
| 141 | for (i = 0; i < pt->sizevarinfo && proto_varinfo(pt)[i].startpc <= pc; i++) | 141 | VarInfo *vi = proto_varinfo(pt); |
| 142 | if (pc < proto_varinfo(pt)[i].endpc && slot-- == 0) | 142 | for (i = 0; i < pt->sizevarinfo && vi[i].startpc <= pc; i++) |
| 143 | return strdata(gco2str(gcref(proto_varinfo(pt)[i].name))); | 143 | if (pc < vi[i].endpc && slot-- == 0) |
| 144 | return strdata(gco2str(gcref(vi[i].name))); | ||
| 144 | return NULL; | 145 | return NULL; |
| 145 | } | 146 | } |
| 146 | 147 | ||
| @@ -176,8 +177,7 @@ restart: | |||
| 176 | } | 177 | } |
| 177 | return "field"; | 178 | return "field"; |
| 178 | case BC_UGET: | 179 | case BC_UGET: |
| 179 | *name = mref(pt->uvname, GCRef) ? | 180 | *name = strdata(proto_uvname(pt, bc_d(ins))); |
| 180 | strdata(gco2str(proto_uvname(pt,bc_d(ins)))) : "?"; | ||
| 181 | return "upvalue"; | 181 | return "upvalue"; |
| 182 | default: | 182 | default: |
| 183 | return NULL; | 183 | return NULL; |
| @@ -224,7 +224,7 @@ void lj_err_pushloc(lua_State *L, GCproto *pt, BCPos pc) | |||
| 224 | MSize i, len = name->len; | 224 | MSize i, len = name->len; |
| 225 | BCLine line; | 225 | BCLine line; |
| 226 | if (pc) | 226 | if (pc) |
| 227 | line = proto_lineinfo(pt) ? proto_line(pt, pc-1) : 0; | 227 | line = proto_line(pt, pc-1); |
| 228 | else | 228 | else |
| 229 | line = pt->linedefined; | 229 | line = pt->linedefined; |
| 230 | if (*s == '@') { | 230 | if (*s == '@') { |
| @@ -377,12 +377,11 @@ LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar) | |||
| 377 | case 'L': | 377 | case 'L': |
| 378 | if (isluafunc(fn)) { | 378 | if (isluafunc(fn)) { |
| 379 | GCtab *t = lj_tab_new(L, 0, 0); | 379 | GCtab *t = lj_tab_new(L, 0, 0); |
| 380 | BCLine *lineinfo = proto_lineinfo(funcproto(fn)); | 380 | GCproto *pt = funcproto(fn); |
| 381 | if (lineinfo) { | 381 | BCLine *lineinfo = proto_lineinfo(pt); |
| 382 | uint32_t i, szl = funcproto(fn)->sizelineinfo; | 382 | MSize i, szl = pt->sizebc; |
| 383 | for (i = 0; i < szl; i++) | 383 | for (i = 0; i < szl; i++) |
| 384 | setboolV(lj_tab_setint(L, t, lineinfo[i]), 1); | 384 | setboolV(lj_tab_setint(L, t, lineinfo[i]), 1); |
| 385 | } | ||
| 386 | settabV(L, L->top, t); | 385 | settabV(L, L->top, t); |
| 387 | } else { | 386 | } else { |
| 388 | setnilV(L->top); | 387 | setnilV(L->top); |
diff --git a/src/lj_func.c b/src/lj_func.c index 74aba745..adc8c039 100644 --- a/src/lj_func.c +++ b/src/lj_func.c | |||
| @@ -17,46 +17,10 @@ | |||
| 17 | 17 | ||
| 18 | /* -- Prototypes ---------------------------------------------------------- */ | 18 | /* -- Prototypes ---------------------------------------------------------- */ |
| 19 | 19 | ||
| 20 | GCproto *lj_func_newproto(lua_State *L) | ||
| 21 | { | ||
| 22 | GCproto *pt = lj_mem_newobj(L, GCproto); | ||
| 23 | pt->gct = ~LJ_TPROTO; | ||
| 24 | pt->numparams = 0; | ||
| 25 | pt->framesize = 0; | ||
| 26 | pt->sizeuv = 0; | ||
| 27 | pt->flags = 0; | ||
| 28 | pt->trace = 0; | ||
| 29 | setmref(pt->k, NULL); | ||
| 30 | setmref(pt->bc, NULL); | ||
| 31 | setmref(pt->uv, NULL); | ||
| 32 | pt->sizebc = 0; | ||
| 33 | pt->sizekgc = 0; | ||
| 34 | pt->sizekn = 0; | ||
| 35 | pt->sizelineinfo = 0; | ||
| 36 | pt->sizevarinfo = 0; | ||
| 37 | pt->sizeuvname = 0; | ||
| 38 | pt->linedefined = 0; | ||
| 39 | pt->lastlinedefined = 0; | ||
| 40 | setmref(pt->lineinfo, NULL); | ||
| 41 | setmref(pt->varinfo, NULL); | ||
| 42 | setmref(pt->uvname, NULL); | ||
| 43 | setgcrefnull(pt->chunkname); | ||
| 44 | return pt; | ||
| 45 | } | ||
| 46 | |||
| 47 | void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) | 20 | void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) |
| 48 | { | 21 | { |
| 49 | MSize nkgc = round_nkgc(pt->sizekgc); | ||
| 50 | MSize sizek = nkgc*(MSize)sizeof(GCRef) + | ||
| 51 | pt->sizekn*(MSize)sizeof(lua_Number); | ||
| 52 | lj_mem_free(g, mref(pt->k, GCRef) - nkgc, sizek); | ||
| 53 | lj_mem_freevec(g, proto_bc(pt), pt->sizebc, BCIns); | ||
| 54 | lj_mem_freevec(g, proto_uv(pt), pt->sizeuv, uint16_t); | ||
| 55 | lj_mem_freevec(g, proto_lineinfo(pt), pt->sizelineinfo, BCLine); | ||
| 56 | lj_mem_freevec(g, proto_varinfo(pt), pt->sizevarinfo, VarInfo); | ||
| 57 | lj_mem_freevec(g, mref(pt->uvname, GCRef), pt->sizeuvname, GCRef); | ||
| 58 | lj_trace_freeproto(g, pt); | 22 | lj_trace_freeproto(g, pt); |
| 59 | lj_mem_freet(g, pt); | 23 | lj_mem_free(g, pt, pt->sizept); |
| 60 | } | 24 | } |
| 61 | 25 | ||
| 62 | /* -- Upvalues ------------------------------------------------------------ */ | 26 | /* -- Upvalues ------------------------------------------------------------ */ |
diff --git a/src/lj_func.h b/src/lj_func.h index c4bf750f..6ed45065 100644 --- a/src/lj_func.h +++ b/src/lj_func.h | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
| 10 | 10 | ||
| 11 | /* Prototypes. */ | 11 | /* Prototypes. */ |
| 12 | LJ_FUNC GCproto *lj_func_newproto(lua_State *L); | ||
| 13 | LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt); | 12 | LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt); |
| 14 | 13 | ||
| 15 | /* Upvalues. */ | 14 | /* Upvalues. */ |
diff --git a/src/lj_gc.c b/src/lj_gc.c index bcef576b..d8221740 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c | |||
| @@ -254,8 +254,8 @@ static void gc_traverse_proto(global_State *g, GCproto *pt) | |||
| 254 | gc_mark_str(proto_chunkname(pt)); | 254 | gc_mark_str(proto_chunkname(pt)); |
| 255 | for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */ | 255 | for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */ |
| 256 | gc_markobj(g, proto_kgc(pt, i)); | 256 | gc_markobj(g, proto_kgc(pt, i)); |
| 257 | for (i = 0; i < (ptrdiff_t)pt->sizeuvname; i++) /* Mark upvalue names. */ | 257 | for (i = 0; i < (ptrdiff_t)pt->sizeuv; i++) /* Mark upvalue names. */ |
| 258 | gc_mark_str(gco2str(proto_uvname(pt, i))); | 258 | gc_mark_str(proto_uvname(pt, i)); |
| 259 | for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */ | 259 | for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */ |
| 260 | gc_mark_str(gco2str(gcref(proto_varinfo(pt)[i].name))); | 260 | gc_mark_str(gco2str(gcref(proto_varinfo(pt)[i].name))); |
| 261 | } | 261 | } |
| @@ -323,13 +323,7 @@ static size_t propagatemark(global_State *g) | |||
| 323 | } else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) { | 323 | } else if (LJ_LIKELY(o->gch.gct == ~LJ_TPROTO)) { |
| 324 | GCproto *pt = gco2pt(o); | 324 | GCproto *pt = gco2pt(o); |
| 325 | gc_traverse_proto(g, pt); | 325 | gc_traverse_proto(g, pt); |
| 326 | return sizeof(GCproto) + sizeof(BCIns) * pt->sizebc + | 326 | return pt->sizept; |
| 327 | sizeof(GCRef) * pt->sizekgc + | ||
| 328 | sizeof(lua_Number) * pt->sizekn + | ||
| 329 | sizeof(uint16_t) * pt->sizeuv + | ||
| 330 | sizeof(BCLine) * pt->sizelineinfo + | ||
| 331 | sizeof(VarInfo) * pt->sizevarinfo + | ||
| 332 | sizeof(GCRef) * pt->sizeuvname; | ||
| 333 | } else { | 327 | } else { |
| 334 | lua_State *th = gco2th(o); | 328 | lua_State *th = gco2th(o); |
| 335 | setgcrefr(th->gclist, g->gc.grayagain); | 329 | setgcrefr(th->gclist, g->gc.grayagain); |
diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index e60a451b..3a4d5da1 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) | |||
| 706 | ctx.spadjp = CFRAME_SIZE + (MSize)(parent ? J->trace[parent]->spadjust : 0); | 706 | ctx.spadjp = CFRAME_SIZE + (MSize)(parent ? J->trace[parent]->spadjust : 0); |
| 707 | ctx.spadj = CFRAME_SIZE + T->spadjust; | 707 | ctx.spadj = CFRAME_SIZE + T->spadjust; |
| 708 | if (startpc >= proto_bc(pt)) | 708 | if (startpc >= proto_bc(pt)) |
| 709 | ctx.lineno = proto_lineinfo(pt) ? proto_line(pt,proto_bcpos(pt,startpc)): 0; | 709 | ctx.lineno = proto_line(pt,proto_bcpos(pt,startpc)); |
| 710 | else | 710 | else |
| 711 | ctx.lineno = pt->linedefined; | 711 | ctx.lineno = pt->linedefined; |
| 712 | ctx.filename = strdata(proto_chunkname(pt)); | 712 | ctx.filename = strdata(proto_chunkname(pt)); |
diff --git a/src/lj_obj.h b/src/lj_obj.h index a0dc689c..d8aab90a 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
| @@ -355,19 +355,18 @@ typedef struct GCproto { | |||
| 355 | MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ | 355 | MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ |
| 356 | MSize sizekgc; /* Number of collectable constants. */ | 356 | MSize sizekgc; /* Number of collectable constants. */ |
| 357 | MSize sizekn; /* Number of lua_Number constants. */ | 357 | MSize sizekn; /* Number of lua_Number constants. */ |
| 358 | MSize sizept; /* Total size including colocated arrays. */ | ||
| 358 | uint8_t sizeuv; /* Number of upvalues. */ | 359 | uint8_t sizeuv; /* Number of upvalues. */ |
| 359 | uint8_t flags; /* Miscellaneous flags (see below). */ | 360 | uint8_t flags; /* Miscellaneous flags (see below). */ |
| 360 | uint16_t trace; /* Anchor for chain of root traces. */ | 361 | uint16_t trace; /* Anchor for chain of root traces. */ |
| 361 | /* ------ The following fields are for debugging/tracebacks only ------ */ | 362 | /* ------ The following fields are for debugging/tracebacks only ------ */ |
| 362 | MSize sizelineinfo; /* Size of lineinfo array (may be 0). */ | 363 | GCRef chunkname; /* Name of the chunk this function was defined in. */ |
| 363 | MSize sizevarinfo; /* Size of local var info array (may be 0). */ | ||
| 364 | MSize sizeuvname; /* Size of upvalue names array (may be 0). */ | ||
| 365 | BCLine linedefined; /* First line of the function definition. */ | 364 | BCLine linedefined; /* First line of the function definition. */ |
| 366 | BCLine lastlinedefined; /* Last line of the function definition. */ | 365 | BCLine lastlinedefined; /* Last line of the function definition. */ |
| 367 | MRef lineinfo; /* Map from bytecode instructions to source lines. */ | 366 | MSize sizevarinfo; /* Size of local var info array. */ |
| 368 | MRef varinfo; /* Names and extents of local variables. */ | 367 | MRef varinfo; /* Names and extents of local variables. */ |
| 369 | MRef uvname; /* Array of upvalue names (GCRef of GCstr). */ | 368 | MRef uvname; /* Array of upvalue names (GCRef of GCstr). */ |
| 370 | GCRef chunkname; /* Name of the chunk this function was defined in. */ | 369 | MRef lineinfo; /* Map from bytecode instructions to source lines. */ |
| 371 | } GCproto; | 370 | } GCproto; |
| 372 | 371 | ||
| 373 | #define PROTO_IS_VARARG 0x01 | 372 | #define PROTO_IS_VARARG 0x01 |
| @@ -389,9 +388,10 @@ typedef struct GCproto { | |||
| 389 | check_exp((uintptr_t)(pos) < (pt)->sizebc, &proto_bc(pt)[(pos)]) | 388 | check_exp((uintptr_t)(pos) < (pt)->sizebc, &proto_bc(pt)[(pos)]) |
| 390 | #define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt))) | 389 | #define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt))) |
| 391 | #define proto_uv(pt) (mref((pt)->uv, uint16_t)) | 390 | #define proto_uv(pt) (mref((pt)->uv, uint16_t)) |
| 391 | |||
| 392 | #define proto_uvname(pt, idx) \ | 392 | #define proto_uvname(pt, idx) \ |
| 393 | check_exp((uintptr_t)(idx) < (pt)->sizeuvname, \ | 393 | check_exp((uintptr_t)(idx) < (pt)->sizeuv, \ |
| 394 | gcref(mref((pt)->uvname, GCRef)[(idx)])) | 394 | gco2str(gcref(mref((pt)->uvname, GCRef)[(idx)]))) |
| 395 | #define proto_chunkname(pt) (gco2str(gcref((pt)->chunkname))) | 395 | #define proto_chunkname(pt) (gco2str(gcref((pt)->chunkname))) |
| 396 | #define proto_lineinfo(pt) (mref((pt)->lineinfo, BCLine)) | 396 | #define proto_lineinfo(pt) (mref((pt)->lineinfo, BCLine)) |
| 397 | #define proto_line(pt, pos) \ | 397 | #define proto_line(pt, pos) \ |
diff --git a/src/lj_parse.c b/src/lj_parse.c index ec355403..678dc4fa 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
| @@ -853,7 +853,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
| 853 | } else if (expr_isk(e)) { | 853 | } else if (expr_isk(e)) { |
| 854 | e->k = VKFALSE; | 854 | e->k = VKFALSE; |
| 855 | return; | 855 | return; |
| 856 | } else if (e->k == VJMP) { | 856 | } else if (e->k == VJMP) { |
| 857 | invertcond(fs, e); | 857 | invertcond(fs, e); |
| 858 | return; | 858 | return; |
| 859 | } else if (e->k == VRELOCABLE) { | 859 | } else if (e->k == VRELOCABLE) { |
| @@ -1026,22 +1026,32 @@ static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) | |||
| 1026 | 1026 | ||
| 1027 | /* -- Function state management ------------------------------------------- */ | 1027 | /* -- Function state management ------------------------------------------- */ |
| 1028 | 1028 | ||
| 1029 | /* NYI: compress debug info. */ | ||
| 1030 | |||
| 1031 | /* Fixup bytecode and lineinfo for prototype. */ | ||
| 1032 | static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, BCLine *lineinfo) | ||
| 1033 | { | ||
| 1034 | MSize i, n = fs->pc; | ||
| 1035 | BCInsLine *base = fs->bcbase; | ||
| 1036 | setmref(pt->bc, bc); | ||
| 1037 | setmref(pt->lineinfo, lineinfo); | ||
| 1038 | pt->sizebc = n; | ||
| 1039 | bc[n] = ~0u; /* Close potentially uninitialized gap between bc and kgc. */ | ||
| 1040 | for (i = 0; i < n; i++) { | ||
| 1041 | bc[i] = base[i].ins; | ||
| 1042 | lineinfo[i] = base[i].line; | ||
| 1043 | } | ||
| 1044 | } | ||
| 1045 | |||
| 1029 | /* Fixup constants for prototype. */ | 1046 | /* Fixup constants for prototype. */ |
| 1030 | static void fs_fixup_k(FuncState *fs, GCproto *pt) | 1047 | static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) |
| 1031 | { | 1048 | { |
| 1032 | GCtab *kt; | 1049 | GCtab *kt; |
| 1033 | TValue *array; | 1050 | TValue *array; |
| 1034 | Node *node; | 1051 | Node *node; |
| 1035 | BCReg nkgc; | 1052 | MSize i, hmask; |
| 1036 | MSize i, hmask, sizek; | ||
| 1037 | GCRef *kptr; | ||
| 1038 | checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants"); | 1053 | checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants"); |
| 1039 | checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants"); | 1054 | checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants"); |
| 1040 | nkgc = round_nkgc(fs->nkgc); | ||
| 1041 | sizek = (MSize)(nkgc*sizeof(GCRef) + fs->nkn*sizeof(lua_Number)); | ||
| 1042 | kptr = lj_mem_newt(fs->L, sizek, GCRef); | ||
| 1043 | if (nkgc) setgcrefnull(kptr[0]); /* May be uninitialized otherwise. */ | ||
| 1044 | kptr += nkgc; | ||
| 1045 | setmref(pt->k, kptr); | 1055 | setmref(pt->k, kptr); |
| 1046 | pt->sizekn = fs->nkn; | 1056 | pt->sizekn = fs->nkn; |
| 1047 | pt->sizekgc = fs->nkgc; | 1057 | pt->sizekgc = fs->nkgc; |
| @@ -1060,7 +1070,7 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt) | |||
| 1060 | ((lua_Number *)kptr)[kidx] = numV(&n->key); | 1070 | ((lua_Number *)kptr)[kidx] = numV(&n->key); |
| 1061 | } else { | 1071 | } else { |
| 1062 | GCobj *o = gcV(&n->key); | 1072 | GCobj *o = gcV(&n->key); |
| 1063 | setgcref(kptr[~kidx], o); | 1073 | setgcref(((GCRef *)kptr)[~kidx], o); |
| 1064 | lj_gc_objbarrier(fs->L, pt, o); | 1074 | lj_gc_objbarrier(fs->L, pt, o); |
| 1065 | } | 1075 | } |
| 1066 | } | 1076 | } |
| @@ -1068,16 +1078,29 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt) | |||
| 1068 | } | 1078 | } |
| 1069 | 1079 | ||
| 1070 | /* Fixup upvalues for prototype. */ | 1080 | /* Fixup upvalues for prototype. */ |
| 1071 | static void fs_fixup_uv(FuncState *fs, GCproto *pt) | 1081 | static void fs_fixup_uv(FuncState *fs, GCproto *pt, uint16_t *uv) |
| 1072 | { | 1082 | { |
| 1073 | MSize i, n = fs->nuv; | 1083 | MSize i, n = fs->nuv; |
| 1074 | uint16_t *uv = lj_mem_newvec(fs->L, n, uint16_t); | ||
| 1075 | setmref(pt->uv, uv); | 1084 | setmref(pt->uv, uv); |
| 1076 | pt->sizeuv = n; | 1085 | pt->sizeuv = n; |
| 1077 | for (i = 0; i < n; i++) | 1086 | for (i = 0; i < n; i++) |
| 1078 | uv[i] = fs->uvloc[i].slot; | 1087 | uv[i] = fs->uvloc[i].slot; |
| 1079 | } | 1088 | } |
| 1080 | 1089 | ||
| 1090 | /* Fixup debug info for prototype. */ | ||
| 1091 | static void fs_fixup_dbg(FuncState *fs, GCproto *pt, VarInfo *vi, MSize sizevi) | ||
| 1092 | { | ||
| 1093 | MSize i, n = fs->nuv; | ||
| 1094 | GCRef *uvname = (GCRef *)((char *)vi + sizevi*sizeof(VarInfo)); | ||
| 1095 | VarInfo *vstack = fs->ls->vstack; | ||
| 1096 | setmref(pt->varinfo, vi); | ||
| 1097 | setmref(pt->uvname, uvname); | ||
| 1098 | pt->sizevarinfo = sizevi; | ||
| 1099 | memcpy(vi, &vstack[fs->vbase], sizevi*sizeof(VarInfo)); | ||
| 1100 | for (i = 0; i < n; i++) | ||
| 1101 | setgcref(uvname[i], gcref(vstack[fs->uvloc[i].vidx].name)); | ||
| 1102 | } | ||
| 1103 | |||
| 1081 | /* Check if bytecode op returns. */ | 1104 | /* Check if bytecode op returns. */ |
| 1082 | static int bcopisret(BCOp op) | 1105 | static int bcopisret(BCOp op) |
| 1083 | { | 1106 | { |
| @@ -1128,6 +1151,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
| 1128 | { | 1151 | { |
| 1129 | lua_State *L = ls->L; | 1152 | lua_State *L = ls->L; |
| 1130 | FuncState *fs = ls->fs; | 1153 | FuncState *fs = ls->fs; |
| 1154 | MSize sizevi; | ||
| 1155 | size_t sizept, ofsk, ofsuv, ofsdbg, ofsli; | ||
| 1131 | GCproto *pt; | 1156 | GCproto *pt; |
| 1132 | 1157 | ||
| 1133 | /* Apply final fixups. */ | 1158 | /* Apply final fixups. */ |
| @@ -1135,61 +1160,41 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
| 1135 | lua_assert(fs->bl == NULL); | 1160 | lua_assert(fs->bl == NULL); |
| 1136 | fs_fixup_ret(fs); | 1161 | fs_fixup_ret(fs); |
| 1137 | 1162 | ||
| 1163 | /* Calculate total size of prototype including all colocated arrays. */ | ||
| 1164 | sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef); | ||
| 1165 | sizept = (sizept + sizeof(lua_Number)-1) & ~(sizeof(lua_Number)-1); | ||
| 1166 | ofsk = sizept; | ||
| 1167 | sizept += fs->nkn*sizeof(lua_Number); | ||
| 1168 | ofsuv = sizept; | ||
| 1169 | sizept += ((fs->nuv+1)&~1)*2; | ||
| 1170 | ofsdbg = sizept; | ||
| 1171 | sizevi = ls->vtop - fs->vbase; | ||
| 1172 | sizept += sizevi*sizeof(VarInfo) + fs->nuv*sizeof(GCRef); | ||
| 1173 | ofsli = sizept; | ||
| 1174 | sizept += fs->pc*sizeof(BCLine); | ||
| 1175 | |||
| 1138 | /* Allocate prototype and initialize its fields. */ | 1176 | /* Allocate prototype and initialize its fields. */ |
| 1139 | pt = lj_func_newproto(L); | 1177 | pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); |
| 1178 | pt->gct = ~LJ_TPROTO; | ||
| 1179 | pt->sizept = (MSize)sizept; | ||
| 1140 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); | 1180 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); |
| 1181 | pt->trace = 0; | ||
| 1141 | pt->flags = fs->flags; | 1182 | pt->flags = fs->flags; |
| 1142 | pt->numparams = fs->numparams; | 1183 | pt->numparams = fs->numparams; |
| 1143 | pt->framesize = fs->framesize; | 1184 | pt->framesize = fs->framesize; |
| 1144 | pt->linedefined = fs->linedefined; | 1185 | pt->linedefined = fs->linedefined; |
| 1145 | pt->lastlinedefined = line; | 1186 | pt->lastlinedefined = line; |
| 1146 | 1187 | ||
| 1147 | /* Anchor prototype since allocation of the arrays may fail. */ | 1188 | fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), |
| 1148 | setprotoV(L, L->top, pt); | 1189 | (BCLine *)((char *)pt + ofsli)); |
| 1149 | incr_top(L); | 1190 | fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); |
| 1150 | 1191 | fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv)); | |
| 1151 | fs_fixup_k(fs, pt); | 1192 | fs_fixup_dbg(fs, pt, (VarInfo *)((char *)pt + ofsdbg), sizevi); |
| 1152 | fs_fixup_uv(fs, pt); | ||
| 1153 | |||
| 1154 | { | ||
| 1155 | MSize i, n = fs->pc; | ||
| 1156 | BCInsLine *base = fs->bcbase; | ||
| 1157 | BCLine *lineinfo; | ||
| 1158 | BCIns *bc = lj_mem_newvec(L, n, BCIns); | ||
| 1159 | setmref(pt->bc, bc); | ||
| 1160 | pt->sizebc = fs->pc; | ||
| 1161 | lineinfo = lj_mem_newvec(L, n, BCLine); | ||
| 1162 | setmref(pt->lineinfo, lineinfo); | ||
| 1163 | pt->sizelineinfo = n; | ||
| 1164 | for (i = 0; i < n; i++) { | ||
| 1165 | bc[i] = base[i].ins; | ||
| 1166 | lineinfo[i] = base[i].line; | ||
| 1167 | } | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | { | ||
| 1171 | MSize n = ls->vtop - fs->vbase; | ||
| 1172 | VarInfo *vi = lj_mem_newvec(L, n, VarInfo); | ||
| 1173 | memcpy(vi, &ls->vstack[fs->vbase], n*sizeof(VarInfo)); | ||
| 1174 | setmref(pt->varinfo, vi); | ||
| 1175 | pt->sizevarinfo = n; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | { | ||
| 1179 | MSize i, n = fs->nuv; | ||
| 1180 | GCRef *uvname = lj_mem_newvec(L, n, GCRef); | ||
| 1181 | for (i = 0; i < n; i++) | ||
| 1182 | setgcref(uvname[i], gcref(ls->vstack[fs->uvloc[i].vidx].name)); | ||
| 1183 | setmref(pt->uvname, uvname); | ||
| 1184 | pt->sizeuvname = n; | ||
| 1185 | } | ||
| 1186 | 1193 | ||
| 1187 | lj_vmevent_send(L, BC, | 1194 | lj_vmevent_send(L, BC, |
| 1188 | setprotoV(L, L->top++, pt); | 1195 | setprotoV(L, L->top++, pt); |
| 1189 | ); | 1196 | ); |
| 1190 | 1197 | ||
| 1191 | L->top--; /* Pop prototype. */ | ||
| 1192 | |||
| 1193 | L->top--; /* Pop table of constants. */ | 1198 | L->top--; /* Pop table of constants. */ |
| 1194 | ls->vtop = fs->vbase; /* Reset variable stack. */ | 1199 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
| 1195 | ls->fs = fs->prev; | 1200 | ls->fs = fs->prev; |
| @@ -1427,7 +1432,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
| 1427 | lex_match(ls, TK_end, TK_function, line); | 1432 | lex_match(ls, TK_end, TK_function, line); |
| 1428 | pt = fs_finish(ls, lastline); | 1433 | pt = fs_finish(ls, lastline); |
| 1429 | fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | 1434 | fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
| 1430 | fs->bclim = ls->sizebcstack - oldbase; | 1435 | fs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
| 1431 | /* Store new prototype in the constant array of the parent. */ | 1436 | /* Store new prototype in the constant array of the parent. */ |
| 1432 | kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO); | 1437 | kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO); |
| 1433 | expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx)); | 1438 | expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx)); |
