aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-08 05:30:57 +0100
committerMike Pall <mike>2010-02-08 05:30:57 +0100
commit6194b1c896c78c2ba0436053dcae596725317e9c (patch)
treec3fc29eddcb51e3717fce1d00eff29f9a211f300 /src
parentf275a9d7ef1a47c30cbb9c70897914d633dff14c (diff)
downloadluajit-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.c4
-rw-r--r--src/lj_api.c4
-rw-r--r--src/lj_dispatch.c2
-rw-r--r--src/lj_err.c25
-rw-r--r--src/lj_func.c38
-rw-r--r--src/lj_func.h1
-rw-r--r--src/lj_gc.c12
-rw-r--r--src/lj_gdbjit.c2
-rw-r--r--src/lj_obj.h14
-rw-r--r--src/lj_parse.c117
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)
138static const char *getvarname(const GCproto *pt, BCPos pc, BCReg slot) 138static 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
20GCproto *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
47void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) 20void 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. */
12LJ_FUNC GCproto *lj_func_newproto(lua_State *L);
13LJ_FUNC void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt); 12LJ_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. */
1032static 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. */
1030static void fs_fixup_k(FuncState *fs, GCproto *pt) 1047static 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. */
1071static void fs_fixup_uv(FuncState *fs, GCproto *pt) 1081static 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. */
1091static 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. */
1082static int bcopisret(BCOp op) 1105static 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));