diff options
-rw-r--r-- | src/lib_jit.c | 2 | ||||
-rw-r--r-- | src/lj_dispatch.c | 7 | ||||
-rw-r--r-- | src/lj_obj.h | 15 | ||||
-rw-r--r-- | src/lj_parse.c | 20 | ||||
-rw-r--r-- | src/lj_record.c | 4 | ||||
-rw-r--r-- | src/lj_trace.c | 10 |
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) | |||
172 | static void setptmode(global_State *g, GCproto *pt, int mode) | 172 | static 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) | |||
185 | static void setptmode_all(global_State *g, GCproto *pt, int mode) | 185 | static 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. */ |
164 | void lj_trace_reenableproto(GCproto *pt) | 164 | void 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) | |||
323 | static void blacklist_pc(GCproto *pt, BCIns *pc) | 323 | static 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; |