summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib_jit.c2
-rw-r--r--src/lj_dispatch.c7
-rw-r--r--src/lj_obj.h15
-rw-r--r--src/lj_parse.c20
-rw-r--r--src/lj_record.c4
-rw-r--r--src/lj_trace.c10
6 files changed, 33 insertions, 25 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 818b8787..31b27ccb 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -191,7 +191,7 @@ LJLIB_CF(jit_util_funcinfo)
191 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv); 191 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv);
192 if (pc < pt->sizebc) 192 if (pc < pt->sizebc)
193 setintfield(L, t, "currentline", lj_debug_line(pt, pc)); 193 setintfield(L, t, "currentline", lj_debug_line(pt, pc));
194 lua_pushboolean(L, (pt->flags & PROTO_IS_VARARG)); 194 lua_pushboolean(L, (pt->flags & PROTO_VARARG));
195 lua_setfield(L, -2, "isvararg"); 195 lua_setfield(L, -2, "isvararg");
196 setstrV(L, L->top++, proto_chunkname(pt)); 196 setstrV(L, L->top++, proto_chunkname(pt));
197 lua_setfield(L, -2, "source"); 197 lua_setfield(L, -2, "source");
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index 5fbc112c..c29cad46 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -172,11 +172,11 @@ void lj_dispatch_update(global_State *g)
172static void setptmode(global_State *g, GCproto *pt, int mode) 172static void setptmode(global_State *g, GCproto *pt, int mode)
173{ 173{
174 if ((mode & LUAJIT_MODE_ON)) { /* (Re-)enable JIT compilation. */ 174 if ((mode & LUAJIT_MODE_ON)) { /* (Re-)enable JIT compilation. */
175 pt->flags &= ~PROTO_NO_JIT; 175 pt->flags &= ~PROTO_NOJIT;
176 lj_trace_reenableproto(pt); /* Unpatch all ILOOP etc. bytecodes. */ 176 lj_trace_reenableproto(pt); /* Unpatch all ILOOP etc. bytecodes. */
177 } else { /* Flush and/or disable JIT compilation. */ 177 } else { /* Flush and/or disable JIT compilation. */
178 if (!(mode & LUAJIT_MODE_FLUSH)) 178 if (!(mode & LUAJIT_MODE_FLUSH))
179 pt->flags |= PROTO_NO_JIT; 179 pt->flags |= PROTO_NOJIT;
180 lj_trace_flushproto(g, pt); /* Flush all traces of prototype. */ 180 lj_trace_flushproto(g, pt); /* Flush all traces of prototype. */
181 } 181 }
182} 182}
@@ -185,6 +185,7 @@ static void setptmode(global_State *g, GCproto *pt, int mode)
185static void setptmode_all(global_State *g, GCproto *pt, int mode) 185static void setptmode_all(global_State *g, GCproto *pt, int mode)
186{ 186{
187 ptrdiff_t i; 187 ptrdiff_t i;
188 if (!(pt->flags & PROTO_CHILD)) return;
188 for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) { 189 for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) {
189 GCobj *o = proto_kgc(pt, i); 190 GCobj *o = proto_kgc(pt, i);
190 if (o->gch.gct == ~LJ_TPROTO) { 191 if (o->gch.gct == ~LJ_TPROTO) {
@@ -400,7 +401,7 @@ static int call_init(lua_State *L, GCfunc *fn)
400 int numparams = pt->numparams; 401 int numparams = pt->numparams;
401 int gotparams = (int)(L->top - L->base); 402 int gotparams = (int)(L->top - L->base);
402 int need = pt->framesize; 403 int need = pt->framesize;
403 if ((pt->flags & PROTO_IS_VARARG)) need += 1+gotparams; 404 if ((pt->flags & PROTO_VARARG)) need += 1+gotparams;
404 lj_state_checkstack(L, (MSize)need); 405 lj_state_checkstack(L, (MSize)need);
405 numparams -= gotparams; 406 numparams -= gotparams;
406 return numparams >= 0 ? numparams : 0; 407 return numparams >= 0 ? numparams : 0;
diff --git a/src/lj_obj.h b/src/lj_obj.h
index e85cf703..3442dc0c 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -309,12 +309,15 @@ typedef struct GCproto {
309 MRef varinfo; /* Names and compressed extents of local variables. */ 309 MRef varinfo; /* Names and compressed extents of local variables. */
310} GCproto; 310} GCproto;
311 311
312#define PROTO_IS_VARARG 0x01 312/* Flags for prototype. */
313#define PROTO_HAS_FNEW 0x02 313#define PROTO_VARARG 0x01 /* Vararg function. */
314#define PROTO_HAS_RETURN 0x04 314#define PROTO_CHILD 0x02 /* Has child prototypes. */
315#define PROTO_FIXUP_RETURN 0x08 315#define PROTO_NOJIT 0x04 /* JIT disabled for this function. */
316#define PROTO_NO_JIT 0x10 316#define PROTO_ILOOP 0x08 /* Patched bytecode with ILOOP etc. */
317#define PROTO_HAS_ILOOP 0x20 317#define PROTO_FFI 0x10 /* Uses BC_KCDATA for FFI datatypes. */
318/* Only used during parsing. */
319#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */
320#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */
318 321
319#define proto_kgc(pt, idx) \ 322#define proto_kgc(pt, idx) \
320 check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \ 323 check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \
diff --git a/src/lj_parse.c b/src/lj_parse.c
index bd9d9a7a..f0bb4419 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -513,6 +513,7 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
513 ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); 513 ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
514#if LJ_HASFFI 514#if LJ_HASFFI
515 } else if (e->k == VKCDATA) { 515 } else if (e->k == VKCDATA) {
516 fs->flags |= PROTO_FFI;
516 ins = BCINS_AD(BC_KCDATA, reg, 517 ins = BCINS_AD(BC_KCDATA, reg,
517 const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA)); 518 const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA));
518#endif 519#endif
@@ -1120,7 +1121,7 @@ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n)
1120 BCInsLine *base = fs->bcbase; 1121 BCInsLine *base = fs->bcbase;
1121 MSize i; 1122 MSize i;
1122 pt->sizebc = n; 1123 pt->sizebc = n;
1123 bc[0] = BCINS_AD((fs->flags & PROTO_IS_VARARG) ? BC_FUNCV : BC_FUNCF, 1124 bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF,
1124 fs->framesize, 0); 1125 fs->framesize, 0);
1125 for (i = 1; i < n; i++) 1126 for (i = 1; i < n; i++)
1126 bc[i] = base[i].ins; 1127 bc[i] = base[i].ins;
@@ -1336,7 +1337,7 @@ static void fs_fixup_ret(FuncState *fs)
1336{ 1337{
1337 BCPos lastpc = fs->pc; 1338 BCPos lastpc = fs->pc;
1338 if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { 1339 if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) {
1339 if (fs->flags & PROTO_HAS_FNEW) 1340 if (fs->flags & PROTO_CHILD)
1340 bcemit_AJ(fs, BC_UCLO, 0, 0); 1341 bcemit_AJ(fs, BC_UCLO, 0, 0);
1341 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ 1342 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */
1342 } 1343 }
@@ -1615,7 +1616,7 @@ static BCReg parse_params(LexState *ls, int needself)
1615 var_new(ls, nparams++, lex_str(ls)); 1616 var_new(ls, nparams++, lex_str(ls));
1616 } else if (ls->token == TK_dots) { 1617 } else if (ls->token == TK_dots) {
1617 lj_lex_next(ls); 1618 lj_lex_next(ls);
1618 fs->flags |= PROTO_IS_VARARG; 1619 fs->flags |= PROTO_VARARG;
1619 break; 1620 break;
1620 } else { 1621 } else {
1621 err_syntax(ls, LJ_ERR_XPARAM); 1622 err_syntax(ls, LJ_ERR_XPARAM);
@@ -1652,10 +1653,13 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
1652 /* Store new prototype in the constant array of the parent. */ 1653 /* Store new prototype in the constant array of the parent. */
1653 expr_init(e, VRELOCABLE, 1654 expr_init(e, VRELOCABLE,
1654 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); 1655 bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO)));
1655 if (!(pfs->flags & PROTO_HAS_FNEW)) { 1656#if LJ_HASFFI
1657 pfs->flags |= (fs.flags & PROTO_FFI);
1658#endif
1659 if (!(pfs->flags & PROTO_CHILD)) {
1656 if (pfs->flags & PROTO_HAS_RETURN) 1660 if (pfs->flags & PROTO_HAS_RETURN)
1657 pfs->flags |= PROTO_FIXUP_RETURN; 1661 pfs->flags |= PROTO_FIXUP_RETURN;
1658 pfs->flags |= PROTO_HAS_FNEW; 1662 pfs->flags |= PROTO_CHILD;
1659 } 1663 }
1660 lj_lex_next(ls); 1664 lj_lex_next(ls);
1661} 1665}
@@ -1781,7 +1785,7 @@ static void expr_simple(LexState *ls, ExpDesc *v)
1781 case TK_dots: { /* Vararg. */ 1785 case TK_dots: { /* Vararg. */
1782 FuncState *fs = ls->fs; 1786 FuncState *fs = ls->fs;
1783 BCReg base; 1787 BCReg base;
1784 checkcond(ls, fs->flags & PROTO_IS_VARARG, LJ_ERR_XDOTS); 1788 checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS);
1785 bcreg_reserve(fs, 1); 1789 bcreg_reserve(fs, 1);
1786 base = fs->freereg-1; 1790 base = fs->freereg-1;
1787 expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams)); 1791 expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams));
@@ -2018,7 +2022,7 @@ static void parse_return(LexState *ls)
2018 } 2022 }
2019 } 2023 }
2020 } 2024 }
2021 if (fs->flags & PROTO_HAS_FNEW) 2025 if (fs->flags & PROTO_CHILD)
2022 bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ 2026 bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */
2023 bcemit_INS(fs, ins); 2027 bcemit_INS(fs, ins);
2024} 2028}
@@ -2491,7 +2495,7 @@ GCproto *lj_parse(LexState *ls)
2491 fs.numparams = 0; 2495 fs.numparams = 0;
2492 fs.bcbase = NULL; 2496 fs.bcbase = NULL;
2493 fs.bclim = 0; 2497 fs.bclim = 0;
2494 fs.flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */ 2498 fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */
2495 bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ 2499 bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */
2496 lj_lex_next(ls); /* Read-ahead first token. */ 2500 lj_lex_next(ls); /* Read-ahead first token. */
2497 parse_chunk(ls); 2501 parse_chunk(ls);
diff --git a/src/lj_record.c b/src/lj_record.c
index fe79832a..1a18724a 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1276,7 +1276,7 @@ static void rec_func_setup(jit_State *J)
1276{ 1276{
1277 GCproto *pt = J->pt; 1277 GCproto *pt = J->pt;
1278 BCReg s, numparams = pt->numparams; 1278 BCReg s, numparams = pt->numparams;
1279 if ((pt->flags & PROTO_NO_JIT)) 1279 if ((pt->flags & PROTO_NOJIT))
1280 lj_trace_err(J, LJ_TRERR_CJITOFF); 1280 lj_trace_err(J, LJ_TRERR_CJITOFF);
1281 if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS) 1281 if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS)
1282 lj_trace_err(J, LJ_TRERR_STACKOV); 1282 lj_trace_err(J, LJ_TRERR_STACKOV);
@@ -1292,7 +1292,7 @@ static void rec_func_vararg(jit_State *J)
1292{ 1292{
1293 GCproto *pt = J->pt; 1293 GCproto *pt = J->pt;
1294 BCReg s, fixargs, vframe = J->maxslot+1; 1294 BCReg s, fixargs, vframe = J->maxslot+1;
1295 lua_assert((pt->flags & PROTO_IS_VARARG)); 1295 lua_assert((pt->flags & PROTO_VARARG));
1296 if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS) 1296 if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS)
1297 lj_trace_err(J, LJ_TRERR_STACKOV); 1297 lj_trace_err(J, LJ_TRERR_STACKOV);
1298 J->base[vframe-1] = J->base[-1]; /* Copy function up. */ 1298 J->base[vframe-1] = J->base[-1]; /* Copy function up. */
diff --git a/src/lj_trace.c b/src/lj_trace.c
index fbd1b45a..2bb2075d 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -163,10 +163,10 @@ void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T)
163/* Re-enable compiling a prototype by unpatching any modified bytecode. */ 163/* Re-enable compiling a prototype by unpatching any modified bytecode. */
164void lj_trace_reenableproto(GCproto *pt) 164void lj_trace_reenableproto(GCproto *pt)
165{ 165{
166 if ((pt->flags & PROTO_HAS_ILOOP)) { 166 if ((pt->flags & PROTO_ILOOP)) {
167 BCIns *bc = proto_bc(pt); 167 BCIns *bc = proto_bc(pt);
168 BCPos i, sizebc = pt->sizebc;; 168 BCPos i, sizebc = pt->sizebc;;
169 pt->flags &= ~PROTO_HAS_ILOOP; 169 pt->flags &= ~PROTO_ILOOP;
170 if (bc_op(bc[0]) == BC_IFUNCF) 170 if (bc_op(bc[0]) == BC_IFUNCF)
171 setbc_op(&bc[0], BC_FUNCF); 171 setbc_op(&bc[0], BC_FUNCF);
172 for (i = 1; i < sizebc; i++) { 172 for (i = 1; i < sizebc; i++) {
@@ -323,7 +323,7 @@ void lj_trace_freestate(global_State *g)
323static void blacklist_pc(GCproto *pt, BCIns *pc) 323static void blacklist_pc(GCproto *pt, BCIns *pc)
324{ 324{
325 setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP); 325 setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP);
326 pt->flags |= PROTO_HAS_ILOOP; 326 pt->flags |= PROTO_ILOOP;
327} 327}
328 328
329/* Penalize a bytecode instruction. */ 329/* Penalize a bytecode instruction. */
@@ -359,13 +359,13 @@ static void trace_start(jit_State *J)
359 lua_State *L; 359 lua_State *L;
360 TraceNo traceno; 360 TraceNo traceno;
361 361
362 if ((J->pt->flags & PROTO_NO_JIT)) { /* JIT disabled for this proto? */ 362 if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
363 if (J->parent == 0) { 363 if (J->parent == 0) {
364 /* Lazy bytecode patching to disable hotcount events. */ 364 /* Lazy bytecode patching to disable hotcount events. */
365 lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL || 365 lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
366 bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF); 366 bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
367 setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP); 367 setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
368 J->pt->flags |= PROTO_HAS_ILOOP; 368 J->pt->flags |= PROTO_ILOOP;
369 } 369 }
370 J->state = LJ_TRACE_IDLE; /* Silently ignored. */ 370 J->state = LJ_TRACE_IDLE; /* Silently ignored. */
371 return; 371 return;