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) setintfield(L, t, "upvalues", (int32_t)pt->sizeuv); if (pc < pt->sizebc) setintfield(L, t, "currentline", lj_debug_line(pt, pc)); - lua_pushboolean(L, (pt->flags & PROTO_IS_VARARG)); + lua_pushboolean(L, (pt->flags & PROTO_VARARG)); lua_setfield(L, -2, "isvararg"); setstrV(L, L->top++, proto_chunkname(pt)); 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) static void setptmode(global_State *g, GCproto *pt, int mode) { if ((mode & LUAJIT_MODE_ON)) { /* (Re-)enable JIT compilation. */ - pt->flags &= ~PROTO_NO_JIT; + pt->flags &= ~PROTO_NOJIT; lj_trace_reenableproto(pt); /* Unpatch all ILOOP etc. bytecodes. */ } else { /* Flush and/or disable JIT compilation. */ if (!(mode & LUAJIT_MODE_FLUSH)) - pt->flags |= PROTO_NO_JIT; + pt->flags |= PROTO_NOJIT; lj_trace_flushproto(g, pt); /* Flush all traces of prototype. */ } } @@ -185,6 +185,7 @@ static void setptmode(global_State *g, GCproto *pt, int mode) static void setptmode_all(global_State *g, GCproto *pt, int mode) { ptrdiff_t i; + if (!(pt->flags & PROTO_CHILD)) return; for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) { GCobj *o = proto_kgc(pt, i); if (o->gch.gct == ~LJ_TPROTO) { @@ -400,7 +401,7 @@ static int call_init(lua_State *L, GCfunc *fn) int numparams = pt->numparams; int gotparams = (int)(L->top - L->base); int need = pt->framesize; - if ((pt->flags & PROTO_IS_VARARG)) need += 1+gotparams; + if ((pt->flags & PROTO_VARARG)) need += 1+gotparams; lj_state_checkstack(L, (MSize)need); numparams -= gotparams; 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 { MRef varinfo; /* Names and compressed extents of local variables. */ } GCproto; -#define PROTO_IS_VARARG 0x01 -#define PROTO_HAS_FNEW 0x02 -#define PROTO_HAS_RETURN 0x04 -#define PROTO_FIXUP_RETURN 0x08 -#define PROTO_NO_JIT 0x10 -#define PROTO_HAS_ILOOP 0x20 +/* Flags for prototype. */ +#define PROTO_VARARG 0x01 /* Vararg function. */ +#define PROTO_CHILD 0x02 /* Has child prototypes. */ +#define PROTO_NOJIT 0x04 /* JIT disabled for this function. */ +#define PROTO_ILOOP 0x08 /* Patched bytecode with ILOOP etc. */ +#define PROTO_FFI 0x10 /* Uses BC_KCDATA for FFI datatypes. */ +/* Only used during parsing. */ +#define PROTO_HAS_RETURN 0x20 /* Already emitted a return. */ +#define PROTO_FIXUP_RETURN 0x40 /* Need to fixup emitted returns. */ #define proto_kgc(pt, idx) \ 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) ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); #if LJ_HASFFI } else if (e->k == VKCDATA) { + fs->flags |= PROTO_FFI; ins = BCINS_AD(BC_KCDATA, reg, const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA)); #endif @@ -1120,7 +1121,7 @@ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n) BCInsLine *base = fs->bcbase; MSize i; pt->sizebc = n; - bc[0] = BCINS_AD((fs->flags & PROTO_IS_VARARG) ? BC_FUNCV : BC_FUNCF, + bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF, fs->framesize, 0); for (i = 1; i < n; i++) bc[i] = base[i].ins; @@ -1336,7 +1337,7 @@ static void fs_fixup_ret(FuncState *fs) { BCPos lastpc = fs->pc; if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { - if (fs->flags & PROTO_HAS_FNEW) + if (fs->flags & PROTO_CHILD) bcemit_AJ(fs, BC_UCLO, 0, 0); bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ } @@ -1615,7 +1616,7 @@ static BCReg parse_params(LexState *ls, int needself) var_new(ls, nparams++, lex_str(ls)); } else if (ls->token == TK_dots) { lj_lex_next(ls); - fs->flags |= PROTO_IS_VARARG; + fs->flags |= PROTO_VARARG; break; } else { err_syntax(ls, LJ_ERR_XPARAM); @@ -1652,10 +1653,13 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) /* Store new prototype in the constant array of the parent. */ expr_init(e, VRELOCABLE, bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); - if (!(pfs->flags & PROTO_HAS_FNEW)) { +#if LJ_HASFFI + pfs->flags |= (fs.flags & PROTO_FFI); +#endif + if (!(pfs->flags & PROTO_CHILD)) { if (pfs->flags & PROTO_HAS_RETURN) pfs->flags |= PROTO_FIXUP_RETURN; - pfs->flags |= PROTO_HAS_FNEW; + pfs->flags |= PROTO_CHILD; } lj_lex_next(ls); } @@ -1781,7 +1785,7 @@ static void expr_simple(LexState *ls, ExpDesc *v) case TK_dots: { /* Vararg. */ FuncState *fs = ls->fs; BCReg base; - checkcond(ls, fs->flags & PROTO_IS_VARARG, LJ_ERR_XDOTS); + checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS); bcreg_reserve(fs, 1); base = fs->freereg-1; expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams)); @@ -2018,7 +2022,7 @@ static void parse_return(LexState *ls) } } } - if (fs->flags & PROTO_HAS_FNEW) + if (fs->flags & PROTO_CHILD) bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ bcemit_INS(fs, ins); } @@ -2491,7 +2495,7 @@ GCproto *lj_parse(LexState *ls) fs.numparams = 0; fs.bcbase = NULL; fs.bclim = 0; - fs.flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */ + fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */ bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ lj_lex_next(ls); /* Read-ahead first token. */ 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) { GCproto *pt = J->pt; BCReg s, numparams = pt->numparams; - if ((pt->flags & PROTO_NO_JIT)) + if ((pt->flags & PROTO_NOJIT)) lj_trace_err(J, LJ_TRERR_CJITOFF); if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS) lj_trace_err(J, LJ_TRERR_STACKOV); @@ -1292,7 +1292,7 @@ static void rec_func_vararg(jit_State *J) { GCproto *pt = J->pt; BCReg s, fixargs, vframe = J->maxslot+1; - lua_assert((pt->flags & PROTO_IS_VARARG)); + lua_assert((pt->flags & PROTO_VARARG)); if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS) lj_trace_err(J, LJ_TRERR_STACKOV); 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) /* Re-enable compiling a prototype by unpatching any modified bytecode. */ void lj_trace_reenableproto(GCproto *pt) { - if ((pt->flags & PROTO_HAS_ILOOP)) { + if ((pt->flags & PROTO_ILOOP)) { BCIns *bc = proto_bc(pt); BCPos i, sizebc = pt->sizebc;; - pt->flags &= ~PROTO_HAS_ILOOP; + pt->flags &= ~PROTO_ILOOP; if (bc_op(bc[0]) == BC_IFUNCF) setbc_op(&bc[0], BC_FUNCF); for (i = 1; i < sizebc; i++) { @@ -323,7 +323,7 @@ void lj_trace_freestate(global_State *g) static void blacklist_pc(GCproto *pt, BCIns *pc) { setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP); - pt->flags |= PROTO_HAS_ILOOP; + pt->flags |= PROTO_ILOOP; } /* Penalize a bytecode instruction. */ @@ -359,13 +359,13 @@ static void trace_start(jit_State *J) lua_State *L; TraceNo traceno; - if ((J->pt->flags & PROTO_NO_JIT)) { /* JIT disabled for this proto? */ + if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */ if (J->parent == 0) { /* Lazy bytecode patching to disable hotcount events. */ lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL || bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF); setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP); - J->pt->flags |= PROTO_HAS_ILOOP; + J->pt->flags |= PROTO_ILOOP; } J->state = LJ_TRACE_IDLE; /* Silently ignored. */ return;