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 /src | |
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.
Diffstat (limited to 'src')
-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)); |